chore(richtext-lexical): adjust node data formats, adjust population behavior, fix some validation issues

This commit is contained in:
Alessio Gravili
2023-10-07 15:52:12 +02:00
parent 7e9c7707ba
commit ad7c25685e
22 changed files with 195 additions and 181 deletions

View File

@@ -314,7 +314,7 @@ export const upload: Validate<unknown, unknown, UploadField> = (value: string, o
}
if (!canUseDOM && typeof value !== 'undefined' && value !== null) {
const idField = options.payload.collections[options.relationTo].config.fields.find(
const idField = options?.payload?.collections[options.relationTo]?.config?.fields?.find(
(field) => fieldAffectsData(field) && field.name === 'id',
)
const type = getIDType(idField, options?.payload?.db?.defaultIDType)

View File

@@ -18,6 +18,7 @@ export const blockAfterReadPromiseHOC = (
overrideAccess,
req,
showHiddenFields,
siblingDoc,
}) => {
const promises: Promise<void>[] = []
@@ -47,6 +48,7 @@ export const blockAfterReadPromiseHOC = (
promises,
req,
showHiddenFields,
siblingDoc,
})
}
})

View File

@@ -17,16 +17,17 @@ export const linkAfterReadPromiseHOC = (
overrideAccess,
req,
showHiddenFields,
siblingDoc,
}) => {
const promises: Promise<void>[] = []
if (node?.fields?.doc?.value && node?.fields?.doc?.relationTo) {
if (node?.fields?.doc?.value?.id && node?.fields?.doc?.relationTo) {
const collection = req.payload.collections[node?.fields?.doc?.relationTo]
if (collection) {
promises.push(
populate({
id: node?.fields?.doc.value,
id: node?.fields?.doc?.value?.id,
collection,
currentDepth,
data: node?.fields?.doc,
@@ -51,6 +52,7 @@ export const linkAfterReadPromiseHOC = (
promises,
req,
showHiddenFields,
siblingDoc,
})
}
return promises

View File

@@ -35,9 +35,12 @@ export type LinkFields = {
// unknown, custom fields:
[key: string]: unknown
doc: {
data?: any // Will be populated in afterRead hook
relationTo: string
value: string
value: {
// Actual doc data, populated in afterRead hook
[key: string]: unknown
id: string
}
} | null
linkType: 'custom' | 'internal'
newTab: boolean
@@ -124,23 +127,10 @@ export class LinkNode extends ElementNode {
element.target = '_blank'
}
element.rel = ''
if (this.__fields?.newTab === true && this.__fields?.linkType === 'custom') {
element.rel = manageRel(element.rel, 'add', 'noopener')
}
if (this.__fields?.sponsored ?? false) {
element.rel = manageRel(element.rel, 'add', 'sponsored')
}
if (this.__fields?.nofollow ?? false) {
element.rel = manageRel(element.rel, 'add', 'nofollow')
}
if (this.__fields?.rel !== null) {
element.rel += ` ${this.__rel}`
}
addClassNamesToElement(element, config.theme.link)
return element
}
@@ -212,9 +202,6 @@ export class LinkNode extends ElementNode {
updateDOM(prevNode: LinkNode, anchor: HTMLAnchorElement, config: EditorConfig): boolean {
const url = this.__fields?.url
const newTab = this.__fields?.newTab
const sponsored = this.__fields?.sponsored
const nofollow = this.__fields?.nofollow
const rel = this.__fields?.rel
if (url != null && url !== prevNode.__fields?.url && this.__fields?.linkType === 'custom') {
anchor.href = url
}
@@ -240,33 +227,6 @@ export class LinkNode extends ElementNode {
}
}
if (nofollow !== prevNode.__fields.nofollow) {
if (nofollow ?? false) {
anchor.rel = manageRel(anchor.rel, 'add', 'nofollow')
} else {
anchor.rel = manageRel(anchor.rel, 'remove', 'nofollow')
}
}
if (sponsored !== prevNode.__fields.sponsored) {
if (sponsored ?? false) {
anchor.rel = manageRel(anchor.rel, 'add', 'sponsored')
} else {
anchor.rel = manageRel(anchor.rel, 'remove', 'sponsored')
}
}
// TODO - revisit - I don't think there can be any other rel
// values other than nofollow and noopener - so not
// sure why anchor.rel += rel below
if (rel !== prevNode.__fields.rel) {
if (rel != null) {
anchor.rel += rel
} else {
anchor.removeAttribute('rel')
}
}
return false
}
}
@@ -281,9 +241,6 @@ function convertAnchorElement(domNode: Node): DOMConversionOutput {
doc: null,
linkType: 'custom',
newTab: domNode.getAttribute('target') === '_blank',
nofollow: domNode.getAttribute('rel')?.includes('nofollow') ?? false,
rel: domNode.getAttribute('rel'),
sponsored: domNode.getAttribute('rel')?.includes('sponsored') ?? false,
url: domNode.getAttribute('href') ?? '',
},
})

View File

@@ -109,8 +109,6 @@ export function LinkEditor({
doc: undefined,
linkType: undefined,
newTab: undefined,
nofollow: undefined,
sponsored: undefined,
url: '',
...linkParent.getFields(),
},
@@ -124,7 +122,7 @@ export function LinkEditor({
// internal link
setLinkUrl(
`/admin/collections/${linkParent.getFields()?.doc?.relationTo}/${linkParent.getFields()
?.doc?.value}`,
?.doc?.value?.id}`,
)
const relatedField = config.collections.find(
@@ -321,6 +319,12 @@ export function LinkEditor({
const data = reduceFieldsToValues(fields, true)
if (data?.fields?.doc?.value) {
data.fields.doc.value = {
id: data.fields.doc.value,
}
}
const newLinkPayload: LinkPayload = data as LinkPayload
editor.dispatchCommand(TOGGLE_LINK_COMMAND, newLinkPayload)

View File

@@ -14,19 +14,19 @@ export const relationshipAfterReadPromise: AfterReadPromise<SerializedRelationsh
}) => {
const promises: Promise<void>[] = []
if (node?.fields?.id) {
const collection = req.payload.collections[node?.fields?.relationTo]
if (node?.value?.id) {
const collection = req.payload.collections[node?.relationTo]
if (collection) {
promises.push(
populate({
id: node?.fields?.id,
id: node.value.id,
collection,
currentDepth,
data: node.fields,
data: node,
depth,
field,
key: 'data',
key: 'value',
overrideAccess,
req,
showHiddenFields,

View File

@@ -33,15 +33,16 @@ const insertRelationship = ({
}) => {
if (!replaceNodeKey) {
editor.dispatchCommand(INSERT_RELATIONSHIP_COMMAND, {
id,
data: null,
relationTo,
value: {
id,
},
})
} else {
editor.update(() => {
const node = $getNodeByKey(replaceNodeKey)
if (node) {
node.replace($createRelationshipNode({ id, data: null, relationTo }))
node.replace($createRelationshipNode({ relationTo, value: { id } }))
}
})
}

View File

@@ -18,18 +18,16 @@ import * as React from 'react'
import { RelationshipComponent } from './components/RelationshipComponent'
export type RelationshipFields = {
data: null | unknown
id: string
export type RelationshipData = {
relationTo: string
value: {
// Actual relationship, populated in afterRead hook
[key: string]: unknown
id: string
}
}
export type SerializedRelationshipNode = Spread<
{
fields: RelationshipFields
},
SerializedDecoratorBlockNode
>
export type SerializedRelationshipNode = Spread<RelationshipData, SerializedDecoratorBlockNode>
function relationshipElementToNode(domNode: HTMLDivElement): DOMConversionOutput | null {
const id = domNode.getAttribute('data-lexical-relationship-id')
@@ -37,9 +35,10 @@ function relationshipElementToNode(domNode: HTMLDivElement): DOMConversionOutput
if (id != null && relationTo != null) {
const node = $createRelationshipNode({
id,
data: null,
relationTo,
value: {
id,
},
})
return { node }
}
@@ -47,24 +46,24 @@ function relationshipElementToNode(domNode: HTMLDivElement): DOMConversionOutput
}
export class RelationshipNode extends DecoratorBlockNode {
__fields: RelationshipFields
__data: RelationshipData
constructor({
fields,
data,
format,
key,
}: {
fields: RelationshipFields
data: RelationshipData
format?: ElementFormatType
key?: NodeKey
}) {
super(format, key)
this.__fields = fields
this.__data = data
}
static clone(node: RelationshipNode): RelationshipNode {
return new RelationshipNode({
fields: node.__fields,
data: node.__data,
format: node.__format,
key: node.__key,
})
@@ -92,7 +91,11 @@ export class RelationshipNode extends DecoratorBlockNode {
}
static importJSON(serializedNode: SerializedRelationshipNode): RelationshipNode {
const node = $createRelationshipNode(serializedNode.fields)
const importedData: RelationshipData = {
relationTo: serializedNode.relationTo,
value: serializedNode.value,
}
const node = $createRelationshipNode(importedData)
node.setFormat(serializedNode.format)
return node
}
@@ -104,7 +107,7 @@ export class RelationshipNode extends DecoratorBlockNode {
return (
<RelationshipComponent
className={config.theme.relationship ?? 'LexicalEditorTheme__relationship'}
fields={this.__fields}
data={this.__data}
format={this.__format}
nodeKey={this.getKey()}
/>
@@ -113,8 +116,8 @@ export class RelationshipNode extends DecoratorBlockNode {
exportDOM(): DOMExportOutput {
const element = document.createElement('div')
element.setAttribute('data-lexical-relationship-id', this.__fields?.id)
element.setAttribute('data-lexical-relationship-relationTo', this.__fields?.relationTo)
element.setAttribute('data-lexical-relationship-id', this.__data?.value?.id)
element.setAttribute('data-lexical-relationship-relationTo', this.__data?.relationTo)
const text = document.createTextNode(this.getTextContent())
element.append(text)
@@ -124,14 +127,14 @@ export class RelationshipNode extends DecoratorBlockNode {
exportJSON(): SerializedRelationshipNode {
return {
...super.exportJSON(),
fields: this.getFields(),
...this.getData(),
type: this.getType(),
version: 1,
}
}
getFields(): RelationshipFields {
return this.getLatest().__fields
getData(): RelationshipData {
return this.getLatest().__data
}
getId(): string {
@@ -139,18 +142,18 @@ export class RelationshipNode extends DecoratorBlockNode {
}
getTextContent(): string {
return `${this?.__fields?.relationTo} relation to ${this.__fields?.id}`
return `${this?.__data?.relationTo} relation to ${this.__data?.value?.id}`
}
setFields(fields: RelationshipFields): void {
setData(data: RelationshipData): void {
const writable = this.getWritable()
writable.__fields = fields
writable.__data = data
}
}
export function $createRelationshipNode(fields: RelationshipFields): RelationshipNode {
export function $createRelationshipNode(data: RelationshipData): RelationshipNode {
return new RelationshipNode({
fields,
data,
})
}

View File

@@ -9,7 +9,7 @@ import { getTranslation } from 'payload/utilities'
import React, { useCallback, useReducer, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { RelationshipFields } from '../RelationshipNode'
import type { RelationshipData } from '../RelationshipNode'
import { useEditorConfigContext } from '../../../../lexical/config/EditorConfigProvider'
import { INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND } from '../../drawer'
@@ -25,7 +25,7 @@ const initialParams = {
type Props = {
children?: React.ReactNode
className?: string
fields: RelationshipFields
data: RelationshipData
format?: ElementFormatType
nodeKey?: string
}
@@ -33,7 +33,10 @@ type Props = {
const Component: React.FC<Props> = (props) => {
const {
children,
fields: { id, relationTo },
data: {
relationTo,
value: { id },
},
nodeKey,
} = props

View File

@@ -5,12 +5,12 @@ import { useConfig } from 'payload/components/utilities'
import { useEffect } from 'react'
import React from 'react'
import type { RelationshipFields } from '../nodes/RelationshipNode'
import type { RelationshipData } from '../nodes/RelationshipNode'
import { RelationshipDrawer } from '../drawer'
import { $createRelationshipNode, RelationshipNode } from '../nodes/RelationshipNode'
export const INSERT_RELATIONSHIP_COMMAND: LexicalCommand<RelationshipFields> = createCommand(
export const INSERT_RELATIONSHIP_COMMAND: LexicalCommand<RelationshipData> = createCommand(
'INSERT_RELATIONSHIP_COMMAND',
)
@@ -23,7 +23,7 @@ export default function RelationshipPlugin(): JSX.Element | null {
throw new Error('RelationshipPlugin: RelationshipNode not registered on editor')
}
return editor.registerCommand<RelationshipFields>(
return editor.registerCommand<RelationshipData>(
INSERT_RELATIONSHIP_COMMAND,
(payload) => {
const relationshipNode = $createRelationshipNode(payload)

View File

@@ -17,19 +17,20 @@ export const uploadAfterReadPromiseHOC = (
overrideAccess,
req,
showHiddenFields,
siblingDoc,
}) => {
const promises: Promise<void>[] = []
if (node?.fields?.value?.id) {
const collection = req.payload.collections[node?.fields?.relationTo]
if (node?.value?.id) {
const collection = req.payload.collections[node?.relationTo]
if (collection) {
promises.push(
populate({
id: node?.fields?.value?.id,
id: node?.value?.id,
collection,
currentDepth,
data: node.fields,
data: node,
depth,
field,
key: 'value',
@@ -39,17 +40,18 @@ export const uploadAfterReadPromiseHOC = (
}),
)
}
if (Array.isArray(props?.collections?.[node?.fields?.relationTo]?.fields)) {
if (Array.isArray(props?.collections?.[node?.relationTo]?.fields)) {
recurseNestedFields({
afterReadPromises,
currentDepth,
data: node.fields || {},
depth,
fields: props?.collections?.[node?.fields?.relationTo]?.fields,
fields: props?.collections?.[node?.relationTo]?.fields,
overrideAccess,
promises,
req,
showHiddenFields,
siblingDoc,
})
}
}

View File

@@ -19,7 +19,7 @@ import { useTranslation } from 'react-i18next'
import type { ElementProps } from '..'
import type { UploadFeatureProps } from '../..'
import type { UploadNode } from '../../nodes/UploadNode'
import type { UploadData, UploadNode } from '../../nodes/UploadNode'
import { useEditorConfigContext } from '../../../../lexical/config/EditorConfigProvider'
@@ -34,9 +34,8 @@ export const ExtraFieldsUploadDrawer: React.FC<
}
> = (props) => {
const {
data: { fields, relationTo, value },
drawerSlug,
fields: { relationTo, value },
fields,
nodeKey,
relatedCollection,
} = props
@@ -69,11 +68,11 @@ export const ExtraFieldsUploadDrawer: React.FC<
editor.update(() => {
const uploadNode: UploadNode | null = $getNodeByKey(nodeKey)
if (uploadNode) {
const newFields = {
...uploadNode.getFields(),
...data,
const newData: UploadData = {
...uploadNode.getData(),
fields: data,
}
uploadNode.setFields(newFields)
uploadNode.setData(newData)
}
})

View File

@@ -13,7 +13,7 @@ import React, { useCallback, useReducer, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { UploadFeatureProps } from '..'
import type { UploadFields } from '../nodes/UploadNode'
import type { UploadData } from '../nodes/UploadNode'
import { useEditorConfigContext } from '../../../lexical/config/EditorConfigProvider'
import { EnabledRelationshipsCondition } from '../../Relationship/utils/EnabledRelationshipsCondition'
@@ -28,14 +28,14 @@ const initialParams = {
}
export type ElementProps = {
fields: UploadFields
data: UploadData
nodeKey: string
//uploadProps: UploadFeatureProps
}
const Component: React.FC<ElementProps> = (props) => {
const {
fields: { relationTo, value },
data: { fields, relationTo, value },
nodeKey,
} = props

View File

@@ -34,6 +34,7 @@ const insertUpload = ({
if (!replaceNodeKey) {
editor.dispatchCommand(INSERT_UPLOAD_COMMAND, {
id,
fields: null,
relationTo,
})
} else {
@@ -42,7 +43,8 @@ const insertUpload = ({
if (node) {
node.replace(
$createUploadNode({
fields: {
data: {
fields: null,
relationTo,
value: {
id,

View File

@@ -16,13 +16,19 @@ import * as React from 'react'
const RawUploadComponent = React.lazy(async () => await import('../component'))
export interface RawUploadPayload {
fields: {
// unknown, custom fields:
[key: string]: unknown
}
id: string
relationTo: string
}
export type UploadFields = {
// unknown, custom fields:
[key: string]: unknown
export type UploadData = {
fields: {
// unknown, custom fields:
[key: string]: unknown
}
relationTo: string
value: {
// Actual upload data, populated in afterRead hook
@@ -41,32 +47,27 @@ function convertUploadElement(domNode: Node): DOMConversionOutput | null {
return null
}
export type SerializedUploadNode = Spread<
{
fields: UploadFields
},
SerializedDecoratorBlockNode
>
export type SerializedUploadNode = Spread<UploadData, SerializedDecoratorBlockNode>
export class UploadNode extends DecoratorBlockNode {
__fields: UploadFields
__data: UploadData
constructor({
fields,
data,
format,
key,
}: {
fields: UploadFields
data: UploadData
format?: ElementFormatType
key?: NodeKey
}) {
super(format, key)
this.__fields = fields
this.__data = data
}
static clone(node: UploadNode): UploadNode {
return new UploadNode({
fields: node.__fields,
data: node.__data,
format: node.__format,
key: node.__key,
})
@@ -86,9 +87,13 @@ export class UploadNode extends DecoratorBlockNode {
}
static importJSON(serializedNode: SerializedUploadNode): UploadNode {
const node = $createUploadNode({
const importedData: UploadData = {
fields: serializedNode.fields,
})
relationTo: serializedNode.relationTo,
value: serializedNode.value,
}
const node = $createUploadNode({ data: importedData })
node.setFormat(serializedNode.format)
return node
@@ -99,9 +104,7 @@ export class UploadNode extends DecoratorBlockNode {
}
decorate(): JSX.Element {
return (
<RawUploadComponent fields={this.__fields} format={this.__format} nodeKey={this.getKey()} />
)
return <RawUploadComponent data={this.__data} format={this.__format} nodeKey={this.getKey()} />
}
exportDOM(): DOMExportOutput {
@@ -114,19 +117,19 @@ export class UploadNode extends DecoratorBlockNode {
exportJSON(): SerializedUploadNode {
return {
...super.exportJSON(),
fields: this.getFields(),
...this.getData(),
type: this.getType(),
version: 1,
}
}
getFields(): UploadFields {
return this.getLatest().__fields
getData(): UploadData {
return this.getLatest().__data
}
setFields(fields: UploadFields): void {
setData(data: UploadData): void {
const writable = this.getWritable()
writable.__fields = fields
writable.__data = data
}
// eslint-disable-next-line class-methods-use-this
@@ -135,8 +138,8 @@ export class UploadNode extends DecoratorBlockNode {
}
}
export function $createUploadNode({ fields }: { fields: UploadFields }): UploadNode {
return $applyNodeReplacement(new UploadNode({ fields }))
export function $createUploadNode({ data }: { data: UploadData }): UploadNode {
return $applyNodeReplacement(new UploadNode({ data }))
}
export function $isUploadNode(node: LexicalNode | null | undefined): node is UploadNode {

View File

@@ -29,7 +29,8 @@ export function UploadPlugin(): JSX.Element | null {
(payload: InsertUploadPayload) => {
editor.update(() => {
const uploadNode = $createUploadNode({
fields: {
data: {
fields: payload.fields,
relationTo: payload.relationTo,
value: {
id: payload.id,

View File

@@ -14,12 +14,12 @@ export const uploadValidation = (): NodeValidation<SerializedUploadNode> => {
}) => {
if (!CAN_USE_DOM) {
const idField = payloadConfig.collections
.find(({ slug }) => slug === node.fields.relationTo)
.find(({ slug }) => slug === node.relationTo)
.fields.find((field) => fieldAffectsData(field) && field.name === 'id')
const type = getIDType(idField, validation?.options?.payload?.db?.defaultIDType)
if (!isValidID(node.fields.value.id, type)) {
if (!isValidID(node.value?.id, type)) {
return validation.options.t('validation:validUploadID')
}
}

View File

@@ -19,6 +19,7 @@ export type AfterReadPromise<T extends SerializedLexicalNode = SerializedLexical
overrideAccess,
req,
showHiddenFields,
siblingDoc,
}: {
afterReadPromises: Map<string, Array<AfterReadPromise>>
currentDepth: number
@@ -28,6 +29,7 @@ export type AfterReadPromise<T extends SerializedLexicalNode = SerializedLexical
overrideAccess: boolean
req: PayloadRequest
showHiddenFields: boolean
siblingDoc: Record<string, unknown>
}) => Promise<void>[]
export type NodeValidation<T extends SerializedLexicalNode = SerializedLexicalNode> = ({

View File

@@ -1,6 +1,10 @@
export function cloneDeep<T>(object: T): T {
export function cloneDeep<T>(object: T, cache: WeakMap<any, any> = new WeakMap()): T {
if (object === null) return null
if (cache.has(object)) {
return cache.get(object)
}
// Handle Date
if (object instanceof Date) {
return new Date(object.getTime()) as unknown as T
@@ -11,19 +15,39 @@ export function cloneDeep<T>(object: T): T {
return new RegExp(object.source, object.flags) as unknown as T
}
// Handle Array
if (Array.isArray(object)) {
return object.map((item) => cloneDeep(item)) as unknown as T
// Handle Map
if (object instanceof Map) {
const clonedMap = new Map()
cache.set(object, clonedMap)
for (const [key, value] of object.entries()) {
clonedMap.set(key, cloneDeep(value, cache))
}
return clonedMap as unknown as T
}
// Handle plain Object
// Handle Set
if (object instanceof Set) {
const clonedSet = new Set()
cache.set(object, clonedSet)
for (const value of object.values()) {
clonedSet.add(cloneDeep(value, cache))
}
return clonedSet as unknown as T
}
// Handle Array and Object
if (typeof object === 'object' && object !== null) {
const clonedObject: any = {}
const clonedObject: any = Array.isArray(object)
? []
: Object.create(Object.getPrototypeOf(object))
cache.set(object, clonedObject)
for (const key in object) {
if (object.hasOwnProperty(key)) {
clonedObject[key] = cloneDeep(object[key])
if (object.hasOwnProperty(key) || Object.getOwnPropertySymbols(object).includes(key as any)) {
clonedObject[key] = cloneDeep(object[key], cache)
}
}
return clonedObject as T
}

View File

@@ -1,13 +1,10 @@
import type { SerializedEditorState } from 'lexical'
import type { Field, PayloadRequest, RichTextField } from 'payload/types'
import type { Field, PayloadRequest, RichTextAdapter } from 'payload/types'
import { fieldAffectsData, fieldHasSubFields, fieldIsArrayType } from 'payload/types'
import type { AfterReadPromise } from '../field/features/types'
import type { AdapterProps } from '../types'
import { populate } from './populate'
import { recurseRichText } from './richTextRelationshipPromise'
type NestedRichTextFieldsArgs = {
afterReadPromises: Map<string, Array<AfterReadPromise>>
@@ -19,6 +16,7 @@ type NestedRichTextFieldsArgs = {
promises: Promise<void>[]
req: PayloadRequest
showHiddenFields: boolean
siblingDoc: Record<string, unknown>
}
export const recurseNestedFields = ({
@@ -31,6 +29,7 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
}: NestedRichTextFieldsArgs): void => {
fields.forEach((field) => {
if (field.type === 'relationship' || field.type === 'upload') {
@@ -128,6 +127,7 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
} else {
recurseNestedFields({
@@ -140,6 +140,7 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
}
} else if (field.type === 'tabs') {
@@ -154,6 +155,7 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
})
} else if (Array.isArray(data[field.name])) {
@@ -171,6 +173,7 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
}
})
@@ -188,29 +191,31 @@ export const recurseNestedFields = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
})
}
}
if (field.type === 'richText' && Array.isArray(data[field.name])) {
;(data[field.name] as SerializedEditorState).root.children.forEach((node) => {
if ('children' in node && Array.isArray(node.children)) {
// This assumes that the richText editor is using lexical and not slate.
// TODO: Throw an error if Slate is used. That would be cursed, who'd do that?
recurseRichText({
afterReadPromises,
children: node.children,
currentDepth,
depth,
field: field as RichTextField<AdapterProps>,
overrideAccess,
promises,
req,
showHiddenFields,
})
if (field.type === 'richText') {
// TODO: This does not properly work yet. E.g. it does not handle a relationship inside of lexical inside of block inside of lexical
const editor: RichTextAdapter = field?.editor
if (editor?.afterReadPromise) {
const afterReadPromise = editor.afterReadPromise({
currentDepth,
depth,
field,
overrideAccess,
req,
showHiddenFields,
siblingDoc,
})
if (afterReadPromise) {
promises.push(afterReadPromise)
}
})
}
}
})
}

View File

@@ -18,6 +18,7 @@ type RecurseRichTextArgs = {
promises: Promise<void>[]
req: PayloadRequest
showHiddenFields: boolean
siblingDoc?: Record<string, unknown>
}
export const recurseRichText = ({
@@ -30,6 +31,7 @@ export const recurseRichText = ({
promises,
req,
showHiddenFields,
siblingDoc,
}: RecurseRichTextArgs): void => {
if (depth <= 0 || currentDepth > depth) {
return
@@ -49,6 +51,7 @@ export const recurseRichText = ({
overrideAccess,
req,
showHiddenFields,
siblingDoc,
}),
)
}
@@ -65,6 +68,7 @@ export const recurseRichText = ({
promises,
req,
showHiddenFields,
siblingDoc,
})
}
})
@@ -93,6 +97,7 @@ export const richTextRelationshipPromise = async ({
promises,
req,
showHiddenFields,
siblingDoc,
})
await Promise.all(promises)

View File

@@ -90,7 +90,9 @@ export function generateLexicalRichText() {
fields: {
url: 'https://',
doc: {
value: '{{ARRAY_DOC_ID}}',
value: {
id: '{{ARRAY_DOC_ID}}',
},
relationTo: 'array-fields',
},
newTab: false,
@@ -117,13 +119,10 @@ export function generateLexicalRichText() {
format: '',
type: 'relationship',
version: 1,
fields: {
value: {
id: '{{TEXT_DOC_ID}}',
data: {
id: '{{TEXT_DOC_ID}}',
},
relationTo: 'text-fields',
},
relationTo: 'text-fields',
},
{
children: [
@@ -234,11 +233,11 @@ export function generateLexicalRichText() {
format: '',
type: 'upload',
version: 1,
relationTo: 'uploads',
value: {
id: '{{UPLOAD_DOC_ID}}',
},
fields: {
relationTo: 'uploads',
value: {
id: '{{UPLOAD_DOC_ID}}',
},
caption: {
root: {
type: 'root',