fix(live-preview): property resets rte nodes (#4313)

This commit is contained in:
Jacob Fletcher
2023-11-29 12:24:51 -05:00
committed by GitHub
parent d4f28b16b4
commit 66679fbdd6
2 changed files with 93 additions and 46 deletions

View File

@@ -39,9 +39,27 @@ export const traverseRichText = ({
result = {} result = {}
} }
// Remove keys from `result` that do not appear in `incomingData`
// There's likely another way to do this,
// But recursion and references make this very difficult
Object.keys(result).forEach((key) => {
if (!(key in incomingData)) {
delete result[key]
}
})
// Iterate over the keys of `incomingData` and populate `result`
Object.keys(incomingData).forEach((key) => { Object.keys(incomingData).forEach((key) => {
if (!result[key]) { if (!result[key]) {
result[key] = incomingData[key] // Instantiate the key in `result` if it doesn't exist
// Ensure its type matches the type of the `incomingData`
// We don't have a schema to check against here
result[key] =
incomingData[key] && typeof incomingData[key] === 'object'
? Array.isArray(incomingData[key])
? []
: {}
: incomingData[key]
} }
const isRelationship = key === 'value' && 'relationTo' in incomingData const isRelationship = key === 'value' && 'relationTo' in incomingData

View File

@@ -4,6 +4,7 @@ import type { Media, Page, Post } from './payload-types'
import { handleMessage } from '../../packages/live-preview/src/handleMessage' import { handleMessage } from '../../packages/live-preview/src/handleMessage'
import { mergeData } from '../../packages/live-preview/src/mergeData' import { mergeData } from '../../packages/live-preview/src/mergeData'
import { traverseRichText } from '../../packages/live-preview/src/traverseRichText'
import payload from '../../packages/payload/src' import payload from '../../packages/payload/src'
import getFileByPath from '../../packages/payload/src/uploads/getFileByPath' import getFileByPath from '../../packages/payload/src/uploads/getFileByPath'
import { fieldSchemaToJSON } from '../../packages/payload/src/utilities/fieldSchemaToJSON' import { fieldSchemaToJSON } from '../../packages/payload/src/utilities/fieldSchemaToJSON'
@@ -494,7 +495,7 @@ describe('Collections - Live Preview', () => {
], ],
} }
// Add a relationship // Make a change to the text
const merge1 = await mergeData({ const merge1 = await mergeData({
depth: 1, depth: 1,
fieldSchema: schemaJSON, fieldSchema: schemaJSON,
@@ -503,7 +504,7 @@ describe('Collections - Live Preview', () => {
relationshipInRichText: [ relationshipInRichText: [
{ {
type: 'paragraph', type: 'paragraph',
text: 'Paragraph 1', text: 'Paragraph 1 (Updated)',
}, },
{ {
type: 'reference', type: 'reference',
@@ -521,6 +522,7 @@ describe('Collections - Live Preview', () => {
expect(merge1._numberOfRequests).toEqual(0) expect(merge1._numberOfRequests).toEqual(0)
expect(merge1.relationshipInRichText).toHaveLength(2) expect(merge1.relationshipInRichText).toHaveLength(2)
expect(merge1.relationshipInRichText[0].text).toEqual('Paragraph 1 (Updated)')
expect(merge1.relationshipInRichText[1].reference.value).toMatchObject(testPost) expect(merge1.relationshipInRichText[1].reference.value).toMatchObject(testPost)
}) })
@@ -584,68 +586,95 @@ describe('Collections - Live Preview', () => {
expect(merge2._numberOfRequests).toEqual(1) expect(merge2._numberOfRequests).toEqual(1)
}) })
it('— rich text - merges rich text', async () => { it('— rich text - merges text changes', async () => {
const initialData: Partial<Page> = {
title: 'Test Page',
}
// Add a relationship // Add a relationship
const merge1 = await mergeData({ const merge1 = await traverseRichText({
depth: 1, depth: 1,
fieldSchema: schemaJSON, apiRoute: undefined,
incomingData: { incomingData: [
...initialData, {
hero: { type: 'paragraph',
type: 'lowImpact', children: [
richText: [
{ {
type: 'paragraph', text: 'Paragraph 1',
children: [
{
text: 'Paragraph 1',
},
],
}, },
], ],
}, },
}, ],
initialData, result: [],
populationPromises: [],
serverURL, serverURL,
returnNumberOfRequests: true,
}) })
expect(merge1._numberOfRequests).toEqual(0) expect(merge1).toHaveLength(1)
expect(merge1.hero.richText).toHaveLength(1) expect(merge1[0].children[0].text).toEqual('Paragraph 1')
expect(merge1.hero.richText[0].children[0].text).toEqual('Paragraph 1')
// Update the rich text // Update the rich text
const merge2 = await mergeData({ const merge2 = await traverseRichText({
depth: 1, depth: 1,
fieldSchema: schemaJSON, apiRoute: undefined,
incomingData: { incomingData: [
...merge1, {
hero: { type: 'paragraph',
type: 'lowImpact', children: [
richText: [
{ {
type: 'paragraph', text: 'Paragraph 1 (Updated)',
children: [
{
text: 'Paragraph 1 (Updated)',
},
],
}, },
], ],
}, },
}, ],
initialData, populationPromises: [],
result: merge1,
serverURL, serverURL,
returnNumberOfRequests: true,
}) })
expect(merge2._numberOfRequests).toEqual(0) expect(merge2).toHaveLength(1)
expect(merge2.hero.richText).toHaveLength(1) expect(merge2[0].children[0].text).toEqual('Paragraph 1 (Updated)')
expect(merge2.hero.richText[0].children[0].text).toEqual('Paragraph 1 (Updated)') })
it('— rich text - can reset heading type', async () => {
// Add a heading with an H1 type
const merge1 = await traverseRichText({
depth: 1,
apiRoute: undefined,
incomingData: [
{
type: 'h1',
children: [
{
text: 'Heading',
},
],
},
],
populationPromises: [],
result: [],
serverURL,
})
expect(merge1).toHaveLength(1)
expect(merge1[0].type).toEqual('h1')
// Update the rich text to remove the heading type
const merge2 = await traverseRichText({
depth: 1,
apiRoute: undefined,
incomingData: [
{
children: [
{
text: 'Heading',
},
],
},
],
populationPromises: [],
result: merge1,
serverURL,
})
expect(merge2).toHaveLength(1)
expect(merge2[0].type).toBeUndefined()
}) })
it('— blocks - adds, reorders, and removes blocks', async () => { it('— blocks - adds, reorders, and removes blocks', async () => {