Skip to content

Commit

Permalink
fix(core): handle array fields within nested objects in array items (#…
Browse files Browse the repository at this point in the history
…7069)

* fix(core): handle array fields within nested objects in array items

* dev(test-studio): update schema

* test(core): unit test `findArrayTypePaths`

* test(core): unit test nested objects in `buildTreeEditingState`

* test(core): component test tree editing with nested objects

* test(core): update tree editing navigation e2e test

* refactor(core): replace `isPortableTextSchemaType` with existing `isArrayOfBlocksSchemaType` asserter
  • Loading branch information
hermanwikner authored Jul 8, 2024
1 parent e54ae8a commit 3c057a8
Show file tree
Hide file tree
Showing 14 changed files with 22,846 additions and 2,281 deletions.
234 changes: 234 additions & 0 deletions dev/test-studio/schema/debug/objectsDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,238 @@ const arrayOfMixedTypes = defineField({
],
})

const arrayWithArrayInNestedObjects = defineField({
type: 'object',
name: 'rootObject',
fields: [
{
type: 'array',
name: 'level1Array',
title: 'Level 1 Array',
of: [
{
type: 'object',
name: 'level1Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'object',
name: 'level2Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'array',
name: 'level2Array',
title: 'Level 2 Array',
of: [
{
type: 'object',
name: 'level2ArrayObject',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'object',
name: 'level3Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'object',
name: 'level3NestedObject',
title: 'Level 3 Nested Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'object',
name: 'level3NestedNestedObject',
title: 'Level 3 Nested Nested Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'object',
name: 'level3DeepNestedObject',
title: 'Level 3 Deep Nested Object',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'array',
name: 'level3DeepNestedArray1',
title: 'Level 3 Array 1',
of: [
{
type: 'object',
name: 'level3DeepNestedArrayObject1',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
{
type: 'array',
name: 'level3DeepNestedArray1',
title: 'Level 3 Nested Array 1',
of: [
{
type: 'object',
name: 'level3DeepNestedArrayObject1',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
],
},
],
},
{
type: 'array',
name: 'level3DeepNestedArray2',
title: 'Level 3 Nested Array 2',
of: [
{
type: 'object',
name: 'level3DeepNestedArrayObject2',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
],
},
],
},
],
},
],
},
{
type: 'array',
name: 'level3DeepNestedArray2',
title: 'Level 3 Array 2',
of: [
{
type: 'object',
name: 'level3DeepNestedArrayObject2',
fields: [
{
type: 'string',
name: 'title',
title: 'Title',
},
],
},
],
},
],
},
],
},
],
},
],
},
],
},
],
},
],
},
{
name: 'level2AnotherArray',
type: 'array',
title: 'Level 2 Another Array',
of: [
{
type: 'object',
name: 'level2AnotherObject',
fields: [
{
type: 'string',
name: 'level2AnotherObjectString',
title: 'Level 2 Another Object String',
},
],
},
],
},
],
},
],
},
],
})

const arrayWithNestedObjectsWithArray = defineField({
name: 'arrayWithNestedObjectsWithArray',
type: 'array',
title: 'Array with nested objects with array',
of: [
{
type: 'object',
name: 'firstObject',
title: 'First object',
fields: [
{
type: 'object',
name: 'secondObject',
title: 'Second object',
fields: [
{
type: 'array',
name: 'nestedArray',
title: 'Nested array',
of: [
{
type: 'object',
name: 'nestedObject',
title: 'Nested object',
fields: [
{
type: 'string',
name: 'nestedString',
title: 'Nested string',
},
],
},
],
},
],
},
],
},
],
})

