Skip to content

Commit fe25b54

Browse files
authored
fix(ui): unique ids for nested rows on row duplicate to prevent errors with postgres (#8790)
Fixes #8784 This works for any deep level, both arrays and blocks.
1 parent ef8a5b1 commit fe25b54

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

packages/ui/src/forms/Form/fieldReducer.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,15 @@ export function fieldReducer(state: FormState, action: FieldAction): FormState {
263263
duplicateRowState.id.initialValue = new ObjectId().toHexString()
264264
}
265265

266+
for (const key of Object.keys(duplicateRowState).filter((key) => key.endsWith('.id'))) {
267+
const idState = duplicateRowState[key]
268+
269+
if (idState && typeof idState.value === 'string' && ObjectId.isValid(idState.value)) {
270+
duplicateRowState[key].value = new ObjectId().toHexString()
271+
duplicateRowState[key].initialValue = new ObjectId().toHexString()
272+
}
273+
}
274+
266275
// If there are subfields
267276
if (Object.keys(duplicateRowState).length > 0) {
268277
// Add new object containing subfield names to unflattenedRows array

test/fields/collections/Blocks/e2e.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,24 @@ describe('Block fields', () => {
130130
expect(await blocks.count()).toEqual(4)
131131
})
132132

133+
test('should save when duplicating subblocks', async () => {
134+
await page.goto(url.create)
135+
const subblocksRow = page.locator('#field-blocks #blocks-row-2')
136+
const rowActions = subblocksRow.locator('.collapsible__actions').first()
137+
await expect(rowActions).toBeVisible()
138+
139+
await rowActions.locator('.array-actions__button').click()
140+
const duplicateButton = rowActions.locator('.array-actions__action.array-actions__duplicate')
141+
await expect(duplicateButton).toBeVisible()
142+
await duplicateButton.click()
143+
144+
const blocks = page.locator('#field-blocks > .blocks-field__rows > div')
145+
expect(await blocks.count()).toEqual(4)
146+
147+
await page.click('#action-save')
148+
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
149+
})
150+
133151
test('should use i18n block labels', async () => {
134152
await page.goto(url.create)
135153
await expect(page.locator('#field-i18nBlocks .blocks-field__header')).toContainText('Block en')

0 commit comments

Comments
 (0)