From b932de61fbfb53beb88db2a55eb5cd251ea9c16b Mon Sep 17 00:00:00 2001 From: Herman Wikner Date: Mon, 1 Jul 2024 14:00:58 +0200 Subject: [PATCH] fix(core): handle fieldset members in `FormInput` (#7045) * dev(test-studio): update `objectsDebug` schema * fix(core): handle fieldset members in `FormInput` * test(core): tree editing with fieldset array * test(core): fix tree editing component test --- dev/test-studio/schema/debug/objectsDebug.ts | 31 ++++++++++++++++ .../tree-editing/TreeEditing.spec.tsx | 36 +++++++++++++++++-- .../tree-editing/TreeEditingStory.tsx | 30 ++++++++++++++++ .../src/core/form/components/FormInput.tsx | 12 +++++-- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/dev/test-studio/schema/debug/objectsDebug.ts b/dev/test-studio/schema/debug/objectsDebug.ts index e7ac66385a7..b15043a32bf 100644 --- a/dev/test-studio/schema/debug/objectsDebug.ts +++ b/dev/test-studio/schema/debug/objectsDebug.ts @@ -213,6 +213,28 @@ const animals = defineField({ of: [animal], }) +const fieldsetArray = defineField({ + type: 'array', + name: 'fieldsetArray', + title: 'Fieldset array', + + fieldset: 'fieldset', + + of: [ + { + type: 'object', + name: 'myObject', + fields: [ + { + name: 'string', + type: 'string', + title: 'String', + }, + ], + }, + ], +}) + const arrayOfImages = defineField({ type: 'array', name: 'arrayOfImages', @@ -353,6 +375,14 @@ const arrayOfMixedTypes = defineField({ export const objectsDebug = defineType({ type: 'document', name: 'objectsDebug', + + fieldsets: [ + { + name: 'fieldset', + title: 'Fieldset', + }, + ], + fields: [ { name: 'title', @@ -361,6 +391,7 @@ export const objectsDebug = defineType({ animals, arrayOfMixedTypes, body, + fieldsetArray, objectWithArray, arrayOfAnonymousObjects, arrayOfImages, diff --git a/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditing.spec.tsx b/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditing.spec.tsx index 5963814d3f7..9a5901d6bad 100644 --- a/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditing.spec.tsx +++ b/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditing.spec.tsx @@ -29,6 +29,19 @@ const DOCUMENT_VALUE: SanityDocument = { title: 'My object 3', }, ], + + myFieldsetArray: [ + { + _type: 'myObject', + _key: 'key-1', + title: 'My object 1', + }, + { + _type: 'myObject', + _key: 'key-2', + title: 'My object 2', + }, + ], } test.describe('Tree editing', () => { @@ -38,8 +51,10 @@ test.describe('Tree editing', () => { }) => { await mount() + const field = page.getByTestId('field-myArrayOfObjects') + // Add an item - await page.getByTestId('add-single-object-button').click() + await field.getByTestId('add-single-object-button').click() // Wait for the dialog to be visible await expect(page.getByTestId('tree-editing-dialog')).toBeVisible() @@ -57,8 +72,10 @@ test.describe('Tree editing', () => { }) => { await mount() + const field = page.getByTestId('field-myArrayOfObjects') + // Add an item - await page.getByTestId('add-single-object-button').click() + await field.getByTestId('add-single-object-button').click() // Test that the legacy dialog is visible and the tree editing dialog is not await expect(page.getByTestId('tree-editing-dialog')).not.toBeVisible() @@ -169,6 +186,21 @@ test.describe('Tree editing', () => { await expect(stringInput).toHaveValue('My object 2') }) + test('should open dialog with correct form view based on the openPath when the array is in a fieldset', async ({ + mount, + page, + }) => { + await mount( + , + ) + + const dialog = page.getByTestId('tree-editing-dialog') + await expect(dialog).toBeVisible() + + const stringInput = dialog.getByTestId('string-input') + await expect(stringInput).toHaveValue('My object 2') + }) + test('should not open dialog when the openPath does not match any item', async ({ mount, page, diff --git a/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditingStory.tsx b/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditingStory.tsx index 66e58d330e7..c5803bc14bf 100644 --- a/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditingStory.tsx +++ b/packages/sanity/playwright-ct/tests/formBuilder/tree-editing/TreeEditingStory.tsx @@ -18,14 +18,44 @@ function getSchemaTypes(opts: GetSchemaTypesOpts) { type: 'document', name: 'test', title: 'Test', + + fieldsets: [ + { + name: 'fieldset', + }, + ], + fields: [ defineField({ type: 'array', name: 'myArrayOfObjects', title: 'My array of objects', + options: { treeEditing: treeEditingEnabled, }, + + of: [ + { + type: 'object', + name: 'myObject', + fields: [ + { + type: 'string', + name: 'title', + title: 'Title', + }, + ], + }, + ], + }), + + defineField({ + type: 'array', + name: 'myFieldsetArray', + title: 'My fieldset array', + fieldset: 'fieldset', + of: [ { type: 'object', diff --git a/packages/sanity/src/core/form/components/FormInput.tsx b/packages/sanity/src/core/form/components/FormInput.tsx index 876dad5501b..c78feffbcb1 100644 --- a/packages/sanity/src/core/form/components/FormInput.tsx +++ b/packages/sanity/src/core/form/components/FormInput.tsx @@ -249,11 +249,19 @@ const FormInputInner = memo(function FormInputInner( if (isObjectInputProps(props)) { const childPath = trimLeft(props.path, absolutePath) + const fieldMember = props.members.find( (member): member is FieldMember => member.kind == 'field' && childPath[0] === member.name, ) - if (!fieldMember) { + const fieldSetMember = props.members + .filter((member) => member.kind === 'fieldSet') + .flatMap((member) => (member.kind === 'fieldSet' && member.fieldSet?.members) || []) + .find((m): m is FieldMember => m.kind === 'field' && m.name === childPath[0]) + + const member = fieldMember || fieldSetMember + + if (!member) { const fieldName = typeof childPath[0] === 'string' ? childPath[0] : JSON.stringify(childPath[0]) @@ -262,7 +270,7 @@ const FormInputInner = memo(function FormInputInner( return (