Skip to content

Commit

Permalink
fix(sanity): open correct groups and fieldsets on setOpenPath
Browse files Browse the repository at this point in the history
  • Loading branch information
rdunk committed Jul 15, 2024
1 parent 97fed17 commit b19b14d
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 9 deletions.
62 changes: 62 additions & 0 deletions dev/test-studio/preview/FieldGroups.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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
nested: {
field6: string | null
field7: string | null
field8: string | null
} | null
} | null
}[]
>(
/* groq */ `*[_type == "fieldGroupsWithFieldsetsHidden"]{_id,field1,field2,nested{field3,field4,field5,nested{field6,field7,field8}}}`,
)

if (error) {
throw error
}

if (loading) {
return <p>Loading...</p>
}

return (
<Box paddingX={4}>
{data?.map((item) => {
return (
<Card key={item._id} padding={4}>
<Stack space={4}>
<Text weight={'bold'}>{item.field1 || 'N/A'}</Text>
<Text weight={'bold'}>{item.field2 || 'N/A'}</Text>
{item.nested && (
<Stack space={4} paddingLeft={2}>
<Text>{item.nested.field3 || 'N/A'}</Text>
<Text>{item.nested.field4 || 'N/A'}</Text>
<Text>{item.nested.field5 || 'N/A'}</Text>
{item.nested.nested && (
<Stack space={4} paddingLeft={2}>
<Text>{item.nested.nested.field6 || 'N/A'}</Text>
<Text>{item.nested.nested.field7 || 'N/A'}</Text>
<Text>{item.nested.nested.field8 || 'N/A'}</Text>
</Stack>
)}
</Stack>
)}
</Stack>
</Card>
)
})}
</Box>
)
}
41 changes: 39 additions & 2 deletions dev/test-studio/preview/main.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<SimpleBlockPortableText />
<ThemeProvider theme={studioTheme}>
<Flex direction={'column'}>
<Box padding={4}>
<TabList space={2}>
<Tab
aria-controls="simple-panel"
id="simple-tab"
label="SimpleBlockPortableText"
onClick={() => setId('simple')}
selected={id === 'simple'}
/>
<Tab
aria-controls="nested-panel"
id="nested-tab"
label="FieldGroups"
onClick={() => setId('nested')}
selected={id === 'nested'}
/>
</TabList>
</Box>

{id === 'simple' && (
<TabPanel aria-labelledby="simple-tab" id="simple-panel">
<SimpleBlockPortableText />
</TabPanel>
)}

{id === 'nested' && (
<TabPanel aria-labelledby="nested-tab" id="nested-panel">
<FieldGroups />
</TabPanel>
)}
</Flex>
</ThemeProvider>

<Suspense fallback={null}>
<VisualEditing />
</Suspense>
Expand Down
86 changes: 86 additions & 0 deletions dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
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,
fieldset: fieldset.name,
},
{
name: 'field5',
type: 'string',
group: group2.name,
},
{
name: 'nested',
type: 'object',
group: group.name,
fieldset: fieldset.name,
groups: [group, group2],
fieldsets: [fieldset],
fields: [
{
name: 'field6',
type: 'string',
fieldset: fieldset.name,
},
{
name: 'field7',
type: 'string',
group: group.name,
fieldset: fieldset.name,
},
{
name: 'field8',
type: 'string',
group: group2.name,
},
],
},
],
},
],
}
2 changes: 2 additions & 0 deletions dev/test-studio/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -252,6 +253,7 @@ export const schemaTypes = [
fieldGroupsWithI18n,
fieldGroupsWithValidation,
fieldGroupsWithFieldsetsAndValidation,
fieldGroupsWithFieldsetsHidden,
virtualizationInObject,
virtualizationDebug,

Expand Down
1 change: 1 addition & 0 deletions dev/test-studio/structure/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export const DEBUG_FIELD_GROUP_TYPES = [
'fieldGroupsWithValidation',
'fieldGroupsWithFieldsets',
'fieldGroupsWithFieldsetsAndValidation',
'fieldGroupsWithFieldsetsHidden',
]

export const EXTERNAL_PLUGIN_INPUT_TYPES = ['markdownTest', 'muxVideoPost']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,16 @@ test('returns new array when previous and next has different length', () => {

expect(immutableReconcile(lessItems, moreItems)).not.toBe(lessItems)
})

test('returns latest non-enumerable value', () => {
const prev = {enumerable: true}
const next = {enumerable: true}
Object.defineProperty(next, 'nonEnumerable', {
value: {foo: 'bar'},
enumerable: false,
})
// @ts-expect-error Object.defineProperty
expect(immutableReconcile(next, prev).nonEnumerable).toBeUndefined()
// @ts-expect-error Object.defineProperty
expect(immutableReconcile(prev, next).nonEnumerable).toBe(next.nonEnumerable)
})
10 changes: 6 additions & 4 deletions packages/sanity/src/core/form/store/utils/getExpandOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ function _immutableReconcile<T>(
assertType<Record<string, unknown>>(previous)
assertType<Record<string, unknown>>(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<string, unknown> = {}
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
}
Expand Down

0 comments on commit b19b14d

Please sign in to comment.