export const objectsDebug = defineType({
type: 'document',
name: 'objectsDebug',
Expand All @@ -396,5 +628,7 @@ export const objectsDebug = defineType({
arrayOfAnonymousObjects,
arrayOfImages,
arrayOfFiles,
arrayWithNestedObjectsWithArray,
arrayWithArrayInNestedObjects,
],
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {expect, test} from '@playwright/experimental-ct-react'
import {type SanityDocument} from '@sanity/types'

import {TreeEditingStory} from './TreeEditingStory'

const ANIMATION_DURATION = 600

const DOCUMENT_VALUE: SanityDocument = {
_type: 'test',
_createdAt: '',
_updatedAt: '',
_id: '123',
_rev: '123',
arrayWithNestedObjectsWithArray: [
{
_type: 'firstObject',
_key: 'firstObject1',
secondObject: {
_type: 'secondObject',
nestedArray: [
{
_type: 'nestedObject',
_key: 'nestedObject1',
nestedString: 'firstObject1.1 > secondObject > nestedArray > nestedObject1',
},
{
_type: 'nestedObject',
_key: 'nestedObject2',
nestedString: 'firstObject1.2 > secondObject > nestedArray > nestedObject2',
},
],
},
},
{
_type: 'firstObject',
_key: 'firstObject2',
secondObject: {
_type: 'secondObject',
nestedArray: [
{
_type: 'nestedObject',
_key: 'nestedObject1',
nestedString: 'firstObject2.1 > secondObject > nestedArray > nestedObject1',
},
{
_type: 'nestedObject',
_key: 'nestedObject2',
nestedString: 'firstObject2.2 > secondObject > nestedArray > nestedObject2',
},
],
},
},
],
}

test.describe('Tree Editing with nested objects', () => {
test('should navigate and display nested objects correctly', async ({mount, page}) => {
// Mount the TreeEditingStory component with initial open path
await mount(
<TreeEditingStory
value={DOCUMENT_VALUE}
openPath={['arrayWithNestedObjectsWithArray', {_key: 'firstObject1'}]}
/>,
)

const dialog = page.getByTestId('tree-editing-dialog')

// Verify the nested array field is visible
const nestedArrayField1 = dialog.getByTestId(
'field-arrayWithNestedObjectsWithArray[_key=="firstObject1"].secondObject.nestedArray',
)
await expect(nestedArrayField1).toBeVisible()

// Open the sidebar
const sidebarToggleButton = dialog.getByTestId('tree-editing-sidebar-toggle')
await sidebarToggleButton.click()

await page.waitForTimeout(ANIMATION_DURATION)

const sidebar = dialog.getByTestId('tree-editing-sidebar')

// Expand the first root object
const firstObjectExpandButton = sidebar.getByTestId(
'tree-editing-menu-expand-button-arrayWithNestedObjectsWithArray[_key=="firstObject1"]',
)
await firstObjectExpandButton.click()

// Expand the nested array
const nestedArrayExpandButton1 = sidebar.getByTestId(
'tree-editing-menu-expand-button-arrayWithNestedObjectsWithArray[_key=="firstObject1"].secondObject.nestedArray',
)
await nestedArrayExpandButton1.click()

// Get the navigation buttons for nested objects
const nestedObjectNavigateButton1 = sidebar.getByTestId(
'tree-editing-menu-navigate-button-arrayWithNestedObjectsWithArray[_key=="firstObject1"].secondObject.nestedArray[_key=="nestedObject1"]',
)
const nestedObjectNavigateButton2 = sidebar.getByTestId(
'tree-editing-menu-navigate-button-arrayWithNestedObjectsWithArray[_key=="firstObject1"].secondObject.nestedArray[_key=="nestedObject2"]',
)

// Verify the nested objects buttons are visible
await expect(nestedObjectNavigateButton1).toBeVisible()
await expect(nestedObjectNavigateButton2).toBeVisible()

// Navigate to the first nested object and verify the the form is displayed
await nestedObjectNavigateButton1.click()
await page.waitForTimeout(ANIMATION_DURATION)
const stringInput = dialog.getByTestId('string-input')
await expect(stringInput).toHaveValue(
'firstObject1.1 > secondObject > nestedArray > nestedObject1',
)

// Navigate to the second nested object and verify the the form is displayed
await nestedObjectNavigateButton2.click()
await page.waitForTimeout(ANIMATION_DURATION)
await expect(stringInput).toHaveValue(
'firstObject1.2 > secondObject > nestedArray > nestedObject2',
)

// Navigate to the second root object and verify the nested array field is visible
const secondRootObjectNavigateButton = sidebar.getByTestId(
'tree-editing-menu-navigate-button-arrayWithNestedObjectsWithArray[_key=="firstObject2"]',
)
await secondRootObjectNavigateButton.click()
await page.waitForTimeout(ANIMATION_DURATION)
const nestedArrayField2 = dialog.getByTestId(
'field-arrayWithNestedObjectsWithArray[_key=="firstObject2"].secondObject.nestedArray',
)
await expect(nestedArrayField2).toBeVisible()
})
})
Loading

0 comments on commit 3c057a8

Please sign in to comment.