Skip to content

Commit

Permalink
fix: adds support for document types named using _id incompatible cha…
Browse files Browse the repository at this point in the history
…racters
  • Loading branch information
snorrees committed Aug 13, 2024
1 parent 9125461 commit 6d5ee68
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 211 deletions.
366 changes: 183 additions & 183 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 3 additions & 12 deletions plugin/src/assistDocument/components/AssistDocumentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Card, Stack, Text} from '@sanity/ui'
import {createContext, useContext, useEffect, useMemo, useRef} from 'react'
import {useContext, useEffect, useMemo, useRef} from 'react'
import {
FormCallbacksProvider,
FormCallbacksValue,
Expand All @@ -21,7 +21,6 @@ import {

import {useAiPaneRouter} from '../../assistInspector/helpers'
import {useAiAssistanceConfig} from '../../assistLayout/AiAssistanceConfigContext'
import {documentTypeFromAiDocumentId} from '../../helpers/ids'
import {
AssistDocument,
AssistField,
Expand All @@ -32,13 +31,12 @@ import {
instructionParam,
StudioInstruction,
} from '../../types'
import {AssistTypeContext} from './AssistTypeContext'
import {BackToInstructionListLink} from './instruction/BackToInstructionsLink'
import {SelectedFieldContextProvider, SelectedFieldContextValue} from './SelectedFieldContext'

const EMPTY_FIELDS: AssistField[] = []

export const TypePathContext = createContext<string | undefined>(undefined)

export function AssistDocumentForm(props: ObjectInputProps) {
if (props.readOnly) {
return (
Expand All @@ -55,16 +53,9 @@ function AssistDocumentFormEditable(props: ObjectInputProps) {
const id = value?._id
const fields = value?.fields

const targetDocumentType = useMemo(() => {
if (!id) {
return undefined
}
return documentTypeFromAiDocumentId(id)
}, [id])

const {params, setParams} = useAiPaneRouter()
const pathKey = params[fieldPathParam]
const typePath = useContext(TypePathContext)
const {typePath, documentType: targetDocumentType} = useContext(AssistTypeContext)
const instruction = params[instructionParam]

const activeKey = useMemo(() => {
Expand Down
7 changes: 7 additions & 0 deletions plugin/src/assistDocument/components/AssistTypeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {createContext} from 'react'

export interface AssistTypeContextValue {
typePath?: string
documentType?: string
}
export const AssistTypeContext = createContext<AssistTypeContextValue>({})
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import {set, StringInputProps} from 'sanity'

import {FieldAutocomplete} from '../../../assistInspector/FieldAutocomplete'
import {FieldRef} from '../../../assistInspector/helpers'
import {TypePathContext} from '../AssistDocumentForm'
import {SelectedFieldContext} from '../SelectedFieldContext'
import {AssistTypeContext} from '../AssistTypeContext'

export function FieldRefPathInput(props: StringInputProps) {
const documentSchema = useContext(SelectedFieldContext)?.documentSchema
const typePath = useContext(TypePathContext)
const {typePath} = useContext(AssistTypeContext)
const ref = useRef<HTMLDivElement>(null)
const id = useId()
const {onChange} = props
Expand Down
8 changes: 5 additions & 3 deletions plugin/src/assistInspector/AssistInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import {styled} from 'styled-components'

import {DocumentForm} from '../_lib/form'
import {TypePathContext} from '../assistDocument/components/AssistDocumentForm'
import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
import {
getAssistableDocId,
Expand Down Expand Up @@ -290,6 +290,8 @@ export function AssistInspector(props: DocumentInspectorProps) {
return <div {..._props} style={{height: '100%', flex: 1, overflow: 'auto'}} />
}, [])

const assistTypeContext = useMemo(() => ({typePath, documentType}), [typePath, documentType])

if (!documentId || !schemaType || schemaType.jsonType !== 'object') {
return (
<Card flex={1} padding={4}>
Expand Down Expand Up @@ -319,7 +321,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
<PresenceOverlay>
<Box padding={4}>
{selectedField && (
<TypePathContext.Provider value={typePath}>
<AssistTypeContext.Provider value={assistTypeContext}>
<VirtualizerScrollInstanceProvider
scrollElement={boundary.current}
containerElement={boundary}
Expand All @@ -333,7 +335,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
<DocumentForm />
</DocumentPaneProvider>
</VirtualizerScrollInstanceProvider>
</TypePathContext.Provider>
</AssistTypeContext.Provider>
)}
</Box>
</PresenceOverlay>
Expand Down
3 changes: 2 additions & 1 deletion plugin/src/assistInspector/InstructionTaskHistoryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
const instruction = instructions?.find((i) => i._key === task.instructionKey)
return {
...task,
title: showTitles ? task.title ?? getInstructionTitle(instruction) : undefined,
title: showTitles ? (task.title ?? getInstructionTitle(instruction)) : undefined,
cancel: () => cancelRun(task._key),
}
}) ?? []
Expand Down Expand Up @@ -187,6 +187,7 @@ const TaskStatusButton = forwardRef(function TaskStatusButton(
return (
<StatusButton
label={`${pluginTitle} status`}
aria-label={`${pluginTitle} status`}
icon={isRunning ? SyncSpinningIcon : hasErrors ? ErrorOutlineIcon : CheckmarkCircleIcon}
mode="bleed"
onClick={onClick}
Expand Down
17 changes: 17 additions & 0 deletions plugin/src/helpers/ids.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {describe, expect, test} from 'vitest'

import {assistDocumentId} from './ids'

describe('ids', () => {
test('assistDocumentId should replace illegal id chars with _', () => {
const testCases = [
{schemaType: 'test', assistId: 'sanity.assist.schemaType.test'},
{schemaType: 'test-type', assistId: 'sanity.assist.schemaType.test-type'},
{schemaType: 'test/type', assistId: 'sanity.assist.schemaType.test_type'},
{schemaType: '%broken©™£€∞', assistId: 'sanity.assist.schemaType._broken_____'},
]
const outputs = testCases.map((testCase) => assistDocumentId(testCase.schemaType))
const expected = testCases.map((testCase) => testCase.assistId)
expect(outputs).toEqual(expected)
})
})
8 changes: 2 additions & 6 deletions plugin/src/helpers/ids.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import {assistDocumentIdPrefix, assistDocumentStatusIdPrefix} from '../types'

const aiDocPrefixPattern = new RegExp(`^${assistDocumentIdPrefix}`)
const illegalIdChars = /[^a-zA-Z0-9._-]/g

export function publicId(id: string) {
return id.replace('drafts.', '')
}

export function assistDocumentId(documentType: string) {
return `${assistDocumentIdPrefix}${documentType}`
}

export function documentTypeFromAiDocumentId(id: string) {
return id.replace(aiDocPrefixPattern, '')
return `${assistDocumentIdPrefix}${documentType}`.replace(illegalIdChars, '_')
}

export function assistTasksStatusId(documentId: string) {
Expand Down
6 changes: 3 additions & 3 deletions studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
"@sanity/embeddings-index-ui": "^1.1.8",
"@sanity/icons": "^2.11.7",
"@sanity/language-filter": "^4.0.0",
"@sanity/ui": "^2.1.0",
"@sanity/vision": "^3.52.0",
"@sanity/ui": "^2.8.8",
"@sanity/vision": "^3.53.0",
"react": "^18.2.0",
"react-animate-height": "^3.2.3",
"react-dom": "^18.2.0",
"react-is": "^18.2.0",
"sanity": "^3.52.0",
"sanity": "^3.53.0",
"sanity-plugin-internationalized-array": "^2.0.0",
"sanity-plugin-media": "^2.2.5",
"styled-components": "^6.1.8"
Expand Down
28 changes: 27 additions & 1 deletion studio/sanity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {languageFilter} from '@sanity/language-filter'
import {internationalizedArray} from 'sanity-plugin-internationalized-array'
import {featureProduct, languageArticle} from './schemas/languageArticle'
import {mockArticle} from './schemas/mockArticle'
import {brokenTypeName} from './schemas/brokenTypeName'
import {CloseIcon} from '@sanity/icons'

export default defineConfig({
name: 'default',
Expand All @@ -23,7 +25,31 @@ export default defineConfig({
apiHost,

plugins: [
structureTool(),
structureTool({
structure: (S) => {
return S.list({
id: 'root',
title: 'Document types',
items: S.documentTypeListItems().map((item) => {
// some Studios use type names that will otherwise crash the structure tool, by assigning a custom id to them (without illegal chars)
// we include one such type here, for testing
if (item.getId() === brokenTypeName.name) {
return S.listItem({
id: 'fixed-type',
icon: CloseIcon,
title: 'Renamed type name',
//@ts-expect-error this works but gives errors, broken typings?
child: S.documentTypeList({
schemaType: brokenTypeName.name,
id: 'broken_type',
}),
})
}
return item
}),
})
},
}),
visionTool(),
codeInput(),
assist({
Expand Down
1 change: 1 addition & 0 deletions studio/schemas/allSchemas.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * as mockArticleTypes from './mockArticle'
export * as languageArticle from './languageArticle'
export * as brokenTypeName from './brokenTypeName'
12 changes: 12 additions & 0 deletions studio/schemas/brokenTypeName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {defineType} from 'sanity'

export const brokenTypeName = defineType({
type: 'document',
name: 'broken/type%broken©™£€∞' /* this document type name will crash standard studio structures*/,
fields: [
{
type: 'string',
name: 'title',
},
],
})

0 comments on commit 6d5ee68

Please sign in to comment.