Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FormState } from 'payload'
import ObjectIdImport from 'bson-objectid'
import { describe, expect, it } from 'vitest'

import { mergeFormStateFromClipboard } from './mergeFormStateFromClipboard.js'
import { mergeFormStateFromClipboard, reduceFormStateByPath } from './mergeFormStateFromClipboard.js'
import type { ClipboardPasteData } from './types.js'

const ObjectId = (
Expand Down Expand Up @@ -550,3 +550,80 @@ describe('mergeFormStateFromClipboard', () => {
})
})
})

describe('reduceFormStateByPath', () => {
it('should strip lastRenderedPath from fields and rows so pasted content re-renders', () => {
const formState: FormState = {
layout: {
valid: true,
value: 1,
initialValue: 1,
rows: [
{
id: 'row-1',
blockType: 'content',
isLoading: false,
lastRenderedPath: 'layout.0',
},
],
},
'layout.0.id': {
value: 'row-1',
valid: true,
},
'layout.0.richText': {
value: 'test content',
valid: true,
lastRenderedPath: 'layout.0.richText',
},
}

const result = reduceFormStateByPath({
formState,
path: 'layout',
})

// lastRenderedPath must not survive the copy, otherwise pasting back onto the
// same path makes the server skip re-rendering and the block body renders blank
expect(result.layout.rows![0].lastRenderedPath).toBeUndefined()
expect(result['layout.0.richText'].lastRenderedPath).toBeUndefined()

// The rest of the state is preserved
expect(result.layout.rows![0].id).toEqual('row-1')
expect(result.layout.rows![0].blockType).toEqual('content')
expect(result['layout.0.richText'].value).toEqual('test content')
expect(result['layout.0.id'].value).toEqual('row-1')
})

it('should strip lastRenderedPath when copying a single row', () => {
const formState: FormState = {
'layout.0.nested': {
valid: true,
value: 1,
rows: [
{
id: 'nested-row-1',
isLoading: false,
lastRenderedPath: 'layout.0.nested.0',
},
],
},
'layout.0.richText': {
value: 'row content',
valid: true,
lastRenderedPath: 'layout.0.richText',
},
}

const result = reduceFormStateByPath({
formState,
path: 'layout',
rowIndex: 0,
})

expect(result['layout.0.richText'].lastRenderedPath).toBeUndefined()
expect(result['layout.0.nested'].rows![0].lastRenderedPath).toBeUndefined()
expect(result['layout.0.richText'].value).toEqual('row content')
expect(result['layout.0.nested'].rows![0].id).toEqual('nested-row-1')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ export function reduceFormStateByPath({
continue
}

const { customComponents: _, validate: __, ...field } = formState[key]
const { customComponents: _, lastRenderedPath: __, validate: ___, ...field } = formState[key]

if (Array.isArray(field.rows)) {
field.rows = field.rows.map((row) => {
if (!row || typeof row !== 'object') {
return row
}
const { customComponents: _, ...serializableRow } = row
const { customComponents: _, lastRenderedPath: __, ...serializableRow } = row
return serializableRow
})
}
Expand Down
Loading