diff --git a/dev/test-studio/preview/FieldGroups.tsx b/dev/test-studio/preview/FieldGroups.tsx new file mode 100644 index 000000000000..1a2a73ee8355 --- /dev/null +++ b/dev/test-studio/preview/FieldGroups.tsx @@ -0,0 +1,50 @@ +import {Box, Card, Stack, Text} from '@sanity/ui' + +import {useQuery} from './loader' + +export function FieldGroups(): JSX.Element { + const {data, loading, error} = useQuery< + { + _id: string + field1: string | null + field2: string | null + nested: { + field3: string | null + field4: string | null + field5: string | null + } | null + }[] + >( + /* groq */ `*[_type == "fieldGroupsWithFieldsetsHidden"]{_id,field1,field2,nested{field3,field4,field5}}`, + ) + + if (error) { + throw error + } + + if (loading) { + return

Loading...

+ } + + return ( + + {data?.map((item) => { + return ( + + + {item.field1 || 'Not Set'} + {item.field2 || 'Not Set'} + {item.nested && ( + + {item.nested.field3 || 'Not Set'} + {item.nested.field4 || 'Not Set'} + {item.nested.field5 || 'Not Set'} + + )} + + + ) + })} + + ) +} diff --git a/dev/test-studio/preview/main.tsx b/dev/test-studio/preview/main.tsx index 2d8b6eac32ef..7fb32fa58a77 100644 --- a/dev/test-studio/preview/main.tsx +++ b/dev/test-studio/preview/main.tsx @@ -1,14 +1,51 @@ +import {Box, Flex, studioTheme, Tab, TabList, TabPanel, ThemeProvider} from '@sanity/ui' import {enableVisualEditing} from '@sanity/visual-editing' -import {Suspense, useEffect} from 'react' +import {Suspense, useEffect, useState} from 'react' import {createRoot} from 'react-dom/client' +import {FieldGroups} from './FieldGroups' import {useLiveMode} from './loader' import {SimpleBlockPortableText} from './SimpleBlockPortableText' function Main() { + const [id, setId] = useState('simple') return ( <> - + + + + + setId('simple')} + selected={id === 'simple'} + /> + setId('nested')} + selected={id === 'nested'} + /> + + + + {id === 'simple' && ( + + + + )} + + {id === 'nested' && ( + + + + )} + + + diff --git a/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js b/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js new file mode 100644 index 000000000000..2e63fd511f49 --- /dev/null +++ b/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js @@ -0,0 +1,59 @@ +const group = { + name: 'group', + title: 'Group', + default: true, +} +const group2 = { + name: 'group2', + title: 'Group 2', +} +const fieldset = { + name: 'fieldset', + title: 'Fieldset', + options: {collapsed: true}, +} + +export default { + name: 'fieldGroupsWithFieldsetsHidden', + title: 'With default groups and collapsed fieldsets', + type: 'document', + groups: [group, group2], + fieldsets: [fieldset], + fields: [ + { + name: 'field1', + type: 'string', + }, + { + name: 'field2', + type: 'string', + group: group.name, + fieldset: fieldset.name, + }, + { + name: 'nested', + type: 'object', + group: group.name, + fieldset: fieldset.name, + groups: [group, group2], + fieldsets: [fieldset], + fields: [ + { + name: 'field3', + type: 'string', + fieldset: fieldset.name, + }, + { + name: 'field4', + type: 'string', + group: group.name, + }, + { + name: 'field5', + type: 'string', + group: group2.name, + }, + ], + }, + ], +} diff --git a/dev/test-studio/schema/index.ts b/dev/test-studio/schema/index.ts index 51b229532b6b..b579539513f1 100644 --- a/dev/test-studio/schema/index.ts +++ b/dev/test-studio/schema/index.ts @@ -32,6 +32,7 @@ import fieldGroupsDefault from './debug/fieldGroupsDefault' import fieldGroupsMany from './debug/fieldGroupsMany' import fieldGroupsWithFieldsets from './debug/fieldGroupsWithFieldsets' import fieldGroupsWithFieldsetsAndValidation from './debug/fieldGroupsWithFieldsetsAndValidation' +import fieldGroupsWithFieldsetsHidden from './debug/fieldGroupsWithFieldsetsHidden' import fieldGroupsWithI18n from './debug/fieldGroupsWithI18n' import fieldGroupsWithValidation from './debug/fieldGroupsWithValidation' import fieldsets from './debug/fieldsets' @@ -252,6 +253,7 @@ export const schemaTypes = [ fieldGroupsWithI18n, fieldGroupsWithValidation, fieldGroupsWithFieldsetsAndValidation, + fieldGroupsWithFieldsetsHidden, virtualizationInObject, virtualizationDebug, diff --git a/dev/test-studio/structure/constants.ts b/dev/test-studio/structure/constants.ts index fbbc480ed0d0..ffcdea6447a4 100644 --- a/dev/test-studio/structure/constants.ts +++ b/dev/test-studio/structure/constants.ts @@ -98,6 +98,7 @@ export const DEBUG_FIELD_GROUP_TYPES = [ 'fieldGroupsWithValidation', 'fieldGroupsWithFieldsets', 'fieldGroupsWithFieldsetsAndValidation', + 'fieldGroupsWithFieldsetsHidden', ] export const EXTERNAL_PLUGIN_INPUT_TYPES = ['markdownTest', 'muxVideoPost'] diff --git a/packages/sanity/src/core/form/store/useFormState.ts b/packages/sanity/src/core/form/store/useFormState.ts index 9d997e0cd245..71c967a9f754 100644 --- a/packages/sanity/src/core/form/store/useFormState.ts +++ b/packages/sanity/src/core/form/store/useFormState.ts @@ -7,7 +7,7 @@ import {useLayoutEffect, useMemo, useRef} from 'react' import {type FormNodePresence} from '../../presence' import {useCurrentUser} from '../../store' import {type FIXME_SanityDocument, prepareFormState} from './formState' -import {type ObjectFormNode, type StateTree} from './types' +import {type ObjectFormNode, type ObjectMember, type StateTree} from './types' import {type DocumentFormNode} from './types/nodes' import {immutableReconcile} from './utils/immutableReconcile' @@ -77,7 +77,7 @@ export function useFormState< presence, validation, changesOpen, - }) as ObjectFormNode // TODO: remove type cast + }) as ObjectFormNode & {_allMembers: ObjectMember[]} // TODO: remove type cast const reconciled = immutableReconcile(prev.current, next) prev.current = reconciled diff --git a/packages/sanity/src/core/form/store/utils/getExpandOperations.ts b/packages/sanity/src/core/form/store/utils/getExpandOperations.ts index be285de9c1c3..79acae7bc30d 100644 --- a/packages/sanity/src/core/form/store/utils/getExpandOperations.ts +++ b/packages/sanity/src/core/form/store/utils/getExpandOperations.ts @@ -107,19 +107,21 @@ function getObjectFieldsetAndFieldGroupOperations( // Group handling const schemaField = node.schemaType.fields.find((field) => field.name === fieldName) const selectedGroupName = node.groups.find((group) => group.selected)?.name - const defaultGroupName = (node.schemaType.groups || []).find((group) => group.default)?.name + const schemaFieldGroup = (schemaField && castArray(schemaField.group)) || [] const inSelectedGroup = selectedGroupName && - (selectedGroupName === ALL_FIELDS_GROUP.name || - (schemaField && castArray(schemaField.group).includes(selectedGroupName))) + (selectedGroupName === ALL_FIELDS_GROUP.name || schemaFieldGroup.includes(selectedGroupName)) const ops: (ExpandFieldSetOperation | SetActiveGroupOperation)[] = [] if (!inSelectedGroup) { + const groupName = + node.groups.find((group) => schemaFieldGroup.includes(group.name))?.name || + ALL_FIELDS_GROUP.name ops.push({ type: 'setSelectedGroup', path: node.path, - groupName: defaultGroupName || ALL_FIELDS_GROUP.name, + groupName, }) } diff --git a/packages/sanity/src/core/form/store/utils/immutableReconcile.ts b/packages/sanity/src/core/form/store/utils/immutableReconcile.ts index 095c1a84dbc8..8e8da4d12f19 100644 --- a/packages/sanity/src/core/form/store/utils/immutableReconcile.ts +++ b/packages/sanity/src/core/form/store/utils/immutableReconcile.ts @@ -54,12 +54,14 @@ function _immutableReconcile( assertType>(previous) assertType>(next) - const nextKeys = Object.keys(next) - let allEqual = Object.keys(previous).length === nextKeys.length + const nextKeys = Object.getOwnPropertyNames(next) + let allEqual = Object.getOwnPropertyNames(previous).length === nextKeys.length const result: Record = {} parents.set(next, result) for (const key of nextKeys) { - const nextValue = _immutableReconcile(previous[key], next[key]!, parents) + const nextValue = next.propertyIsEnumerable(key) + ? _immutableReconcile(previous[key], next[key]!, parents) + : next[key] if (nextValue !== previous[key]) { allEqual = false }