UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

107 lines (87 loc) 3.03 kB
import { type ArraySchemaType, isArrayOfObjectsSchemaType, type ObjectSchemaType, type Path, } from '@sanity/types' import {toString} from '@sanity/util/paths' import {getValueAtPath} from '../../../../../field/paths/helpers' import {getSchemaTypeTitle} from '../../../../../schema/helpers' import {type TreeEditingBreadcrumb, type TreeEditingMenuItem} from '../../types' import {getRootPath} from '../getRootPath' import {getSchemaField} from '../getSchemaField' import {buildArrayState} from './buildArrayState' const EMPTY_ARRAY: [] = [] export const EMPTY_TREE_STATE: TreeEditingState = { breadcrumbs: EMPTY_ARRAY, menuItems: EMPTY_ARRAY, relativePath: EMPTY_ARRAY, rootTitle: '', } export interface BuildTreeEditingStateProps { schemaType: ObjectSchemaType | ArraySchemaType documentValue: unknown openPath: Path } export interface TreeEditingState { /** The breadcrumbs for the tree editing state */ breadcrumbs: TreeEditingBreadcrumb[] /** The menu items for the tree editing state */ menuItems: TreeEditingMenuItem[] /** * The relative path to the selected item in the tree editing state. * It is used to determine which field to show in the form editor. */ relativePath: Path /** The title of the root field */ rootTitle: string } export interface RecursiveProps extends Omit<BuildTreeEditingStateProps, 'openPath'> { path: Path } export function buildTreeEditingState(props: BuildTreeEditingStateProps): TreeEditingState { const {openPath} = props const rootPath = getRootPath(openPath) const rootField = getSchemaField(props.schemaType, toString(rootPath)) as ObjectSchemaType const rootTitle = getSchemaTypeTitle(rootField?.type as ObjectSchemaType) if (!isArrayOfObjectsSchemaType(rootField?.type)) { return EMPTY_TREE_STATE } if (rootField?.options?.treeEditing === false) { return EMPTY_TREE_STATE } let relativePath: Path = [] const breadcrumbs: TreeEditingBreadcrumb[] = [] const result = recursive({ schemaType: rootField, documentValue: props.documentValue, path: rootPath, }) function recursive(recursiveProps: RecursiveProps): TreeEditingState { const {schemaType, path, documentValue} = recursiveProps const value = getValueAtPath(documentValue, path) as Array<Record<string, unknown>> const arrayValue = Array.isArray(value) ? value : EMPTY_ARRAY const arraySchemaType = schemaType?.type as ArraySchemaType const arrayState = buildArrayState({ arraySchemaType, arrayValue, documentValue, openPath, // Pass the recursive function to the buildArrayState function // to allow for recursive calls in the array items. recursive, rootPath: path, }) if (arrayState.relativePath.length > 0) { relativePath = arrayState.relativePath } breadcrumbs.unshift(...arrayState.breadcrumbs) return arrayState } return { relativePath, breadcrumbs, menuItems: result.menuItems, rootTitle, } }