From eba777c3a0b4c489d87d3c6154d835a105fef4a2 Mon Sep 17 00:00:00 2001 From: Sasha <64744993+r1tsuu@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:21:36 +0300 Subject: [PATCH] fix: error saving after duplicating blocks with nested items (#8814) Fixes https://github.com/payloadcms/payload/issues/6583 Port of https://github.com/payloadcms/payload/pull/8790 to 2.0 --- .../components/forms/Form/fieldReducer.ts | 9 +++++ test/fields/e2e.spec.ts | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/packages/payload/src/admin/components/forms/Form/fieldReducer.ts b/packages/payload/src/admin/components/forms/Form/fieldReducer.ts index 2ac8c143883..f4b4ba2bce0 100644 --- a/packages/payload/src/admin/components/forms/Form/fieldReducer.ts +++ b/packages/payload/src/admin/components/forms/Form/fieldReducer.ts @@ -228,6 +228,15 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields { const duplicateRowState = deepCopyObject(rows[rowIndex]) if (duplicateRowState.id) duplicateRowState.id = new ObjectID().toHexString() + for (const key of Object.keys(duplicateRowState).filter((key) => key.endsWith('.id'))) { + const idState = duplicateRowState[key] + + if (idState && typeof idState.value === 'string' && ObjectID.isValid(idState.value)) { + duplicateRowState[key].value = new ObjectID().toHexString() + duplicateRowState[key].initialValue = new ObjectID().toHexString() + } + } + // If there are subfields if (Object.keys(duplicateRowState).length > 0) { // Add new object containing subfield names to unflattenedRows array diff --git a/test/fields/e2e.spec.ts b/test/fields/e2e.spec.ts index 709c6c7603f..47de77f8e88 100644 --- a/test/fields/e2e.spec.ts +++ b/test/fields/e2e.spec.ts @@ -767,6 +767,39 @@ describe('fields', () => { await expect(page.locator('.Toastify')).toContainText('Please correct invalid fields') }) + test('should duplicate block', async () => { + await page.goto(url.create) + const firstRow = page.locator('#field-blocks #blocks-row-0') + const rowActions = firstRow.locator('.collapsible__actions') + await expect(rowActions).toBeVisible() + + await rowActions.locator('.array-actions__button').click() + const duplicateButton = rowActions.locator('.array-actions__action.array-actions__duplicate') + await expect(duplicateButton).toBeVisible() + await duplicateButton.click() + + const blocks = page.locator('#field-blocks > .blocks-field__rows > div') + expect(await blocks.count()).toEqual(4) + }) + + test('should save when duplicating subblocks', async () => { + await page.goto(url.create) + const subblocksRow = page.locator('#field-blocks #blocks-row-2') + const rowActions = subblocksRow.locator('.collapsible__actions').first() + await expect(rowActions).toBeVisible() + + await rowActions.locator('.array-actions__button').click() + const duplicateButton = rowActions.locator('.array-actions__action.array-actions__duplicate') + await expect(duplicateButton).toBeVisible() + await duplicateButton.click() + + const blocks = page.locator('#field-blocks > .blocks-field__rows > div') + expect(await blocks.count()).toEqual(4) + + await page.click('#action-save') + await expect(page.locator('.Toastify')).toContainText('successfully') + }) + describe('row manipulation', () => { describe('react hooks', () => { test('should add 2 new block rows', async () => {