From 4090aebb0e94e776258f0c1c761044a4744a1857 Mon Sep 17 00:00:00 2001 From: Jacob Fletcher Date: Tue, 5 Dec 2023 00:53:11 -0500 Subject: [PATCH] fix(live-preview): populates rte uploads and relationships (#4379) --- packages/live-preview/src/traverseRichText.ts | 16 +- test/live-preview/collections/Pages.ts | 10 +- test/live-preview/int.spec.ts | 426 ++++++++++++++++-- .../app/(pages)/[slug]/page.client.tsx | 1 - .../app/_blocks/Relationships/index.tsx | 10 +- .../app/_components/RichText/index.tsx | 14 +- .../_components/RichText/serializeLexical.tsx | 89 ++++ .../{serialize.tsx => serializeSlate.tsx} | 55 ++- test/live-preview/next-app/payload-types.ts | 48 +- test/live-preview/payload-types.ts | 25 +- test/live-preview/seed/home.ts | 60 ++- 11 files changed, 677 insertions(+), 77 deletions(-) create mode 100644 test/live-preview/next-app/app/_components/RichText/serializeLexical.tsx rename test/live-preview/next-app/app/_components/RichText/{serialize.tsx => serializeSlate.tsx} (55%) diff --git a/packages/live-preview/src/traverseRichText.ts b/packages/live-preview/src/traverseRichText.ts index 0e25047f0c..e73e026d51 100644 --- a/packages/live-preview/src/traverseRichText.ts +++ b/packages/live-preview/src/traverseRichText.ts @@ -53,13 +53,20 @@ export const traverseRichText = ({ ? Array.isArray(incomingData[key]) ? [] : {} - : incomingData[key] + : undefined } const isRelationship = key === 'value' && 'relationTo' in incomingData if (isRelationship) { - const needsPopulation = !result.value || typeof result.value !== 'object' + // or if there are no keys besides id + const needsPopulation = + !result.value || + typeof result.value !== 'object' || + (typeof result.value === 'object' && + Object.keys(result.value).length === 1 && + 'id' in result.value) + const hasChanged = result && typeof result === 'object' && @@ -71,7 +78,10 @@ export const traverseRichText = ({ } populationsByCollection[incomingData.relationTo].push({ - id: incomingData[key], + id: + incomingData[key] && typeof incomingData[key] === 'object' + ? incomingData[key].id + : incomingData[key], accessor: 'value', ref: result, }) diff --git a/test/live-preview/collections/Pages.ts b/test/live-preview/collections/Pages.ts index 5c4eae729b..fe5b483ad5 100644 --- a/test/live-preview/collections/Pages.ts +++ b/test/live-preview/collections/Pages.ts @@ -1,5 +1,6 @@ import type { CollectionConfig } from '../../../packages/payload/src/collections/config/types' +import { lexicalEditor } from '../../../packages/richtext-lexical/src' import { Archive } from '../blocks/ArchiveBlock' import { CallToAction } from '../blocks/CallToAction' import { Content } from '../blocks/Content' @@ -62,8 +63,15 @@ export const Pages: CollectionConfig = { label: 'Test', fields: [ { - name: 'relationshipInRichText', + label: 'Rich Text — Slate', type: 'richText', + name: 'richTextSlate', + }, + { + label: 'Rich Text — Lexical', + type: 'richText', + name: 'richTextLexical', + editor: lexicalEditor({}), }, { name: 'relationshipAsUpload', diff --git a/test/live-preview/int.spec.ts b/test/live-preview/int.spec.ts index 1b3f5b603b..7a47dd9ec3 100644 --- a/test/live-preview/int.spec.ts +++ b/test/live-preview/int.spec.ts @@ -154,10 +154,7 @@ describe('Collections - Live Preview', () => { expect(mergedData._numberOfRequests).toEqual(0) }) - // TODO: this test is not working in Postgres - // This is because of how relationships are handled in `mergeData` - // This test passes in MongoDB, though - it.skip('— uploads - adds and removes media', async () => { + it('— uploads - adds and removes media', async () => { const initialData: Partial = { title: 'Test Page', } @@ -198,6 +195,166 @@ describe('Collections - Live Preview', () => { expect(mergedDataWithoutUpload.hero.media).toBeFalsy() }) + + it('— uploads - populates within Slate rich text editor', async () => { + const initialData: Partial = { + title: 'Test Page', + } + + // Add upload + const merge1 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...initialData, + richTextSlate: [ + { + type: 'upload', + relationTo: 'media', + value: media.id, + }, + ], + }, + initialData, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge1.richTextSlate).toHaveLength(1) + expect(merge1.richTextSlate[0].value).toMatchObject(media) + expect(merge1._numberOfRequests).toEqual(1) + + // Remove upload + const merge2 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...merge1, + richTextSlate: [ + { + type: 'paragraph', + children: [ + { + text: 'Hello, world!', + }, + ], + }, + ], + }, + initialData, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge2.richTextSlate).toHaveLength(1) + expect(merge2.richTextSlate[0].value).toBeFalsy() + expect(merge2.richTextSlate[0].type).toEqual('paragraph') + expect(merge2._numberOfRequests).toEqual(0) + }) + + it('— uploads - populates within Lexical rich text editor', async () => { + const initialData: Partial = { + title: 'Test Page', + } + + // Add upload + const merge1 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...initialData, + richTextLexical: { + root: { + type: 'root', + format: '', + indent: 0, + version: 1, + children: [ + { + children: [ + { + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: 'Hello, world!', + type: 'text', + version: 1, + }, + ], + direction: 'ltr', + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + { + format: '', + type: 'upload', + relationTo: 'media', + version: 1, + value: media.id, + }, + ], + direction: 'ltr', + }, + }, + }, + initialData, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge1.richTextLexical.root.children).toHaveLength(2) + expect(merge1.richTextLexical.root.children[1].value).toMatchObject(media) + expect(merge1._numberOfRequests).toEqual(1) + + // Remove upload + const merge2 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...merge1, + richTextLexical: { + root: { + type: 'root', + format: '', + indent: 0, + version: 1, + children: [ + { + children: [ + { + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: 'Hello, world!', + type: 'text', + version: 1, + }, + ], + direction: 'ltr', + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + ], + direction: 'ltr', + }, + }, + }, + initialData, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge2.richTextLexical.root.children).toHaveLength(1) + expect(merge2.richTextLexical.root.children[0].value).toBeFalsy() + expect(merge2.richTextLexical.root.children[0].type).toEqual('paragraph') + }) + it('— relationships - populates monomorphic has one relationships', async () => { const initialData: Partial = { title: 'Test Page', @@ -422,7 +579,7 @@ describe('Collections - Live Preview', () => { }, ], }, - initialData, + initialData: merge1, serverURL, returnNumberOfRequests: true, }) @@ -451,7 +608,130 @@ describe('Collections - Live Preview', () => { ]) }) - it('— relationships - populates within rich text', async () => { + it('— relationships - populates within Slate rich text editor', async () => { + const initialData: Partial = { + title: 'Test Page', + } + + // Add a relationship and an upload + const merge1 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...initialData, + richTextSlate: [ + { + children: [ + { + text: ' ', + }, + ], + relationTo: 'posts', + type: 'relationship', + value: { + id: testPost.id, + }, + }, + { + type: 'paragraph', + children: [ + { + text: '', + }, + ], + }, + { + children: [ + { + text: '', + }, + ], + relationTo: 'media', + type: 'upload', + value: { + id: media.id, + }, + }, + ], + }, + initialData, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge1._numberOfRequests).toEqual(2) + expect(merge1.richTextSlate).toHaveLength(3) + expect(merge1.richTextSlate[0].type).toEqual('relationship') + expect(merge1.richTextSlate[0].value).toMatchObject(testPost) + expect(merge1.richTextSlate[1].type).toEqual('paragraph') + expect(merge1.richTextSlate[2].type).toEqual('upload') + expect(merge1.richTextSlate[2].value).toMatchObject(media) + + // Add a new node between the relationship and the upload + const merge2 = await mergeData({ + depth: 1, + fieldSchema: schemaJSON, + incomingData: { + ...merge1, + richTextSlate: [ + { + children: [ + { + text: ' ', + }, + ], + relationTo: 'posts', + type: 'relationship', + value: { + id: testPost.id, + }, + }, + { + type: 'paragraph', + children: [ + { + text: '', + }, + ], + }, + { + type: 'paragraph', + children: [ + { + text: '', + }, + ], + }, + { + children: [ + { + text: '', + }, + ], + relationTo: 'media', + type: 'upload', + value: { + id: media.id, + }, + }, + ], + }, + initialData: merge1, + serverURL, + returnNumberOfRequests: true, + }) + + expect(merge2._numberOfRequests).toEqual(1) + expect(merge2.richTextSlate).toHaveLength(4) + expect(merge2.richTextSlate[0].type).toEqual('relationship') + expect(merge2.richTextSlate[0].value).toMatchObject(testPost) + expect(merge2.richTextSlate[1].type).toEqual('paragraph') + expect(merge2.richTextSlate[2].type).toEqual('paragraph') + expect(merge2.richTextSlate[3].type).toEqual('upload') + expect(merge2.richTextSlate[3].value).toMatchObject(media) + }) + + it('— relationships - populates within Lexical rich text editor', async () => { const initialData: Partial = { title: 'Test Page', } @@ -462,56 +742,130 @@ describe('Collections - Live Preview', () => { fieldSchema: schemaJSON, incomingData: { ...initialData, - relationshipInRichText: [ - { - type: 'paragraph', - text: 'Paragraph 1', + richTextLexical: { + root: { + type: 'root', + format: '', + indent: 0, + version: 1, + children: [ + { + format: '', + type: 'relationship', + version: 1, + relationTo: 'posts', + value: { + id: testPost.id, + }, + }, + { + children: [], + direction: null, + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + { + format: '', + type: 'upload', + version: 1, + fields: null, + relationTo: 'media', + value: { + id: media.id, + }, + }, + ], + direction: null, }, - { - type: 'reference', - reference: { - relationTo: 'posts', - value: testPost.id, - }, - }, - ], + }, }, initialData, serverURL, returnNumberOfRequests: true, }) - expect(merge1._numberOfRequests).toEqual(1) - expect(merge1.relationshipInRichText).toHaveLength(2) - expect(merge1.relationshipInRichText[1].reference.value).toMatchObject(testPost) + expect(merge1._numberOfRequests).toEqual(2) + expect(merge1.richTextLexical.root.children).toHaveLength(3) + expect(merge1.richTextLexical.root.children[0].type).toEqual('relationship') + expect(merge1.richTextLexical.root.children[0].value).toMatchObject(testPost) + expect(merge1.richTextLexical.root.children[1].type).toEqual('paragraph') + expect(merge1.richTextLexical.root.children[2].type).toEqual('upload') + expect(merge1.richTextLexical.root.children[2].value).toMatchObject(media) - // Remove the relationship + // Add a node before the populated one const merge2 = await mergeData({ depth: 1, fieldSchema: schemaJSON, incomingData: { ...merge1, - relationshipInRichText: [ - { - type: 'paragraph', - text: 'Paragraph 1', + richTextLexical: { + root: { + type: 'root', + format: '', + indent: 0, + version: 1, + children: [ + { + format: '', + type: 'relationship', + version: 1, + relationTo: 'posts', + value: { + id: testPost.id, + }, + }, + { + children: [], + direction: null, + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + { + children: [], + direction: null, + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + { + format: '', + type: 'upload', + version: 1, + fields: null, + relationTo: 'media', + value: { + id: media.id, + }, + }, + ], + direction: null, }, - ], + }, }, - initialData, + initialData: merge1, serverURL, returnNumberOfRequests: true, }) - expect(merge2._numberOfRequests).toEqual(0) - expect(merge2.relationshipInRichText).toHaveLength(1) - expect(merge2.relationshipInRichText[0].type).toEqual('paragraph') + expect(merge2._numberOfRequests).toEqual(1) + expect(merge2.richTextLexical.root.children).toHaveLength(4) + expect(merge2.richTextLexical.root.children[0].type).toEqual('relationship') + expect(merge2.richTextLexical.root.children[0].value).toMatchObject(testPost) + expect(merge2.richTextLexical.root.children[1].type).toEqual('paragraph') + expect(merge2.richTextLexical.root.children[2].type).toEqual('paragraph') + expect(merge2.richTextLexical.root.children[3].type).toEqual('upload') + expect(merge2.richTextLexical.root.children[3].value).toMatchObject(media) }) it('— relationships - does not re-populate existing rich text relationships', async () => { const initialData: Partial = { title: 'Test Page', - relationshipInRichText: [ + richTextSlate: [ { type: 'paragraph', text: 'Paragraph 1', @@ -532,7 +886,7 @@ describe('Collections - Live Preview', () => { fieldSchema: schemaJSON, incomingData: { ...initialData, - relationshipInRichText: [ + richTextSlate: [ { type: 'paragraph', text: 'Paragraph 1 (Updated)', @@ -552,9 +906,9 @@ describe('Collections - Live Preview', () => { }) expect(merge1._numberOfRequests).toEqual(0) - expect(merge1.relationshipInRichText).toHaveLength(2) - expect(merge1.relationshipInRichText[0].text).toEqual('Paragraph 1 (Updated)') - expect(merge1.relationshipInRichText[1].reference.value).toMatchObject(testPost) + expect(merge1.richTextSlate).toHaveLength(2) + expect(merge1.richTextSlate[0].text).toEqual('Paragraph 1 (Updated)') + expect(merge1.richTextSlate[1].reference.value).toMatchObject(testPost) }) it('— relationships - populates within blocks', async () => { diff --git a/test/live-preview/next-app/app/(pages)/[slug]/page.client.tsx b/test/live-preview/next-app/app/(pages)/[slug]/page.client.tsx index 7eb0ef707a..3b15594a31 100644 --- a/test/live-preview/next-app/app/(pages)/[slug]/page.client.tsx +++ b/test/live-preview/next-app/app/(pages)/[slug]/page.client.tsx @@ -6,7 +6,6 @@ import React from 'react' import { PAYLOAD_SERVER_URL } from '@/app/_api/serverURL' import { Hero } from '@/app/_components/Hero' import { Blocks } from '@/app/_components/Blocks' -import { RelationshipsBlock } from '@/app/_blocks/Relationships' export const PageClient: React.FC<{ page: PageType diff --git a/test/live-preview/next-app/app/_blocks/Relationships/index.tsx b/test/live-preview/next-app/app/_blocks/Relationships/index.tsx index c85d8a9d9a..4dfea2d806 100644 --- a/test/live-preview/next-app/app/_blocks/Relationships/index.tsx +++ b/test/live-preview/next-app/app/_blocks/Relationships/index.tsx @@ -22,9 +22,15 @@ export const RelationshipsBlock: React.FC = (props) => This block is for testing purposes only. It renders every possible type of relationship.

- Rich Text: + Rich Text — Slate:

- {data?.relationshipInRichText && } + {data?.richTextSlate && } +

+ Rich Text — Lexical: +

+ {data?.richTextLexical && ( + + )}

Upload:

diff --git a/test/live-preview/next-app/app/_components/RichText/index.tsx b/test/live-preview/next-app/app/_components/RichText/index.tsx index 657d2d8d21..57b462fc78 100644 --- a/test/live-preview/next-app/app/_components/RichText/index.tsx +++ b/test/live-preview/next-app/app/_components/RichText/index.tsx @@ -1,17 +1,25 @@ import React from 'react' -import serialize from './serialize' +import serializeSlate from './serializeSlate' +import serializeLexical from './serializeLexical' import classes from './index.module.scss' -const RichText: React.FC<{ className?: string; content: any }> = ({ className, content }) => { +const RichText: React.FC<{ + className?: string + content: any + renderUploadFilenameOnly?: boolean + serializer?: 'lexical' | 'slate' +}> = ({ className, content, renderUploadFilenameOnly, serializer = 'slate' }) => { if (!content) { return null } return (
- {serialize(content)} + {serializer === 'slate' + ? serializeSlate(content, renderUploadFilenameOnly) + : serializeLexical(content, renderUploadFilenameOnly)}
) } diff --git a/test/live-preview/next-app/app/_components/RichText/serializeLexical.tsx b/test/live-preview/next-app/app/_components/RichText/serializeLexical.tsx new file mode 100644 index 0000000000..063a65d43c --- /dev/null +++ b/test/live-preview/next-app/app/_components/RichText/serializeLexical.tsx @@ -0,0 +1,89 @@ +import type { SerializedEditorState } from 'lexical' +import { CMSLink } from '../Link' +import { Media } from '../Media' + +const serializer = ( + content?: SerializedEditorState['root']['children'], + renderUploadFilenameOnly?: boolean, +): React.ReactNode | React.ReactNode[] => + content?.map((node, i) => { + switch (node.type) { + case 'h1': + return

{serializeLexical(node?.children, renderUploadFilenameOnly)}

+ + case 'h2': + return

{serializeLexical(node?.children, renderUploadFilenameOnly)}

+ + case 'h3': + return

{serializeLexical(node?.children, renderUploadFilenameOnly)}

+ + case 'h4': + return

{serializeLexical(node?.children, renderUploadFilenameOnly)}

+ + case 'h5': + return
{serializeLexical(node?.children, renderUploadFilenameOnly)}
+ + case 'h6': + return
{serializeLexical(node?.children, renderUploadFilenameOnly)}
+ + case 'quote': + return ( +
+ {serializeLexical(node?.children, renderUploadFilenameOnly)} +
+ ) + + case 'ul': + return
    {serializeLexical(node?.children, renderUploadFilenameOnly)}
+ + case 'ol': + return
    {serializeLexical(node.children, renderUploadFilenameOnly)}
+ + case 'li': + return
  • {serializeLexical(node.children, renderUploadFilenameOnly)}
  • + + case 'relationship': + return ( + + {node.value && typeof node.value === 'object' + ? node.value.title || node.value.id + : node.value} + + ) + + case 'link': + return ( + + {serializer(node?.children, renderUploadFilenameOnly)} + + ) + + case 'upload': + if (renderUploadFilenameOnly) { + return {node.value.filename} + } + + return + + case 'paragraph': + return

    {serializer(node?.children, renderUploadFilenameOnly)}

    + + case 'text': + return {node.text} + } + }) + +const serializeLexical = ( + content?: SerializedEditorState, + renderUploadFilenameOnly?: boolean, +): React.ReactNode | React.ReactNode[] => { + return serializer(content?.root?.children, renderUploadFilenameOnly) +} + +export default serializeLexical diff --git a/test/live-preview/next-app/app/_components/RichText/serialize.tsx b/test/live-preview/next-app/app/_components/RichText/serializeSlate.tsx similarity index 55% rename from test/live-preview/next-app/app/_components/RichText/serialize.tsx rename to test/live-preview/next-app/app/_components/RichText/serializeSlate.tsx index 571a47a0a1..bc82ea2aa4 100644 --- a/test/live-preview/next-app/app/_components/RichText/serialize.tsx +++ b/test/live-preview/next-app/app/_components/RichText/serializeSlate.tsx @@ -1,8 +1,8 @@ import React, { Fragment } from 'react' import escapeHTML from 'escape-html' -import Link from 'next/link' import { Text } from 'slate' import { CMSLink } from '../Link' +import { Media } from '../Media' // eslint-disable-next-line no-use-before-define type Children = Leaf[] @@ -15,7 +15,10 @@ type Leaf = { [key: string]: unknown } -const serialize = (children?: Children): React.ReactNode[] => +const serializeSlate = ( + children?: Children, + renderUploadFilenameOnly?: boolean, +): React.ReactNode[] => children?.map((node, i) => { if (Text.isText(node)) { let text = @@ -57,25 +60,39 @@ const serialize = (children?: Children): React.ReactNode[] => switch (node.type) { case 'h1': - return

    {serialize(node?.children)}

    + return

    {serializeSlate(node?.children, renderUploadFilenameOnly)}

    + case 'h2': - return

    {serialize(node?.children)}

    + return

    {serializeSlate(node?.children, renderUploadFilenameOnly)}

    + case 'h3': - return

    {serialize(node?.children)}

    + return

    {serializeSlate(node?.children, renderUploadFilenameOnly)}

    + case 'h4': - return

    {serialize(node?.children)}

    + return

    {serializeSlate(node?.children, renderUploadFilenameOnly)}

    + case 'h5': - return
    {serialize(node?.children)}
    + return
    {serializeSlate(node?.children, renderUploadFilenameOnly)}
    + case 'h6': - return
    {serialize(node?.children)}
    + return
    {serializeSlate(node?.children, renderUploadFilenameOnly)}
    + case 'quote': - return
    {serialize(node?.children)}
    + return ( +
    + {serializeSlate(node?.children, renderUploadFilenameOnly)} +
    + ) + case 'ul': - return
      {serialize(node?.children)}
    + return
      {serializeSlate(node?.children, renderUploadFilenameOnly)}
    + case 'ol': - return
      {serialize(node.children)}
    + return
      {serializeSlate(node.children, renderUploadFilenameOnly)}
    + case 'li': - return
  • {serialize(node.children)}
  • + return
  • {serializeSlate(node.children, renderUploadFilenameOnly)}
  • + case 'relationship': return ( @@ -84,6 +101,7 @@ const serialize = (children?: Children): React.ReactNode[] => : node.value} ) + case 'link': return ( reference={node.doc as any} newTab={Boolean(node?.newTab)} > - {serialize(node?.children)} + {serializeSlate(node?.children, renderUploadFilenameOnly)} ) + case 'upload': + if (renderUploadFilenameOnly) { + return {node.value.filename} + } + + return + default: - return

    {serialize(node?.children)}

    + return

    {serializeSlate(node?.children, renderUploadFilenameOnly)}

    } }) || [] -export default serialize +export default serializeSlate diff --git a/test/live-preview/next-app/payload-types.ts b/test/live-preview/next-app/payload-types.ts index 14c54a5b6a..e9f4006b35 100644 --- a/test/live-preview/next-app/payload-types.ts +++ b/test/live-preview/next-app/payload-types.ts @@ -11,6 +11,7 @@ export interface Config { users: User pages: Page posts: Post + tenants: Tenant categories: Category media: Media 'payload-preferences': PayloadPreference @@ -37,6 +38,7 @@ export interface User { export interface Page { id: string slug: string + tenant?: (string | null) | Tenant title: string hero: { type: 'none' | 'highImpact' | 'lowImpact' @@ -152,16 +154,6 @@ export interface Page { } )[] | null - meta?: { - title?: string | null - description?: string | null - image?: string | Media | null - } - relationshipInRichText?: - | { - [k: string]: unknown - }[] - | null relationshipAsUpload?: string | Media | null relationshipMonoHasOne?: (string | null) | Post relationshipMonoHasMany?: (string | Post)[] | null @@ -198,6 +190,41 @@ export interface Page { id?: string | null }[] | null + richTextSlate?: + | { + [k: string]: unknown + }[] + | null + richTextLexical?: { + root: { + children: { + type: string + version: number + [k: string]: unknown + }[] + direction: ('ltr' | 'rtl') | null + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' + indent: number + type: string + version: number + } + [k: string]: unknown + } | null + tab: { + relationshipInTab?: (string | null) | Post + } + meta?: { + title?: string | null + description?: string | null + image?: string | Media | null + } + updatedAt: string + createdAt: string +} +export interface Tenant { + id: string + title: string + clientURL: string updatedAt: string createdAt: string } @@ -221,6 +248,7 @@ export interface Media { export interface Post { id: string slug: string + tenant?: (string | null) | Tenant title: string hero: { type: 'none' | 'highImpact' | 'lowImpact' diff --git a/test/live-preview/payload-types.ts b/test/live-preview/payload-types.ts index 7e61f60d31..e9f4006b35 100644 --- a/test/live-preview/payload-types.ts +++ b/test/live-preview/payload-types.ts @@ -154,11 +154,6 @@ export interface Page { } )[] | null - relationshipInRichText?: - | { - [k: string]: unknown - }[] - | null relationshipAsUpload?: string | Media | null relationshipMonoHasOne?: (string | null) | Post relationshipMonoHasMany?: (string | Post)[] | null @@ -195,6 +190,26 @@ export interface Page { id?: string | null }[] | null + richTextSlate?: + | { + [k: string]: unknown + }[] + | null + richTextLexical?: { + root: { + children: { + type: string + version: number + [k: string]: unknown + }[] + direction: ('ltr' | 'rtl') | null + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' + indent: number + type: string + version: number + } + [k: string]: unknown + } | null tab: { relationshipInTab?: (string | null) | Post } diff --git a/test/live-preview/seed/home.ts b/test/live-preview/seed/home.ts index 1ad5eb8fbd..a5f7e298fa 100644 --- a/test/live-preview/seed/home.ts +++ b/test/live-preview/seed/home.ts @@ -95,7 +95,7 @@ export const home: Omit = { }, ], relationshipAsUpload: '{{MEDIA_ID}}', - relationshipInRichText: [ + richTextSlate: [ { children: [ { @@ -108,7 +108,65 @@ export const home: Omit = { id: '{{POST_1_ID}}', }, }, + { + type: 'paragraph', + children: [ + { + text: '', + }, + ], + }, + { + children: [ + { + text: '', + }, + ], + relationTo: 'media', + type: 'upload', + value: { + id: '{{MEDIA_ID}}', + }, + }, ], + richTextLexical: { + root: { + type: 'root', + format: '', + indent: 0, + version: 1, + children: [ + { + format: '', + type: 'relationship', + version: 1, + relationTo: 'posts', + value: { + id: '{{POST_1_ID}}', + }, + }, + { + children: [], + direction: null, + format: '', + indent: 0, + type: 'paragraph', + version: 1, + }, + { + format: '', + type: 'upload', + version: 1, + fields: null, + relationTo: 'media', + value: { + id: '{{MEDIA_ID}}', + }, + }, + ], + direction: null, + }, + }, relationshipMonoHasMany: ['{{POST_1_ID}}'], relationshipMonoHasOne: '{{POST_1_ID}}', relationshipPolyHasMany: [{ relationTo: 'posts', value: '{{POST_1_ID}}' }],