feat(richtext-lexical): improve upload and relationship node types (#7822)

Fixes https://github.com/payloadcms/payload/issues/7808. The types are
now accurate. Previously, they would assume that upload and relationship
nodes are never populated
This commit is contained in:
Alessio Gravili
2024-08-22 18:05:45 -04:00
committed by GitHub
parent c2b2f10676
commit 6349cd42e9
4 changed files with 34 additions and 16 deletions

View File

@@ -39,10 +39,16 @@ type Props = {
const Component: React.FC<Props> = (props) => {
const {
data: { relationTo, value: id },
data: { relationTo, value },
nodeKey,
} = props
if (typeof value === 'object') {
throw new Error(
'Relationship value should be a string or number. The Lexical Relationship component should not receive the populated value object.',
)
}
const relationshipElemRef = useRef<HTMLDivElement | null>(null)
const [editor] = useLexicalComposerContext()
@@ -63,12 +69,12 @@ const Component: React.FC<Props> = (props) => {
const { i18n, t } = useTranslation()
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
const [{ data }, { setParams }] = usePayloadAPI(
`${serverURL}${api}/${relatedCollection.slug}/${id}`,
`${serverURL}${api}/${relatedCollection.slug}/${value}`,
{ initialParams },
)
const [DocumentDrawer, DocumentDrawerToggler, { closeDrawer }] = useDocumentDrawer({
id,
id: value,
collectionSlug: relatedCollection.slug,
})
@@ -153,7 +159,7 @@ const Component: React.FC<Props> = (props) => {
</p>
<DocumentDrawerToggler className={`${baseClass}__doc-drawer-toggler`}>
<p className={`${baseClass}__title`}>
{data ? data[relatedCollection?.admin?.useAsTitle || 'id'] : id}
{data ? data[relatedCollection?.admin?.useAsTitle || 'id'] : value}
</p>
</DocumentDrawerToggler>
</div>
@@ -188,7 +194,7 @@ const Component: React.FC<Props> = (props) => {
</div>
)}
{id && <DocumentDrawer onSave={updateRelationship} />}
{!!value && <DocumentDrawer onSave={updateRelationship} />}
</div>
)
}

View File

@@ -10,15 +10,17 @@ import type {
NodeKey,
Spread,
} from 'lexical'
import type { CollectionSlug } from 'payload'
import type { CollectionSlug, DataFromCollectionSlug } from 'payload'
import type { JSX } from 'react'
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js'
export type RelationshipData = {
relationTo: CollectionSlug
value: number | string
}
[TCollectionSlug in CollectionSlug]: {
relationTo: TCollectionSlug
value: DataFromCollectionSlug<TCollectionSlug> | number | string
}
}[CollectionSlug]
export type SerializedRelationshipNode = {
children?: never // required so that our typed editor state doesn't automatically add children

View File

@@ -57,6 +57,12 @@ const Component: React.FC<ElementProps> = (props) => {
nodeKey,
} = props
if (typeof value === 'object') {
throw new Error(
'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',
)
}
const {
config: {
collections,

View File

@@ -8,7 +8,7 @@ import type {
NodeKey,
Spread,
} from 'lexical'
import type { CollectionSlug, JsonObject } from 'payload'
import type { CollectionSlug, DataFromCollectionSlug, JsonObject } from 'payload'
import type { JSX } from 'react'
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js'
@@ -16,12 +16,16 @@ import ObjectID from 'bson-objectid'
import { $applyNodeReplacement } from 'lexical'
import * as React from 'react'
export type UploadData = {
fields: JsonObject
id: string
relationTo: CollectionSlug
value: number | string
}
export type UploadData<TUploadExtraFieldsData extends JsonObject = JsonObject> = {
[TCollectionSlug in CollectionSlug]: {
fields: TUploadExtraFieldsData
// Every lexical node that has sub-fields needs to have a unique ID. This is the ID of this upload node, not the ID of the linked upload document
id: string
relationTo: TCollectionSlug
// Value can be just the document ID, or the full, populated document
value: DataFromCollectionSlug<TCollectionSlug> | number | string
}
}[CollectionSlug]
export function isGoogleDocCheckboxImg(img: HTMLImageElement): boolean {
return (