Files
payloadcms/packages/ui/src/fields/Join/index.tsx
Jarrod Flesch bcbca0e44a chore: improves field types (#9172)
### What?
Ensures `path` is required and only present on the fields that expect it
(all fields except row).

Deprecates `useFieldComponents` and `FieldComponentsProvider` and
instead extends the RenderField component to account for all field
types. This also improves type safety within `RenderField`.

### Why?
`path` being optional just adds DX overhead and annoyance. 

### How?
Added `FieldPaths` type which is added to iterable field types. Placed
`path` back onto the ClientFieldBase type.
2024-11-13 13:53:47 -05:00

78 lines
1.9 KiB
TypeScript

'use client'
import type { JoinFieldClient, JoinFieldClientComponent, PaginatedDocs, Where } from 'payload'
import React, { useMemo } from 'react'
import { RelationshipTable } from '../../elements/RelationshipTable/index.js'
import { useField } from '../../forms/useField/index.js'
import { withCondition } from '../../forms/withCondition/index.js'
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
import { FieldLabel } from '../FieldLabel/index.js'
import { fieldBaseClass } from '../index.js'
const JoinFieldComponent: JoinFieldClientComponent = (props) => {
const {
field,
field: {
name,
admin: { allowCreate },
collection,
label,
localized,
on,
required,
},
path,
} = props
const { id: docID } = useDocumentInfo()
const { customComponents: { AfterInput, BeforeInput, Label } = {}, value } =
useField<PaginatedDocs>({
path,
})
const filterOptions: Where = useMemo(() => {
const where = {
[on]: {
in: [docID || ''],
},
}
if (field.where) {
return {
and: [where, field.where],
}
}
return where
}, [docID, on, field.where])
return (
<div className={[fieldBaseClass, 'join'].filter(Boolean).join(' ')}>
{BeforeInput}
<RelationshipTable
allowCreate={typeof docID !== 'undefined' && allowCreate}
field={field as JoinFieldClient}
filterOptions={filterOptions}
initialData={docID && value ? value : ({ docs: [] } as PaginatedDocs)}
initialDrawerData={{
[on]: docID,
}}
Label={
<h4 style={{ margin: 0 }}>
{Label || (
<FieldLabel label={label} localized={localized} path={path} required={required} />
)}
</h4>
}
relationTo={collection}
/>
{AfterInput}
</div>
)
}
export const JoinField = withCondition(JoinFieldComponent)