feat(ui): threads row data through list drawer onSelect callback (#11339)

When rendering a list drawer, you can pass a custom `onSelect` callback
to execute when the user clicks on the linked cell within the table. The
underlying handler, however, only passes the `docID` and
`collectionSlug` args through the callback, rather than the document
itself. This makes it impossible to perform side-effects that require
the data of the row that was selected.

Instances of this callback were also largely untyped.

Needed for #11330.
This commit is contained in:
Jacob Fletcher
2025-02-21 17:08:05 -05:00
committed by GitHub
parent f31568c69c
commit d766b1904c
10 changed files with 47 additions and 29 deletions

View File

@@ -1,7 +1,8 @@
'use client'
import type { ListDrawerProps } from '@payloadcms/ui'
import { useListDrawer, useTranslation } from '@payloadcms/ui'
import React, { Fragment, useCallback, useEffect, useState } from 'react'
import React, { Fragment, useCallback, useState } from 'react'
import { ReactEditor, useSlate } from 'slate-react'
import { RelationshipIcon } from '../../../icons/Relationship/index.js'
@@ -34,15 +35,13 @@ type Props = {
const RelationshipButtonComponent: React.FC<Props> = ({ enabledCollectionSlugs }) => {
const { t } = useTranslation()
const editor = useSlate()
const [selectedCollectionSlug, setSelectedCollectionSlug] = useState(
() => enabledCollectionSlugs[0],
)
const [ListDrawer, ListDrawerToggler, { closeDrawer, isDrawerOpen }] = useListDrawer({
const [selectedCollectionSlug] = useState(() => enabledCollectionSlugs[0])
const [ListDrawer, ListDrawerToggler, { closeDrawer }] = useListDrawer({
collectionSlugs: enabledCollectionSlugs,
selectedCollection: selectedCollectionSlug,
})
const onSelect = useCallback(
const onSelect = useCallback<NonNullable<ListDrawerProps['onSelect']>>(
({ collectionSlug, docID }) => {
insertRelationship(editor, {
relationTo: collectionSlug,

View File

@@ -1,5 +1,7 @@
'use client'
import type { ListDrawerProps } from '@payloadcms/ui'
import { getTranslation } from '@payloadcms/translations'
import {
Button,
@@ -103,8 +105,8 @@ const RelationshipElementComponent: React.FC = () => {
[editor, element, relatedCollection, cacheBust, setParams, closeDrawer],
)
const swapRelationship = React.useCallback(
({ collectionSlug, docID }) => {
const swapRelationship = useCallback<NonNullable<ListDrawerProps['onSelect']>>(
({ collectionSlug, doc }) => {
const elementPath = ReactEditor.findPath(editor, element)
Transforms.setNodes(
@@ -113,7 +115,7 @@ const RelationshipElementComponent: React.FC = () => {
type: 'relationship',
children: [{ text: ' ' }],
relationTo: collectionSlug,
value: { id: docID },
value: { id: doc.id },
},
{ at: elementPath },
)

View File

@@ -1,5 +1,7 @@
'use client'
import type { ListDrawerProps } from '@payloadcms/ui'
import { useListDrawer, useTranslation } from '@payloadcms/ui'
import React, { Fragment, useCallback } from 'react'
import { ReactEditor, useSlate } from 'slate-react'
@@ -41,12 +43,12 @@ const UploadButton: React.FC<ButtonProps> = ({ enabledCollectionSlugs }) => {
uploads: true,
})
const onSelect = useCallback(
({ collectionSlug, docID }) => {
const onSelect = useCallback<NonNullable<ListDrawerProps['onSelect']>>(
({ collectionSlug, doc }) => {
insertUpload(editor, {
relationTo: collectionSlug,
value: {
id: docID,
id: doc.id,
},
})
closeDrawer()

View File

@@ -1,5 +1,6 @@
'use client'
import type { ListDrawerProps } from '@payloadcms/ui'
import type { ClientCollectionConfig } from 'payload'
import { getTranslation } from '@payloadcms/translations'
@@ -23,8 +24,8 @@ import type { UploadElementType } from '../types.js'
import { useElement } from '../../../providers/ElementProvider.js'
import { EnabledRelationshipsCondition } from '../../EnabledRelationshipsCondition.js'
import { uploadFieldsSchemaPath, uploadName } from '../shared.js'
import './index.scss'
import { UploadDrawer } from './UploadDrawer/index.js'
import './index.scss'
const baseClass = 'rich-text-upload'
@@ -110,13 +111,13 @@ const UploadElementComponent: React.FC<{ enabledCollectionSlugs?: string[] }> =
[editor, element, setParams, cacheBust, closeDrawer],
)
const swapUpload = React.useCallback(
({ collectionSlug, docID }) => {
const swapUpload = useCallback<NonNullable<ListDrawerProps['onSelect']>>(
({ collectionSlug, doc }) => {
const newNode = {
type: uploadName,
children: [{ text: ' ' }],
relationTo: collectionSlug,
value: { id: docID },
value: { id: doc.id },
}
const elementPath = ReactEditor.findPath(editor, element)