@sanity/assist 3.0.5 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +336 -342
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +334 -340
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +336 -342
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/assistDocument/components/AssistDocumentForm.tsx +3 -12
- package/src/assistDocument/components/AssistTypeContext.tsx +7 -0
- package/src/assistDocument/components/instruction/FieldRefInput.tsx +2 -2
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +1 -1
- package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +1 -1
- package/src/assistInspector/AssistInspector.tsx +5 -3
- package/src/assistInspector/InstructionTaskHistoryButton.tsx +2 -1
- package/src/helpers/conditionalMembers.test.ts +28 -0
- package/src/helpers/conditionalMembers.ts +1 -1
- package/src/helpers/ids.test.ts +17 -0
- package/src/helpers/ids.ts +2 -6
- package/src/schemas/assistDocumentSchema.tsx +1 -1
- package/src/schemas/serialize/serializeSchema.ts +2 -2
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {Card, Stack, Text} from '@sanity/ui'
|
|
2
|
-
import {
|
|
2
|
+
import {useContext, useEffect, useMemo, useRef} from 'react'
|
|
3
3
|
import {
|
|
4
4
|
FormCallbacksProvider,
|
|
5
5
|
FormCallbacksValue,
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
|
|
22
22
|
import {useAiPaneRouter} from '../../assistInspector/helpers'
|
|
23
23
|
import {useAiAssistanceConfig} from '../../assistLayout/AiAssistanceConfigContext'
|
|
24
|
-
import {documentTypeFromAiDocumentId} from '../../helpers/ids'
|
|
25
24
|
import {
|
|
26
25
|
AssistDocument,
|
|
27
26
|
AssistField,
|
|
@@ -32,13 +31,12 @@ import {
|
|
|
32
31
|
instructionParam,
|
|
33
32
|
StudioInstruction,
|
|
34
33
|
} from '../../types'
|
|
34
|
+
import {AssistTypeContext} from './AssistTypeContext'
|
|
35
35
|
import {BackToInstructionListLink} from './instruction/BackToInstructionsLink'
|
|
36
36
|
import {SelectedFieldContextProvider, SelectedFieldContextValue} from './SelectedFieldContext'
|
|
37
37
|
|
|
38
38
|
const EMPTY_FIELDS: AssistField[] = []
|
|
39
39
|
|
|
40
|
-
export const TypePathContext = createContext<string | undefined>(undefined)
|
|
41
|
-
|
|
42
40
|
export function AssistDocumentForm(props: ObjectInputProps) {
|
|
43
41
|
if (props.readOnly) {
|
|
44
42
|
return (
|
|
@@ -55,16 +53,9 @@ function AssistDocumentFormEditable(props: ObjectInputProps) {
|
|
|
55
53
|
const id = value?._id
|
|
56
54
|
const fields = value?.fields
|
|
57
55
|
|
|
58
|
-
const targetDocumentType = useMemo(() => {
|
|
59
|
-
if (!id) {
|
|
60
|
-
return undefined
|
|
61
|
-
}
|
|
62
|
-
return documentTypeFromAiDocumentId(id)
|
|
63
|
-
}, [id])
|
|
64
|
-
|
|
65
56
|
const {params, setParams} = useAiPaneRouter()
|
|
66
57
|
const pathKey = params[fieldPathParam]
|
|
67
|
-
const typePath = useContext(
|
|
58
|
+
const {typePath, documentType: targetDocumentType} = useContext(AssistTypeContext)
|
|
68
59
|
const instruction = params[instructionParam]
|
|
69
60
|
|
|
70
61
|
const activeKey = useMemo(() => {
|
|
@@ -4,12 +4,12 @@ import {set, StringInputProps} from 'sanity'
|
|
|
4
4
|
|
|
5
5
|
import {FieldAutocomplete} from '../../../assistInspector/FieldAutocomplete'
|
|
6
6
|
import {FieldRef} from '../../../assistInspector/helpers'
|
|
7
|
-
import {
|
|
7
|
+
import {AssistTypeContext} from '../AssistTypeContext'
|
|
8
8
|
import {SelectedFieldContext} from '../SelectedFieldContext'
|
|
9
9
|
|
|
10
10
|
export function FieldRefPathInput(props: StringInputProps) {
|
|
11
11
|
const documentSchema = useContext(SelectedFieldContext)?.documentSchema
|
|
12
|
-
const typePath = useContext(
|
|
12
|
+
const {typePath} = useContext(AssistTypeContext)
|
|
13
13
|
const ref = useRef<HTMLDivElement>(null)
|
|
14
14
|
const id = useId()
|
|
15
15
|
const {onChange} = props
|
|
@@ -168,7 +168,7 @@ function ArrayOutputInput({
|
|
|
168
168
|
<Flex key={itemType.name}>
|
|
169
169
|
<Selectable
|
|
170
170
|
value={itemType.name}
|
|
171
|
-
title={isType(itemType, 'block') ? 'Text' : itemType.title ?? itemType.name}
|
|
171
|
+
title={isType(itemType, 'block') ? 'Text' : (itemType.title ?? itemType.name)}
|
|
172
172
|
arrayValue={value as OutputTypeItem[] | undefined}
|
|
173
173
|
onChange={onSelectChange}
|
|
174
174
|
/>
|
|
@@ -8,7 +8,7 @@ export function InstructionVisibility(props: StringInputProps) {
|
|
|
8
8
|
const user = useCurrentUser()
|
|
9
9
|
|
|
10
10
|
const handleChange = useCallback(() => {
|
|
11
|
-
const newValue = value ? '' : user?.id ?? ''
|
|
11
|
+
const newValue = value ? '' : (user?.id ?? '')
|
|
12
12
|
onChange(newValue ? set(newValue) : unset())
|
|
13
13
|
}, [onChange, user, value])
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {styled} from 'styled-components'
|
|
17
17
|
|
|
18
18
|
import {DocumentForm} from '../_lib/form'
|
|
19
|
-
import {
|
|
19
|
+
import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
|
|
20
20
|
import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
|
|
21
21
|
import {
|
|
22
22
|
getAssistableDocId,
|
|
@@ -290,6 +290,8 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
290
290
|
return <div {..._props} style={{height: '100%', flex: 1, overflow: 'auto'}} />
|
|
291
291
|
}, [])
|
|
292
292
|
|
|
293
|
+
const assistTypeContext = useMemo(() => ({typePath, documentType}), [typePath, documentType])
|
|
294
|
+
|
|
293
295
|
if (!documentId || !schemaType || schemaType.jsonType !== 'object') {
|
|
294
296
|
return (
|
|
295
297
|
<Card flex={1} padding={4}>
|
|
@@ -319,7 +321,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
319
321
|
<PresenceOverlay>
|
|
320
322
|
<Box padding={4}>
|
|
321
323
|
{selectedField && (
|
|
322
|
-
<
|
|
324
|
+
<AssistTypeContext.Provider value={assistTypeContext}>
|
|
323
325
|
<VirtualizerScrollInstanceProvider
|
|
324
326
|
scrollElement={boundary.current}
|
|
325
327
|
containerElement={boundary}
|
|
@@ -333,7 +335,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
333
335
|
<DocumentForm />
|
|
334
336
|
</DocumentPaneProvider>
|
|
335
337
|
</VirtualizerScrollInstanceProvider>
|
|
336
|
-
</
|
|
338
|
+
</AssistTypeContext.Provider>
|
|
337
339
|
)}
|
|
338
340
|
</Box>
|
|
339
341
|
</PresenceOverlay>
|
|
@@ -112,7 +112,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
|
|
|
112
112
|
const instruction = instructions?.find((i) => i._key === task.instructionKey)
|
|
113
113
|
return {
|
|
114
114
|
...task,
|
|
115
|
-
title: showTitles ? task.title ?? getInstructionTitle(instruction) : undefined,
|
|
115
|
+
title: showTitles ? (task.title ?? getInstructionTitle(instruction)) : undefined,
|
|
116
116
|
cancel: () => cancelRun(task._key),
|
|
117
117
|
}
|
|
118
118
|
}) ?? []
|
|
@@ -187,6 +187,7 @@ const TaskStatusButton = forwardRef(function TaskStatusButton(
|
|
|
187
187
|
return (
|
|
188
188
|
<StatusButton
|
|
189
189
|
label={`${pluginTitle} status`}
|
|
190
|
+
aria-label={`${pluginTitle} status`}
|
|
190
191
|
icon={isRunning ? SyncSpinningIcon : hasErrors ? ErrorOutlineIcon : CheckmarkCircleIcon}
|
|
191
192
|
mode="bleed"
|
|
192
193
|
onClick={onClick}
|
|
@@ -59,6 +59,34 @@ describe('conditionalMembers', () => {
|
|
|
59
59
|
expect(conditionalMembers).toEqual([{path: 'title', hidden: false, readOnly: false}])
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
+
test('regression test: should include document path with conditional readonly and no hidden', () => {
|
|
63
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
64
|
+
name: 'test',
|
|
65
|
+
types: [
|
|
66
|
+
defineType({
|
|
67
|
+
type: 'document',
|
|
68
|
+
name: 'article',
|
|
69
|
+
readOnly: () => false,
|
|
70
|
+
fields: [{type: 'string', name: 'title'}],
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
}).get('article')
|
|
74
|
+
|
|
75
|
+
const docState = {
|
|
76
|
+
path: [],
|
|
77
|
+
schemaType: docSchema,
|
|
78
|
+
members: [
|
|
79
|
+
{
|
|
80
|
+
kind: 'field',
|
|
81
|
+
field: {path: [docSchema.fields[0].name], schemaType: docSchema.fields[0].type},
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
} as any
|
|
85
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
86
|
+
|
|
87
|
+
expect(conditionalMembers).toEqual([{path: '', hidden: false, readOnly: false}])
|
|
88
|
+
})
|
|
89
|
+
|
|
62
90
|
test('should include array item path with conditional readonly', () => {
|
|
63
91
|
const docSchema: ObjectSchemaType = Schema.compile({
|
|
64
92
|
name: 'test',
|
|
@@ -42,7 +42,7 @@ export function getConditionalMembers(docState: DocumentFormNode): ConditionalMe
|
|
|
42
42
|
path: '',
|
|
43
43
|
hidden: false,
|
|
44
44
|
readOnly: !!docState.readOnly,
|
|
45
|
-
conditional:
|
|
45
|
+
conditional: isConditional(docState.schemaType),
|
|
46
46
|
}
|
|
47
47
|
return (
|
|
48
48
|
[doc, ...extractConditionalPaths(docState, MAX_DEPTH)]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {describe, expect, test} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {assistDocumentId} from './ids'
|
|
4
|
+
|
|
5
|
+
describe('ids', () => {
|
|
6
|
+
test('assistDocumentId should replace illegal id chars with _', () => {
|
|
7
|
+
const testCases = [
|
|
8
|
+
{schemaType: 'test', assistId: 'sanity.assist.schemaType.test'},
|
|
9
|
+
{schemaType: 'test-type', assistId: 'sanity.assist.schemaType.test-type'},
|
|
10
|
+
{schemaType: 'test/type', assistId: 'sanity.assist.schemaType.test_type'},
|
|
11
|
+
{schemaType: '%broken©™£€∞', assistId: 'sanity.assist.schemaType._broken_____'},
|
|
12
|
+
]
|
|
13
|
+
const outputs = testCases.map((testCase) => assistDocumentId(testCase.schemaType))
|
|
14
|
+
const expected = testCases.map((testCase) => testCase.assistId)
|
|
15
|
+
expect(outputs).toEqual(expected)
|
|
16
|
+
})
|
|
17
|
+
})
|
package/src/helpers/ids.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import {assistDocumentIdPrefix, assistDocumentStatusIdPrefix} from '../types'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const illegalIdChars = /[^a-zA-Z0-9._-]/g
|
|
4
4
|
|
|
5
5
|
export function publicId(id: string) {
|
|
6
6
|
return id.replace('drafts.', '')
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function assistDocumentId(documentType: string) {
|
|
10
|
-
return `${assistDocumentIdPrefix}${documentType}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function documentTypeFromAiDocumentId(id: string) {
|
|
14
|
-
return id.replace(aiDocPrefixPattern, '')
|
|
10
|
+
return `${assistDocumentIdPrefix}${documentType}`.replace(illegalIdChars, '_')
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
export function assistTasksStatusId(documentId: string) {
|
|
@@ -170,7 +170,7 @@ export const promptContext = defineType({
|
|
|
170
170
|
},
|
|
171
171
|
prepare(select) {
|
|
172
172
|
return select.ref
|
|
173
|
-
? contextDocumentSchema?.preview?.prepare?.(select) ?? select
|
|
173
|
+
? (contextDocumentSchema?.preview?.prepare?.(select) ?? select)
|
|
174
174
|
: {title: 'No reference selected', media: contextDocumentSchema.icon}
|
|
175
175
|
},
|
|
176
176
|
},
|
|
@@ -89,7 +89,7 @@ function getBaseFields(
|
|
|
89
89
|
options: Object.keys(schemaOptions).length ? schemaOptions : undefined,
|
|
90
90
|
values: Array.isArray(type?.options?.list)
|
|
91
91
|
? type?.options?.list.map((v: string | {value: string; title: string}) =>
|
|
92
|
-
typeof v === 'string' ? v : v.value ?? `${v.title}
|
|
92
|
+
typeof v === 'string' ? v : (v.value ?? `${v.title}`),
|
|
93
93
|
)
|
|
94
94
|
: undefined,
|
|
95
95
|
of: 'of' in type && typeName === 'array' ? arrayOf(type, schema, options) : undefined,
|
|
@@ -156,7 +156,7 @@ function serializeMember(
|
|
|
156
156
|
options: Options | undefined,
|
|
157
157
|
): SerializedSchemaMember {
|
|
158
158
|
const typeNameExists = !!schema.get(type?.name)
|
|
159
|
-
const typeName = typeNameExists ? type.name : type.type?.name ?? ''
|
|
159
|
+
const typeName = typeNameExists ? type.name : (type.type?.name ?? '')
|
|
160
160
|
return removeUndef({
|
|
161
161
|
...(options?.leanFormat ? {} : {_type: assistSerializedFieldTypeName}),
|
|
162
162
|
name: name,
|