@sanity/assist 3.0.9 → 3.1.1
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/index.esm.js +369 -488
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +368 -487
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -488
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
- package/src/assistDocument/AssistDocumentContext.tsx +3 -1
- package/src/assistDocument/AssistDocumentContextProvider.tsx +3 -4
- package/src/assistDocument/AssistDocumentInput.tsx +1 -7
- package/src/assistDocument/AssistDocumentLayout.tsx +12 -0
- package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -6
- package/src/assistDocument/components/FieldRefPreview.tsx +2 -4
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +40 -17
- package/src/assistInspector/AssistInspector.tsx +15 -12
- package/src/components/ImageContext.tsx +15 -8
- package/src/fieldActions/assistFieldActions.tsx +12 -21
- package/src/fieldActions/generateCaptionActions.tsx +11 -4
- package/src/fieldActions/generateImageActions.tsx +3 -3
- package/src/helpers/ids.test.ts +12 -1
- package/src/helpers/ids.ts +9 -1
- package/src/plugin.tsx +5 -1
- package/src/presence/AssistDocumentPresence.tsx +5 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/assist",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "You create the instructions; Sanity AI Assist does the rest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"main": "./dist/index.js",
|
|
31
31
|
"module": "./dist/index.esm.js",
|
|
32
|
-
"source": "./src/index.ts",
|
|
33
32
|
"types": "./dist/index.d.ts",
|
|
34
33
|
"files": [
|
|
35
34
|
"dist",
|
|
@@ -82,10 +81,10 @@
|
|
|
82
81
|
"react": "^18.2.0",
|
|
83
82
|
"react-dom": "^18.2.0",
|
|
84
83
|
"rimraf": "^5.0.5",
|
|
85
|
-
"sanity": "^3.
|
|
84
|
+
"sanity": "^3.74.1",
|
|
86
85
|
"semantic-release": "^23.0.8",
|
|
87
86
|
"styled-components": "^6.1.8",
|
|
88
|
-
"typescript": "5.
|
|
87
|
+
"typescript": "^5.7.2",
|
|
89
88
|
"vitest": "^1.4.0"
|
|
90
89
|
},
|
|
91
90
|
"peerDependencies": {
|
|
@@ -8,9 +8,11 @@ export type AssistDocumentContextValue = (
|
|
|
8
8
|
| {assistDocument: undefined; loading: true}
|
|
9
9
|
) & {
|
|
10
10
|
documentIsNew: boolean
|
|
11
|
+
/**
|
|
12
|
+
* This is the _actual_ id of the current document (ie the document loaded in the pane); it contains draft. versions. prefix ect depending on context
|
|
13
|
+
*/
|
|
11
14
|
assistableDocumentId: string
|
|
12
15
|
documentIsAssistable: boolean
|
|
13
|
-
documentId: string
|
|
14
16
|
documentSchemaType: ObjectSchemaType
|
|
15
17
|
openInspector: (inspectorName: string, paneParams?: Record<string, string>) => void
|
|
16
18
|
closeInspector: (inspectorName?: string) => void
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {PropsWithChildren} from 'react'
|
|
2
|
-
import {ObjectSchemaType} from 'sanity'
|
|
3
2
|
|
|
4
3
|
import {AssistDocumentContext} from './AssistDocumentContext'
|
|
5
4
|
import {useAssistDocumentContextValue} from './hooks/useAssistDocumentContextValue'
|
|
6
5
|
|
|
7
6
|
export interface AIDocumentInputProps {
|
|
8
7
|
documentId: string
|
|
9
|
-
|
|
8
|
+
documentType: string
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export function AssistDocumentContextProvider(props: PropsWithChildren<AIDocumentInputProps>) {
|
|
13
|
-
const {documentId,
|
|
14
|
-
const value = useAssistDocumentContextValue(documentId,
|
|
12
|
+
const {documentId, documentType} = props
|
|
13
|
+
const value = useAssistDocumentContextValue(documentId, documentType)
|
|
15
14
|
return (
|
|
16
15
|
<AssistDocumentContext.Provider value={value}>{props.children}</AssistDocumentContext.Provider>
|
|
17
16
|
)
|
|
@@ -9,7 +9,6 @@ import {usePathKey} from '../helpers/misc'
|
|
|
9
9
|
import {isType} from '../helpers/typeUtils'
|
|
10
10
|
import {FirstAssistedPathProvider} from '../onboarding/FirstAssistedPathProvider'
|
|
11
11
|
import {assistDocumentTypeName} from '../types'
|
|
12
|
-
import {AssistDocumentContextProvider} from './AssistDocumentContextProvider'
|
|
13
12
|
import {useInstructionToaster} from './hooks/useInstructionToaster'
|
|
14
13
|
|
|
15
14
|
export function AssistDocumentInputWrapper(props: InputProps) {
|
|
@@ -44,12 +43,7 @@ function AssistDocumentInput({documentId, ...props}: ObjectInputProps & {documen
|
|
|
44
43
|
|
|
45
44
|
return (
|
|
46
45
|
<FirstAssistedPathProvider members={props.members}>
|
|
47
|
-
|
|
48
|
-
{props.renderDefault({
|
|
49
|
-
...props,
|
|
50
|
-
schemaType,
|
|
51
|
-
})}
|
|
52
|
-
</AssistDocumentContextProvider>
|
|
46
|
+
{props.renderDefault({...props, schemaType})}
|
|
53
47
|
</FirstAssistedPathProvider>
|
|
54
48
|
)
|
|
55
49
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {DocumentLayoutProps} from 'sanity'
|
|
2
|
+
|
|
3
|
+
import {AssistDocumentContextProvider} from './AssistDocumentContextProvider'
|
|
4
|
+
|
|
5
|
+
export function AssistDocumentLayout(props: DocumentLayoutProps) {
|
|
6
|
+
const {documentId, documentType} = props
|
|
7
|
+
return (
|
|
8
|
+
<AssistDocumentContextProvider documentType={documentType} documentId={documentId}>
|
|
9
|
+
{props.renderDefault(props)}
|
|
10
|
+
</AssistDocumentContextProvider>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
@@ -2,7 +2,6 @@ import {useCallback, useEffect, useState} from 'react'
|
|
|
2
2
|
import {ObjectSchemaType, PatchEvent, SanityDocument, unset} from 'sanity'
|
|
3
3
|
|
|
4
4
|
import {useRunInstruction} from '../assistLayout/RunInstructionProvider'
|
|
5
|
-
import {publicId} from '../helpers/ids'
|
|
6
5
|
|
|
7
6
|
export interface DraftDelayedTaskArgs<T> {
|
|
8
7
|
documentOnChange: (event: PatchEvent) => void
|
|
@@ -19,11 +18,6 @@ export function isDocAssistable(
|
|
|
19
18
|
return !!(documentSchemaType.liveEdit ? published : draft)
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export function getAssistableDocId(documentSchemaType: ObjectSchemaType, documentId: string) {
|
|
23
|
-
const baseId = publicId(documentId)
|
|
24
|
-
return documentSchemaType.liveEdit ? baseId : `drafts.${baseId}`
|
|
25
|
-
}
|
|
26
|
-
|
|
27
21
|
export function useRequestRunInstruction(args: {
|
|
28
22
|
documentOnChange: (event: PatchEvent) => void
|
|
29
23
|
// indicates if the document is a draft or liveEditable currently
|
|
@@ -7,22 +7,20 @@ import {useSelectedField} from '../../assistInspector/helpers'
|
|
|
7
7
|
import {SelectedFieldContext} from './SelectedFieldContext'
|
|
8
8
|
|
|
9
9
|
export function FieldRefPreview(props: PreviewProps & {path?: string}) {
|
|
10
|
+
const {actions} = props
|
|
10
11
|
const documentSchema = useContext(SelectedFieldContext)?.documentSchema
|
|
11
12
|
const path = (useContext(InlineBlockValueContext) as {path?: string})?.path ?? props.path
|
|
12
13
|
const selectedField = useSelectedField(documentSchema, path)
|
|
13
14
|
return (
|
|
14
15
|
<Flex gap={2} align="center" style={{width: '100%'}}>
|
|
15
16
|
<Flex flex={1} gap={2} align="center" paddingY={3} paddingX={1}>
|
|
16
|
-
{/*<Box>
|
|
17
|
-
<Text>{selectedField?.icon ? createElement(selectedField?.icon) : <CodeIcon />}</Text>
|
|
18
|
-
</Box>*/}
|
|
19
17
|
<Box>
|
|
20
18
|
<Text size={1} textOverflow="ellipsis">
|
|
21
19
|
{selectedField?.title ?? 'Select field'}
|
|
22
20
|
</Text>
|
|
23
21
|
</Box>
|
|
24
22
|
</Flex>
|
|
25
|
-
|
|
23
|
+
{actions as any}
|
|
26
24
|
</Flex>
|
|
27
25
|
)
|
|
28
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {useMemo} from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {getDraftId, getVersionId, type ObjectSchemaType, useSchema} from 'sanity'
|
|
3
3
|
import {useDocumentPane} from 'sanity/structure'
|
|
4
4
|
|
|
5
5
|
import {useAiPaneRouter} from '../../assistInspector/helpers'
|
|
@@ -8,31 +8,55 @@ import type {AssistDocumentContextValue} from '../AssistDocumentContext'
|
|
|
8
8
|
import {isDocAssistable} from '../RequestRunInstructionProvider'
|
|
9
9
|
import {useStudioAssistDocument} from './useStudioAssistDocument'
|
|
10
10
|
|
|
11
|
-
export function useAssistDocumentContextValue(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
11
|
+
export function useAssistDocumentContextValue(documentId: string, documentType: string) {
|
|
12
|
+
const schema = useSchema()
|
|
13
|
+
|
|
14
|
+
const documentSchemaType = useMemo(() => {
|
|
15
|
+
const schemaType = schema.get(documentType) as ObjectSchemaType | undefined
|
|
16
|
+
if (!schemaType) {
|
|
17
|
+
throw new Error(`Schema type "${documentType}" not found`)
|
|
18
|
+
}
|
|
19
|
+
return schemaType
|
|
20
|
+
}, [documentType, schema])
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
openInspector,
|
|
24
|
+
closeInspector,
|
|
25
|
+
inspector,
|
|
26
|
+
onChange: documentOnChange,
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
28
|
+
// @ts-ignore this is a valid option available in `corel` - Remove after corel is merged to next
|
|
29
|
+
selectedReleaseId,
|
|
30
|
+
editState,
|
|
31
|
+
} = useDocumentPane()
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
33
|
+
// @ts-ignore this is a valid option available in `corel` - Remove after corel is merged to next
|
|
34
|
+
const {draft, published, version} = editState || {}
|
|
35
|
+
|
|
36
|
+
let assistableDocumentId = version?._id || draft?._id || published?._id
|
|
37
|
+
if (!assistableDocumentId) {
|
|
38
|
+
assistableDocumentId = selectedReleaseId
|
|
39
|
+
? getVersionId(documentId, selectedReleaseId)
|
|
40
|
+
: documentSchemaType.liveEdit
|
|
41
|
+
? documentId
|
|
42
|
+
: getDraftId(documentId)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const documentIsNew = selectedReleaseId ? !version?._id : !draft?._id && !published?._id
|
|
46
|
+
const documentIsAssistable = selectedReleaseId
|
|
47
|
+
? !!version
|
|
48
|
+
: isDocAssistable(documentSchemaType, published, draft)
|
|
23
49
|
|
|
24
50
|
const {params} = useAiPaneRouter()
|
|
25
51
|
const selectedPath = params[fieldPathParam]
|
|
26
|
-
const {openInspector, closeInspector, inspector, onChange: documentOnChange} = useDocumentPane()
|
|
27
52
|
|
|
28
53
|
const assistDocument = useStudioAssistDocument({
|
|
29
|
-
documentId,
|
|
54
|
+
documentId: assistableDocumentId,
|
|
30
55
|
schemaType: documentSchemaType,
|
|
31
56
|
})
|
|
32
57
|
|
|
33
58
|
const value: AssistDocumentContextValue = useMemo(() => {
|
|
34
59
|
const base = {
|
|
35
|
-
documentId,
|
|
36
60
|
assistableDocumentId,
|
|
37
61
|
documentSchemaType,
|
|
38
62
|
documentIsNew,
|
|
@@ -54,7 +78,6 @@ export function useAssistDocumentContextValue(
|
|
|
54
78
|
}, [
|
|
55
79
|
assistDocument,
|
|
56
80
|
documentIsAssistable,
|
|
57
|
-
documentId,
|
|
58
81
|
assistableDocumentId,
|
|
59
82
|
documentSchemaType,
|
|
60
83
|
documentIsNew,
|
|
@@ -4,7 +4,6 @@ import {useCallback, useMemo, useRef} from 'react'
|
|
|
4
4
|
import {
|
|
5
5
|
type DocumentInspectorProps,
|
|
6
6
|
PresenceOverlay,
|
|
7
|
-
useEditState,
|
|
8
7
|
VirtualizerScrollInstanceProvider,
|
|
9
8
|
} from 'sanity'
|
|
10
9
|
import {
|
|
@@ -18,11 +17,7 @@ import {styled} from 'styled-components'
|
|
|
18
17
|
import {DocumentForm} from '../_lib/form'
|
|
19
18
|
import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
|
|
20
19
|
import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
|
|
21
|
-
import {
|
|
22
|
-
getAssistableDocId,
|
|
23
|
-
isDocAssistable,
|
|
24
|
-
useRequestRunInstruction,
|
|
25
|
-
} from '../assistDocument/RequestRunInstructionProvider'
|
|
20
|
+
import {useRequestRunInstruction} from '../assistDocument/RequestRunInstructionProvider'
|
|
26
21
|
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
27
22
|
import {giveFeedbackUrl, pluginTitle, releaseAnnouncementUrl, salesUrl} from '../constants'
|
|
28
23
|
import {getConditionalMembers} from '../helpers/conditionalMembers'
|
|
@@ -39,6 +34,7 @@ import {
|
|
|
39
34
|
useTypePath,
|
|
40
35
|
} from './helpers'
|
|
41
36
|
import {InstructionTaskHistoryButton} from './InstructionTaskHistoryButton'
|
|
37
|
+
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
42
38
|
|
|
43
39
|
const CardWithShadowBelow = styled(Card)`
|
|
44
40
|
position: relative;
|
|
@@ -209,15 +205,15 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
209
205
|
onChange: documentOnChange,
|
|
210
206
|
formState,
|
|
211
207
|
} = documentPane
|
|
212
|
-
|
|
208
|
+
|
|
209
|
+
const {assistableDocumentId, documentIsAssistable} = useAssistDocumentContext()
|
|
213
210
|
|
|
214
211
|
const formStateRef = useRef(formState)
|
|
215
212
|
formStateRef.current = formState
|
|
216
213
|
|
|
217
|
-
const assistableDocId = getAssistableDocId(schemaType, documentId)
|
|
218
214
|
const {instructionLoading, requestRunInstruction} = useRequestRunInstruction({
|
|
219
215
|
documentOnChange,
|
|
220
|
-
isDocAssistable:
|
|
216
|
+
isDocAssistable: documentIsAssistable,
|
|
221
217
|
})
|
|
222
218
|
|
|
223
219
|
const typePath = useTypePath(docValue, pathKey ?? '')
|
|
@@ -268,14 +264,14 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
268
264
|
pathKey &&
|
|
269
265
|
typePath &&
|
|
270
266
|
requestRunInstruction({
|
|
271
|
-
documentId:
|
|
267
|
+
documentId: assistableDocumentId,
|
|
272
268
|
path: pathKey,
|
|
273
269
|
typePath,
|
|
274
270
|
assistDocumentId: assistDocumentId(documentType),
|
|
275
271
|
instruction,
|
|
276
272
|
conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : [],
|
|
277
273
|
}),
|
|
278
|
-
[pathKey, instruction, typePath, documentType,
|
|
274
|
+
[pathKey, instruction, typePath, documentType, assistableDocumentId, requestRunInstruction],
|
|
279
275
|
)
|
|
280
276
|
|
|
281
277
|
const Region = useCallback((_props: any) => {
|
|
@@ -331,6 +327,13 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
331
327
|
index={documentPane.index}
|
|
332
328
|
itemId="ai"
|
|
333
329
|
pane={paneNode}
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
331
|
+
//@ts-ignore this is a valid option available in `corel` - Remove after corel is merged to next
|
|
332
|
+
forcedVersion={{
|
|
333
|
+
isReleaseLocked: false,
|
|
334
|
+
selectedPerspectiveName: 'published',
|
|
335
|
+
selectedReleaseId: undefined,
|
|
336
|
+
}}
|
|
334
337
|
>
|
|
335
338
|
<DocumentForm />
|
|
336
339
|
</DocumentPaneProvider>
|
|
@@ -373,7 +376,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
|
|
|
373
376
|
)}
|
|
374
377
|
|
|
375
378
|
<InstructionTaskHistoryButton
|
|
376
|
-
documentId={
|
|
379
|
+
documentId={assistableDocumentId}
|
|
377
380
|
tasks={tasks}
|
|
378
381
|
instructions={instructions}
|
|
379
382
|
showTitles={!instructionKey}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {createContext, useEffect, useMemo, useState} from 'react'
|
|
2
|
-
import {type InputProps, pathToString, useSyncState} from 'sanity'
|
|
3
|
-
import {usePaneRouter} from 'sanity/structure'
|
|
2
|
+
import {getPublishedId, type InputProps, pathToString, useSyncState} from 'sanity'
|
|
3
|
+
import {useDocumentPane, usePaneRouter} from 'sanity/structure'
|
|
4
4
|
|
|
5
5
|
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
6
6
|
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
7
|
-
import {publicId} from '../helpers/ids'
|
|
8
7
|
import {getDescriptionFieldOption, getImageInstructionFieldOption} from '../helpers/typeUtils'
|
|
9
8
|
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
10
9
|
|
|
@@ -19,14 +18,19 @@ export const ImageContext = createContext<ImageContextValue>({})
|
|
|
19
18
|
export function ImageContextProvider(props: InputProps) {
|
|
20
19
|
const {schemaType, path, value, readOnly} = props
|
|
21
20
|
const assetRef = (value as any)?.asset?._ref
|
|
21
|
+
const {selectedReleaseId} = useDocumentPane()
|
|
22
22
|
const [assetRefState, setAssetRefState] = useState<string | undefined>(assetRef)
|
|
23
23
|
|
|
24
|
-
const {
|
|
24
|
+
const {assistableDocumentId, documentSchemaType} = useAssistDocumentContext()
|
|
25
25
|
const {config, status} = useAiAssistanceConfig()
|
|
26
26
|
const apiClient = useApiClient(config?.__customApiClient)
|
|
27
27
|
const {generateCaption} = useGenerateCaption(apiClient)
|
|
28
28
|
|
|
29
|
-
const {isSyncing} = useSyncState(
|
|
29
|
+
const {isSyncing} = useSyncState(
|
|
30
|
+
getPublishedId(assistableDocumentId),
|
|
31
|
+
documentSchemaType.name,
|
|
32
|
+
selectedReleaseId,
|
|
33
|
+
)
|
|
30
34
|
|
|
31
35
|
const router = usePaneRouter()
|
|
32
36
|
const isShowingOlderRevision = !!router.params?.rev
|
|
@@ -35,7 +39,7 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
35
39
|
const descriptionField = getDescriptionFieldOption(schemaType)
|
|
36
40
|
if (
|
|
37
41
|
assetRef &&
|
|
38
|
-
|
|
42
|
+
assistableDocumentId &&
|
|
39
43
|
descriptionField &&
|
|
40
44
|
assetRef !== assetRefState &&
|
|
41
45
|
!isSyncing &&
|
|
@@ -44,7 +48,10 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
44
48
|
) {
|
|
45
49
|
setAssetRefState(assetRef)
|
|
46
50
|
if (canUseAssist(status)) {
|
|
47
|
-
generateCaption({
|
|
51
|
+
generateCaption({
|
|
52
|
+
path: pathToString([...path, descriptionField]),
|
|
53
|
+
documentId: assistableDocumentId,
|
|
54
|
+
})
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
}, [
|
|
@@ -52,7 +59,7 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
52
59
|
path,
|
|
53
60
|
assetRef,
|
|
54
61
|
assetRefState,
|
|
55
|
-
|
|
62
|
+
assistableDocumentId,
|
|
56
63
|
generateCaption,
|
|
57
64
|
isSyncing,
|
|
58
65
|
status,
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
type DocumentFieldAction,
|
|
5
5
|
type DocumentFieldActionGroup,
|
|
6
6
|
type DocumentFieldActionItem,
|
|
7
|
-
type ObjectSchemaType,
|
|
8
7
|
typed,
|
|
9
8
|
useCurrentUser,
|
|
10
9
|
} from 'sanity'
|
|
@@ -12,11 +11,7 @@ import {useDocumentPane} from 'sanity/structure'
|
|
|
12
11
|
|
|
13
12
|
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
14
13
|
import {getIcon} from '../assistDocument/components/instruction/appearance/IconInput'
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
getAssistableDocId,
|
|
18
|
-
useRequestRunInstruction,
|
|
19
|
-
} from '../assistDocument/RequestRunInstructionProvider'
|
|
14
|
+
import {useRequestRunInstruction} from '../assistDocument/RequestRunInstructionProvider'
|
|
20
15
|
import {aiInspectorId} from '../assistInspector/constants'
|
|
21
16
|
import {useSelectedField, useTypePath} from '../assistInspector/helpers'
|
|
22
17
|
import {pluginTitleShort} from '../constants'
|
|
@@ -39,8 +34,6 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
39
34
|
useAction(props) {
|
|
40
35
|
const {schemaType} = props
|
|
41
36
|
|
|
42
|
-
const isDocumentLevel = props.path.length === 0
|
|
43
|
-
|
|
44
37
|
const {
|
|
45
38
|
assistDocument,
|
|
46
39
|
documentIsNew,
|
|
@@ -50,17 +43,9 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
50
43
|
inspector,
|
|
51
44
|
documentOnChange,
|
|
52
45
|
documentSchemaType,
|
|
53
|
-
documentId,
|
|
54
46
|
selectedPath,
|
|
55
47
|
assistableDocumentId,
|
|
56
|
-
} =
|
|
57
|
-
// document field actions do not have access to the document context
|
|
58
|
-
// conditional hook _should_ be safe here since the logical path will be stable
|
|
59
|
-
isDocumentLevel
|
|
60
|
-
? // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
61
|
-
useAssistDocumentContextValue(props.documentId, schemaType as ObjectSchemaType)
|
|
62
|
-
: // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
63
|
-
useAssistDocumentContext()
|
|
48
|
+
} = useAssistDocumentContext()
|
|
64
49
|
|
|
65
50
|
const {value: docValue, formState} = useDocumentPane()
|
|
66
51
|
const formStateRef = useRef(formState)
|
|
@@ -72,7 +57,6 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
72
57
|
const typePath = useTypePath(docValue, pathKey)
|
|
73
58
|
const assistDocumentId = assistDocument?._id
|
|
74
59
|
|
|
75
|
-
const assistableDocId = getAssistableDocId(documentSchemaType, documentId)
|
|
76
60
|
const {requestRunInstruction} = useRequestRunInstruction({
|
|
77
61
|
documentOnChange,
|
|
78
62
|
isDocAssistable: documentIsAssistable ?? false,
|
|
@@ -121,11 +105,11 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
121
105
|
|
|
122
106
|
const onInstructionAction = useCallback(
|
|
123
107
|
(instruction: StudioInstruction) => {
|
|
124
|
-
if (!pathKey || !fieldAssistKey || !assistDocumentId || !
|
|
108
|
+
if (!pathKey || !fieldAssistKey || !assistDocumentId || !assistableDocumentId) {
|
|
125
109
|
return
|
|
126
110
|
}
|
|
127
111
|
requestRunInstruction({
|
|
128
|
-
documentId:
|
|
112
|
+
documentId: assistableDocumentId,
|
|
129
113
|
assistDocumentId,
|
|
130
114
|
path: pathKey,
|
|
131
115
|
typePath,
|
|
@@ -135,7 +119,14 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
135
119
|
: [],
|
|
136
120
|
})
|
|
137
121
|
},
|
|
138
|
-
[
|
|
122
|
+
[
|
|
123
|
+
requestRunInstruction,
|
|
124
|
+
assistableDocumentId,
|
|
125
|
+
pathKey,
|
|
126
|
+
typePath,
|
|
127
|
+
assistDocumentId,
|
|
128
|
+
fieldAssistKey,
|
|
129
|
+
],
|
|
139
130
|
)
|
|
140
131
|
|
|
141
132
|
const privateInstructions = useMemo(
|
|
@@ -30,7 +30,7 @@ export const generateCaptionsActions: DocumentFieldAction = {
|
|
|
30
30
|
if (imageContext && pathKey === imageContext?.imageDescriptionPath) {
|
|
31
31
|
//if this is true, it is stable, and not breaking rules of hooks
|
|
32
32
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
33
|
-
const {
|
|
33
|
+
const {assistableDocumentId} = useAssistDocumentContext()
|
|
34
34
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
35
35
|
return useMemo(() => {
|
|
36
36
|
return node({
|
|
@@ -54,14 +54,21 @@ export const generateCaptionsActions: DocumentFieldAction = {
|
|
|
54
54
|
})
|
|
55
55
|
return
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
generateCaption({path: pathKey, documentId: documentId ?? ''})
|
|
57
|
+
generateCaption({path: pathKey, documentId: assistableDocumentId})
|
|
59
58
|
},
|
|
60
59
|
renderAsButton: true,
|
|
61
60
|
disabled: loading,
|
|
62
61
|
hidden: !imageContext.assetRef,
|
|
63
62
|
})
|
|
64
|
-
}, [
|
|
63
|
+
}, [
|
|
64
|
+
generateCaption,
|
|
65
|
+
pathKey,
|
|
66
|
+
assistableDocumentId,
|
|
67
|
+
loading,
|
|
68
|
+
imageContext,
|
|
69
|
+
status,
|
|
70
|
+
openInspector,
|
|
71
|
+
])
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
// works but not supported by types
|
|
@@ -27,7 +27,7 @@ export const generateImagActions: DocumentFieldAction = {
|
|
|
27
27
|
if (imageContext && pathKey === imageContext?.imageInstructionPath) {
|
|
28
28
|
//if this is true, it is stable, and not breaking rules of hooks
|
|
29
29
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
30
|
-
const {
|
|
30
|
+
const {assistableDocumentId} = useAssistDocumentContext()
|
|
31
31
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
32
32
|
return useMemo(() => {
|
|
33
33
|
return node({
|
|
@@ -44,12 +44,12 @@ export const generateImagActions: DocumentFieldAction = {
|
|
|
44
44
|
if (loading) {
|
|
45
45
|
return
|
|
46
46
|
}
|
|
47
|
-
generateImage({path: pathKey, documentId:
|
|
47
|
+
generateImage({path: pathKey, documentId: assistableDocumentId})
|
|
48
48
|
},
|
|
49
49
|
renderAsButton: true,
|
|
50
50
|
disabled: loading,
|
|
51
51
|
})
|
|
52
|
-
}, [generateImage, pathKey,
|
|
52
|
+
}, [generateImage, pathKey, assistableDocumentId, loading])
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// works but not supported by types
|
package/src/helpers/ids.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {describe, expect, test} from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {assistDocumentId} from './ids'
|
|
3
|
+
import {assistDocumentId, assistTasksStatusId} from './ids'
|
|
4
4
|
|
|
5
5
|
describe('ids', () => {
|
|
6
6
|
test('assistDocumentId should replace illegal id chars with _', () => {
|
|
@@ -14,4 +14,15 @@ describe('ids', () => {
|
|
|
14
14
|
const expected = testCases.map((testCase) => testCase.assistId)
|
|
15
15
|
expect(outputs).toEqual(expected)
|
|
16
16
|
})
|
|
17
|
+
|
|
18
|
+
test.each([
|
|
19
|
+
{documentId: 'foo', assistId: 'sanity.assist.status.foo'},
|
|
20
|
+
{documentId: 'drafts.foo', assistId: 'sanity.assist.status.foo'},
|
|
21
|
+
{documentId: 'versions.r12332.foo', assistId: 'sanity.assist.status.r12332.foo'},
|
|
22
|
+
])(
|
|
23
|
+
"assistTasksStatusId should return the documentId with 'sanity.assist.status' prefix for $documentId",
|
|
24
|
+
({documentId, assistId}) => {
|
|
25
|
+
expect(assistTasksStatusId(documentId)).toEqual(assistId)
|
|
26
|
+
},
|
|
27
|
+
)
|
|
17
28
|
})
|
package/src/helpers/ids.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {getPublishedId, getVersionFromId, isVersionId} from 'sanity'
|
|
2
|
+
|
|
1
3
|
import {assistDocumentIdPrefix, assistDocumentStatusIdPrefix} from '../types'
|
|
2
4
|
|
|
3
5
|
const illegalIdChars = /[^a-zA-Z0-9._-]/g
|
|
@@ -11,5 +13,11 @@ export function assistDocumentId(documentType: string) {
|
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export function assistTasksStatusId(documentId: string) {
|
|
14
|
-
|
|
16
|
+
if (isVersionId(documentId)) {
|
|
17
|
+
// Creates an id: sanity.assist.status.<versionName>.<documentId>
|
|
18
|
+
return `${assistDocumentStatusIdPrefix}${getVersionFromId(documentId)}.${getPublishedId(documentId)}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Creates an id: sanity.assist.status<documentId>
|
|
22
|
+
return `${assistDocumentStatusIdPrefix}${getPublishedId(documentId)}`
|
|
15
23
|
}
|
package/src/plugin.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import {isImage} from './helpers/typeUtils'
|
|
|
17
17
|
import {ImageContextProvider} from './components/ImageContext'
|
|
18
18
|
import {TranslationConfig} from './translate/types'
|
|
19
19
|
import {assistDocumentTypeName, AssistPreset} from './types'
|
|
20
|
+
import {AssistDocumentLayout} from './assistDocument/AssistDocumentLayout'
|
|
20
21
|
|
|
21
22
|
export interface AssistPluginConfig {
|
|
22
23
|
translate?: TranslationConfig
|
|
@@ -69,10 +70,13 @@ export const assist = definePlugin<AssistPluginConfig | void>((config) => {
|
|
|
69
70
|
}
|
|
70
71
|
const docSchema = schema.get(schemaType)
|
|
71
72
|
if (docSchema && isObjectSchemaType(docSchema) && isSchemaAssistEnabled(docSchema)) {
|
|
72
|
-
return [...prev, createAssistDocumentPresence(documentId
|
|
73
|
+
return [...prev, createAssistDocumentPresence(documentId)]
|
|
73
74
|
}
|
|
74
75
|
return prev
|
|
75
76
|
},
|
|
77
|
+
components: {
|
|
78
|
+
unstable_layout: AssistDocumentLayout,
|
|
79
|
+
},
|
|
76
80
|
},
|
|
77
81
|
|
|
78
82
|
studio: {
|
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
import {Card, Flex} from '@sanity/ui'
|
|
2
2
|
import {useMemo} from 'react'
|
|
3
|
-
import {ObjectSchemaType} from 'sanity'
|
|
4
3
|
|
|
5
|
-
import {
|
|
4
|
+
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
6
5
|
import {documentRootKey, fieldPresenceTypeName} from '../types'
|
|
7
6
|
import {AiFieldPresence} from './AiFieldPresence'
|
|
8
7
|
import {aiPresence} from './useAssistPresence'
|
|
9
8
|
|
|
10
|
-
export function createAssistDocumentPresence(
|
|
11
|
-
documentId: string | undefined,
|
|
12
|
-
schemaType: ObjectSchemaType,
|
|
13
|
-
) {
|
|
9
|
+
export function createAssistDocumentPresence(documentId: string | undefined) {
|
|
14
10
|
return function AssistDocumentPresenceWrapper() {
|
|
15
|
-
return documentId ?
|
|
16
|
-
<AssistDocumentPresence documentId={documentId} schemaType={schemaType} />
|
|
17
|
-
) : null
|
|
11
|
+
return documentId ? <AssistDocumentPresence /> : null
|
|
18
12
|
}
|
|
19
13
|
}
|
|
20
14
|
|
|
21
|
-
function AssistDocumentPresence(
|
|
22
|
-
const {assistDocument} =
|
|
23
|
-
props.documentId,
|
|
24
|
-
props.schemaType as ObjectSchemaType,
|
|
25
|
-
)
|
|
15
|
+
function AssistDocumentPresence() {
|
|
16
|
+
const {assistDocument} = useAssistDocumentContext()
|
|
26
17
|
const anyPresence = useMemo(() => {
|
|
27
18
|
const anyPresence = assistDocument?.tasks
|
|
28
19
|
?.filter((run) => !run.ended && !run.reason)
|