@sanity/assist 2.0.4-canary.0 → 2.0.5
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/README.md +233 -214
- package/dist/index.esm.js +1769 -1769
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1767 -1767
- package/dist/index.js.map +1 -1
- package/package.json +17 -18
- package/src/_lib/connector/ConnectFromRegion.tsx +4 -3
- package/src/_lib/connector/ConnectToRegion.tsx +1 -0
- package/src/_lib/connector/ConnectorRegion.tsx +2 -1
- package/src/_lib/connector/ConnectorsProvider.tsx +2 -1
- package/src/_lib/connector/ConnectorsStoreContext.ts +1 -0
- package/src/_lib/connector/index.ts +1 -1
- package/src/_lib/connector/mapConnectorToLine.ts +2 -2
- package/src/_lib/connector/useConnectorsStore.ts +2 -1
- package/src/_lib/connector/useRegionRects.ts +4 -3
- package/src/_lib/fixedListenQuery.ts +11 -11
- package/src/_lib/form/DocumentForm.tsx +4 -3
- package/src/_lib/form/helpers.ts +2 -1
- package/src/_lib/useListeningQuery.ts +4 -3
- package/src/assistConnectors/AssistConnectorsOverlay.tsx +1 -0
- package/src/assistConnectors/ConnectorPath.tsx +3 -2
- package/src/assistConnectors/draw/connectorPath.ts +13 -13
- package/src/assistDocument/AssistDocumentContext.tsx +3 -2
- package/src/assistDocument/AssistDocumentContextProvider.tsx +2 -1
- package/src/assistDocument/AssistDocumentInput.tsx +9 -8
- package/src/assistDocument/RequestRunInstructionProvider.tsx +4 -3
- package/src/assistDocument/components/AssistDocumentForm.tsx +25 -24
- package/src/assistDocument/components/FieldRefPreview.tsx +4 -3
- package/src/assistDocument/components/InstructionsArrayInput.tsx +4 -3
- package/src/assistDocument/components/SelectedFieldContext.tsx +1 -1
- package/src/assistDocument/components/helpers.ts +4 -4
- package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +3 -2
- package/src/assistDocument/components/instruction/FieldRefInput.tsx +5 -4
- package/src/assistDocument/components/instruction/InstructionInput.tsx +3 -2
- package/src/assistDocument/components/instruction/InstructionOutputField.tsx +2 -1
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +14 -13
- package/src/assistDocument/components/instruction/PromptInput.tsx +4 -3
- package/src/assistDocument/components/instruction/appearance/IconInput.tsx +2 -2
- package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +1 -1
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +7 -6
- package/src/assistDocument/hooks/useInstructionToaster.tsx +6 -5
- package/src/assistDocument/hooks/useStudioAssistDocument.ts +14 -13
- package/src/assistFormComponents/AssistField.tsx +9 -8
- package/src/assistFormComponents/AssistFormBlock.tsx +5 -4
- package/src/assistFormComponents/AssistInlineFormBlock.tsx +1 -1
- package/src/assistFormComponents/AssistItem.tsx +3 -2
- package/src/assistFormComponents/validation/listItem.tsx +2 -2
- package/src/assistFormComponents/validation/validationList.tsx +3 -2
- package/src/assistInspector/AssistInspector.tsx +16 -15
- package/src/assistInspector/FieldAutocomplete.tsx +4 -3
- package/src/assistInspector/InstructionTaskHistoryButton.tsx +19 -18
- package/src/assistInspector/helpers.ts +10 -9
- package/src/assistInspector/index.ts +4 -3
- package/src/assistLayout/AiAssistanceConfigContext.tsx +1 -0
- package/src/assistLayout/AssistLayout.tsx +5 -4
- package/src/assistLayout/RunInstructionProvider.tsx +18 -15
- package/src/components/FadeInContent.tsx +1 -1
- package/src/components/HideReferenceChangedBannerInput.tsx +1 -1
- package/src/components/ImageContext.tsx +4 -3
- package/src/components/SafeValueInput.tsx +7 -6
- package/src/components/TimeAgo.tsx +1 -1
- package/src/fieldActions/assistFieldActions.tsx +31 -30
- package/src/fieldActions/generateCaptionActions.tsx +8 -7
- package/src/fieldActions/generateImageActions.tsx +6 -5
- package/src/helpers/assistSupported.ts +1 -0
- package/src/helpers/conditionalMembers.test.ts +2 -1
- package/src/helpers/conditionalMembers.ts +17 -14
- package/src/helpers/misc.ts +3 -2
- package/src/helpers/typeUtils.ts +1 -1
- package/src/helpers/useAssistSupported.ts +2 -1
- package/src/onboarding/FieldActionsOnboarding.tsx +2 -1
- package/src/onboarding/FirstAssistedPathProvider.tsx +4 -3
- package/src/onboarding/InspectorOnboarding.tsx +3 -2
- package/src/onboarding/onboardingStore.ts +1 -1
- package/src/presence/AiFieldPresence.tsx +3 -1
- package/src/presence/AssistDocumentPresence.tsx +7 -6
- package/src/presence/useAssistPresence.ts +6 -3
- package/src/schemas/assistDocumentSchema.tsx +21 -20
- package/src/schemas/contextDocumentSchema.tsx +3 -2
- package/src/schemas/index.ts +2 -1
- package/src/schemas/serialize/SchemTypeTool.tsx +4 -3
- package/src/schemas/serialize/serializeSchema.test.ts +3 -2
- package/src/schemas/serialize/serializeSchema.ts +15 -14
- package/src/schemas/serializedSchemaTypeSchema.ts +2 -1
- package/src/translate/FieldTranslationProvider.tsx +33 -25
- package/src/translate/getLanguageParams.ts +3 -3
- package/src/translate/paths.test.ts +11 -4
- package/src/translate/paths.ts +12 -11
- package/src/translate/translateActions.tsx +12 -11
- package/src/translate/types.ts +2 -2
- package/src/useApiClient.ts +9 -9
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
CheckmarkCircleIcon,
|
|
3
|
+
ClockIcon,
|
|
4
|
+
CloseCircleIcon,
|
|
5
|
+
ErrorOutlineIcon,
|
|
6
|
+
SyncIcon,
|
|
7
|
+
} from '@sanity/icons'
|
|
3
8
|
import {
|
|
4
9
|
Box,
|
|
5
10
|
Button,
|
|
@@ -13,19 +18,15 @@ import {
|
|
|
13
18
|
useGlobalKeyDown,
|
|
14
19
|
useLayer,
|
|
15
20
|
} from '@sanity/ui'
|
|
16
|
-
import {
|
|
17
|
-
CheckmarkCircleIcon,
|
|
18
|
-
ClockIcon,
|
|
19
|
-
CloseCircleIcon,
|
|
20
|
-
ErrorOutlineIcon,
|
|
21
|
-
SyncIcon,
|
|
22
|
-
} from '@sanity/icons'
|
|
23
|
-
import {TimeAgo} from '../components/TimeAgo'
|
|
21
|
+
import {createElement, ForwardedRef, forwardRef, useCallback, useMemo, useState} from 'react'
|
|
24
22
|
import {StatusButton, StatusButtonProps, typed, useClient} from 'sanity'
|
|
25
|
-
import {getInstructionTitle} from '../helpers/misc'
|
|
26
23
|
import styled, {keyframes} from 'styled-components'
|
|
27
|
-
|
|
24
|
+
|
|
25
|
+
import {TimeAgo} from '../components/TimeAgo'
|
|
28
26
|
import {maxHistoryVisibilityMs, pluginTitle} from '../constants'
|
|
27
|
+
import {assistTasksStatusId} from '../helpers/ids'
|
|
28
|
+
import {getInstructionTitle} from '../helpers/misc'
|
|
29
|
+
import {AssistTasksStatus, InstructionTask, StudioInstruction, TaskEndedReason} from '../types'
|
|
29
30
|
|
|
30
31
|
export interface InstructionTaskHistoryButtonProps {
|
|
31
32
|
documentId?: string
|
|
@@ -96,7 +97,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
|
|
|
96
97
|
.commit()
|
|
97
98
|
.catch(console.error)
|
|
98
99
|
},
|
|
99
|
-
[client, documentId]
|
|
100
|
+
[client, documentId],
|
|
100
101
|
)
|
|
101
102
|
|
|
102
103
|
const titledTasks = useMemo(() => {
|
|
@@ -105,7 +106,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
|
|
|
105
106
|
?.filter(
|
|
106
107
|
(task) =>
|
|
107
108
|
task.started &&
|
|
108
|
-
new Date().getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs
|
|
109
|
+
new Date().getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs,
|
|
109
110
|
)
|
|
110
111
|
.map((task): CancelableInstructionTask => {
|
|
111
112
|
const instruction = instructions?.find((i) => i._key === task.instructionKey)
|
|
@@ -124,7 +125,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
|
|
|
124
125
|
const isRunning = useMemo(() => titledTasks.some((r) => !r.ended), [titledTasks])
|
|
125
126
|
const hasErrors = useMemo(
|
|
126
127
|
() => titledTasks.some((r) => r.reason === 'error' || r.reason === 'timeout'),
|
|
127
|
-
[titledTasks]
|
|
128
|
+
[titledTasks],
|
|
128
129
|
)
|
|
129
130
|
|
|
130
131
|
const [open, setOpen] = useState(false)
|
|
@@ -179,7 +180,7 @@ const TaskStatusButton = forwardRef(function TaskStatusButton(
|
|
|
179
180
|
onClick: () => void
|
|
180
181
|
selected: boolean
|
|
181
182
|
},
|
|
182
|
-
ref: ForwardedRef<HTMLButtonElement
|
|
183
|
+
ref: ForwardedRef<HTMLButtonElement>,
|
|
183
184
|
) {
|
|
184
185
|
const {disabled, hasErrors, isRunning, onClick, selected} = props
|
|
185
186
|
|
|
@@ -210,8 +211,8 @@ function TaskList(props: {onEscape: () => void; tasks: CancelableInstructionTask
|
|
|
210
211
|
onEscape()
|
|
211
212
|
}
|
|
212
213
|
},
|
|
213
|
-
[isTopLayer, onEscape]
|
|
214
|
-
)
|
|
214
|
+
[isTopLayer, onEscape],
|
|
215
|
+
),
|
|
215
216
|
)
|
|
216
217
|
|
|
217
218
|
return (
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
OlistIcon,
|
|
8
8
|
StringIcon,
|
|
9
9
|
} from '@sanity/icons'
|
|
10
|
+
import {extractWithPath} from '@sanity/mutator'
|
|
11
|
+
import {ComponentType, useContext, useMemo} from 'react'
|
|
10
12
|
import {
|
|
11
13
|
ArraySchemaType,
|
|
12
14
|
isKeySegment,
|
|
@@ -18,13 +20,12 @@ import {
|
|
|
18
20
|
SchemaType,
|
|
19
21
|
stringToPath,
|
|
20
22
|
} from 'sanity'
|
|
21
|
-
import {ComponentType, useContext, useMemo} from 'react'
|
|
22
|
-
import {AssistInspectorRouteParams, documentRootKey, fieldPathParam} from '../types'
|
|
23
23
|
import {type PaneRouterContextValue, usePaneRouter} from 'sanity/desk'
|
|
24
|
+
|
|
25
|
+
import {SelectedFieldContext} from '../assistDocument/components/SelectedFieldContext'
|
|
24
26
|
import {isAssistSupported} from '../helpers/assistSupported'
|
|
25
27
|
import {isPortableTextArray, isType} from '../helpers/typeUtils'
|
|
26
|
-
import {
|
|
27
|
-
import {extractWithPath} from '@sanity/mutator'
|
|
28
|
+
import {AssistInspectorRouteParams, documentRootKey, fieldPathParam} from '../types'
|
|
28
29
|
|
|
29
30
|
export interface FieldRef {
|
|
30
31
|
key: string
|
|
@@ -74,7 +75,7 @@ export function getFieldRefsWithDocument(schemaType: ObjectSchemaType): FieldRef
|
|
|
74
75
|
export function getFieldRefs(
|
|
75
76
|
schemaType: ObjectSchemaType,
|
|
76
77
|
parent?: FieldRef,
|
|
77
|
-
depth = 0
|
|
78
|
+
depth = 0,
|
|
78
79
|
): FieldRef[] {
|
|
79
80
|
if (depth >= maxDepth) {
|
|
80
81
|
return []
|
|
@@ -171,14 +172,14 @@ export function useTypePath(doc: SanityDocumentLike, pathString: string) {
|
|
|
171
172
|
|
|
172
173
|
export function useSelectedField(
|
|
173
174
|
documentSchemaType?: SchemaType,
|
|
174
|
-
path?: string
|
|
175
|
+
path?: string,
|
|
175
176
|
): FieldRef | undefined {
|
|
176
177
|
const selectableFields = useMemo(
|
|
177
178
|
() =>
|
|
178
179
|
documentSchemaType && isObjectSchemaType(documentSchemaType)
|
|
179
180
|
? getFieldRefsWithDocument(documentSchemaType)
|
|
180
181
|
: [],
|
|
181
|
-
[documentSchemaType]
|
|
182
|
+
[documentSchemaType],
|
|
182
183
|
)
|
|
183
184
|
|
|
184
185
|
return useMemo(() => {
|
|
@@ -207,7 +208,7 @@ export function useAiPaneRouter() {
|
|
|
207
208
|
const paneRouter = usePaneRouter()
|
|
208
209
|
|
|
209
210
|
return useMemo(
|
|
210
|
-
() => ({...paneRouter, params: paneRouter.params ?? {}} as AiPaneRouter
|
|
211
|
-
[paneRouter]
|
|
211
|
+
() => ({...paneRouter, params: paneRouter.params ?? {}}) as AiPaneRouter,
|
|
212
|
+
[paneRouter],
|
|
212
213
|
)
|
|
213
214
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {SparklesIcon} from '@sanity/icons'
|
|
2
2
|
import {DocumentInspector, typed} from 'sanity'
|
|
3
|
-
|
|
4
|
-
import {AssistInspectorWrapper} from './AssistInspector'
|
|
5
|
-
import {AssistInspectorRouteParams, fieldPathParam, instructionParam} from '../types'
|
|
3
|
+
|
|
6
4
|
import {pluginTitle} from '../constants'
|
|
5
|
+
import {AssistInspectorRouteParams, fieldPathParam, instructionParam} from '../types'
|
|
6
|
+
import {AssistInspectorWrapper} from './AssistInspector'
|
|
7
|
+
import {aiInspectorId} from './constants'
|
|
7
8
|
|
|
8
9
|
export const assistInspector: DocumentInspector = {
|
|
9
10
|
name: aiInspectorId,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
1
2
|
import {useState} from 'react'
|
|
2
3
|
import {LayoutProps} from 'sanity'
|
|
4
|
+
|
|
3
5
|
import {Connector, ConnectorsProvider} from '../_lib/connector'
|
|
4
6
|
import {AssistConnectorsOverlay} from '../assistConnectors'
|
|
5
7
|
import {AssistPluginConfig} from '../plugin'
|
|
6
|
-
import {
|
|
7
|
-
import {RunInstructionRequest} from '../useApiClient'
|
|
8
|
+
import {FieldTranslationProvider} from '../translate/FieldTranslationProvider'
|
|
8
9
|
import {StudioInstruction} from '../types'
|
|
10
|
+
import {RunInstructionRequest} from '../useApiClient'
|
|
11
|
+
import {AiAssistanceConfigProvider} from './AiAssistanceConfigContext'
|
|
9
12
|
import {RunInstructionProvider} from './RunInstructionProvider'
|
|
10
|
-
import {ThemeProvider} from '@sanity/ui'
|
|
11
|
-
import {FieldTranslationProvider} from '../translate/FieldTranslationProvider'
|
|
12
13
|
|
|
13
14
|
export interface AIStudioLayoutProps extends LayoutProps {
|
|
14
15
|
config: AssistPluginConfig
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {Button, Dialog, Flex, Stack, Text, TextArea, Tooltip} from '@sanity/ui'
|
|
2
|
-
import {getInstructionTitle} from '../helpers/misc'
|
|
3
1
|
import {PlayIcon} from '@sanity/icons'
|
|
2
|
+
import {Button, Dialog, Flex, Stack, Text, TextArea, Tooltip} from '@sanity/ui'
|
|
4
3
|
import {
|
|
5
4
|
createContext,
|
|
6
|
-
Dispatch,
|
|
7
|
-
FormEvent,
|
|
8
|
-
PropsWithChildren,
|
|
9
|
-
SetStateAction,
|
|
5
|
+
type Dispatch,
|
|
6
|
+
type FormEvent,
|
|
7
|
+
type PropsWithChildren,
|
|
8
|
+
type SetStateAction,
|
|
10
9
|
useCallback,
|
|
11
10
|
useContext,
|
|
12
11
|
useEffect,
|
|
@@ -15,11 +14,13 @@ import {
|
|
|
15
14
|
useRef,
|
|
16
15
|
useState,
|
|
17
16
|
} from 'react'
|
|
18
|
-
import {
|
|
19
|
-
|
|
17
|
+
import {FormFieldHeaderText} from 'sanity'
|
|
18
|
+
|
|
19
|
+
import {getInstructionTitle} from '../helpers/misc'
|
|
20
|
+
import {type UserInputBlock, userInputTypeName} from '../types'
|
|
20
21
|
import {useApiClient, useRunInstructionApi} from '../useApiClient'
|
|
21
22
|
import {useAiAssistanceConfig} from './AiAssistanceConfigContext'
|
|
22
|
-
import {
|
|
23
|
+
import type {RunInstructionArgs} from './AssistLayout'
|
|
23
24
|
|
|
24
25
|
type BlockInputs = Record<string, string>
|
|
25
26
|
const NO_INPUT: BlockInputs = {}
|
|
@@ -42,6 +43,7 @@ function isUserInputBlock(block: {_type: string}): block is UserInputBlock {
|
|
|
42
43
|
return block._type === userInputTypeName
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
45
47
|
export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
46
48
|
const {config} = useAiAssistanceConfig()
|
|
47
49
|
const apiClient = useApiClient(config?.__customApiClient)
|
|
@@ -63,7 +65,7 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
63
65
|
const instructionKey = instruction._key
|
|
64
66
|
const userInputBlocks = instruction?.prompt
|
|
65
67
|
?.flatMap((block) =>
|
|
66
|
-
block._type === 'block' ? block.children.filter(isUserInputBlock) : [block]
|
|
68
|
+
block._type === 'block' ? block.children.filter(isUserInputBlock) : [block],
|
|
67
69
|
)
|
|
68
70
|
.filter(isUserInputBlock)
|
|
69
71
|
|
|
@@ -81,16 +83,17 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
81
83
|
userInputBlocks,
|
|
82
84
|
})
|
|
83
85
|
},
|
|
84
|
-
[
|
|
86
|
+
[runInstructionRequest, loading],
|
|
85
87
|
)
|
|
86
88
|
|
|
87
89
|
const close = useCallback(() => {
|
|
88
90
|
setRunRequest(undefined)
|
|
89
91
|
setInputs(NO_INPUT)
|
|
90
|
-
}, [
|
|
92
|
+
}, [])
|
|
91
93
|
|
|
92
94
|
const runWithInput = useCallback(() => {
|
|
93
95
|
if (runRequest) {
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
94
97
|
const {instruction, userTexts, ...request} = runRequest
|
|
95
98
|
runInstructionRequest({
|
|
96
99
|
...request,
|
|
@@ -110,7 +113,7 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
110
113
|
() =>
|
|
111
114
|
(runRequest?.userInputBlocks?.length ?? 0) >
|
|
112
115
|
Object.entries(inputs).filter(([, value]) => !!value).length,
|
|
113
|
-
[runRequest?.userInputBlocks, inputs]
|
|
116
|
+
[runRequest?.userInputBlocks, inputs],
|
|
114
117
|
)
|
|
115
118
|
|
|
116
119
|
const runButton = (
|
|
@@ -126,7 +129,7 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
126
129
|
|
|
127
130
|
const contextValue: RunInstructionContextValue = useMemo(
|
|
128
131
|
() => ({runInstruction, instructionLoading: loading}),
|
|
129
|
-
[runInstruction, loading]
|
|
132
|
+
[runInstruction, loading],
|
|
130
133
|
)
|
|
131
134
|
|
|
132
135
|
return (
|
|
@@ -192,7 +195,7 @@ function UserInput(props: {
|
|
|
192
195
|
[key]: (e.currentTarget ?? e.target).value,
|
|
193
196
|
}))
|
|
194
197
|
},
|
|
195
|
-
[key, setInputs]
|
|
198
|
+
[key, setInputs],
|
|
196
199
|
)
|
|
197
200
|
|
|
198
201
|
const value = useMemo(() => inputs[key], [inputs, key])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {ObjectInputProps} from 'sanity'
|
|
2
1
|
import {Box} from '@sanity/ui'
|
|
3
2
|
import {useEffect, useRef} from 'react'
|
|
3
|
+
import {ObjectInputProps} from 'sanity'
|
|
4
4
|
|
|
5
5
|
export function HideReferenceChangedBannerInput(props: ObjectInputProps) {
|
|
6
6
|
const ref = useRef<HTMLDivElement>(null)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {createContext, useEffect, useMemo, useState} from 'react'
|
|
2
2
|
import {InputProps, pathToString, useSyncState} from 'sanity'
|
|
3
|
-
import {
|
|
3
|
+
import {usePaneRouter} from 'sanity/desk'
|
|
4
|
+
|
|
4
5
|
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
5
|
-
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
6
6
|
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
7
7
|
import {publicId} from '../helpers/ids'
|
|
8
|
-
import {
|
|
8
|
+
import {getDescriptionFieldOption, getImageInstructionFieldOption} from '../helpers/typeUtils'
|
|
9
|
+
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
9
10
|
|
|
10
11
|
export interface ImageContextValue {
|
|
11
12
|
imageDescriptionPath?: string
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {InputProps, isArraySchemaType, PatchEvent, unset} from 'sanity'
|
|
2
|
-
import {ErrorInfo, PropsWithChildren, useCallback, useMemo, useState} from 'react'
|
|
3
1
|
import {Box, Button, Card, ErrorBoundary, Flex, Stack, Text} from '@sanity/ui'
|
|
4
|
-
import {
|
|
2
|
+
import {ErrorInfo, PropsWithChildren, useCallback, useMemo, useState} from 'react'
|
|
3
|
+
import {InputProps, isArraySchemaType, PatchEvent, unset} from 'sanity'
|
|
5
4
|
import styled from 'styled-components'
|
|
6
5
|
|
|
6
|
+
import {isPortableTextArray} from '../helpers/typeUtils'
|
|
7
|
+
|
|
7
8
|
const WrapPreCard = styled(Card)`
|
|
8
9
|
& pre {
|
|
9
10
|
white-space: pre-wrap !important;
|
|
@@ -19,7 +20,7 @@ export function SafeValueInput(props: InputProps) {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function ErrorWrapper(
|
|
22
|
-
props: PropsWithChildren<{onChange: (patchEvent: PatchEvent) => void}
|
|
23
|
+
props: PropsWithChildren<{onChange: (patchEvent: PatchEvent) => void}>,
|
|
23
24
|
) {
|
|
24
25
|
const {onChange} = props
|
|
25
26
|
const [error, setError] = useState<Error | undefined>()
|
|
@@ -28,7 +29,7 @@ export function ErrorWrapper(
|
|
|
28
29
|
(params: {error: Error; info: ErrorInfo}) => {
|
|
29
30
|
setError(params.error)
|
|
30
31
|
},
|
|
31
|
-
[setError]
|
|
32
|
+
[setError],
|
|
32
33
|
)
|
|
33
34
|
|
|
34
35
|
const unsetValue = useCallback(() => {
|
|
@@ -65,7 +66,7 @@ export function ErrorWrapper(
|
|
|
65
66
|
function PteValueFixer(props: InputProps) {
|
|
66
67
|
const isPortableText = useMemo(
|
|
67
68
|
() => isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType),
|
|
68
|
-
[props.schemaType]
|
|
69
|
+
[props.schemaType],
|
|
69
70
|
)
|
|
70
71
|
const value = props.value
|
|
71
72
|
if (isPortableText && value && !(value as any[]).length) {
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
+
import {ControlsIcon, SparklesIcon} from '@sanity/icons'
|
|
2
|
+
import {useCallback, useMemo, useRef} from 'react'
|
|
1
3
|
import {
|
|
2
|
-
DocumentFieldAction,
|
|
3
|
-
DocumentFieldActionGroup,
|
|
4
|
-
DocumentFieldActionItem,
|
|
5
|
-
ObjectSchemaType,
|
|
4
|
+
type DocumentFieldAction,
|
|
5
|
+
type DocumentFieldActionGroup,
|
|
6
|
+
type DocumentFieldActionItem,
|
|
7
|
+
type ObjectSchemaType,
|
|
6
8
|
typed,
|
|
7
9
|
useCurrentUser,
|
|
8
10
|
} from 'sanity'
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
import {pluginTitleShort} from '../constants'
|
|
12
|
-
import {useAssistSupported} from '../helpers/useAssistSupported'
|
|
11
|
+
import {useDocumentPane} from 'sanity/desk'
|
|
12
|
+
|
|
13
13
|
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
14
|
-
import {getInstructionTitle, usePathKey} from '../helpers/misc'
|
|
15
|
-
import {documentRootKey, fieldPathParam, instructionParam, StudioInstruction} from '../types'
|
|
16
|
-
import {aiInspectorId} from '../assistInspector/constants'
|
|
17
14
|
import {getIcon} from '../assistDocument/components/instruction/appearance/IconInput'
|
|
18
15
|
import {useAssistDocumentContextValue} from '../assistDocument/hooks/useAssistDocumentContextValue'
|
|
19
16
|
import {
|
|
20
17
|
getAssistableDocId,
|
|
21
18
|
useRequestRunInstruction,
|
|
22
19
|
} from '../assistDocument/RequestRunInstructionProvider'
|
|
23
|
-
import {
|
|
24
|
-
import {generateCaptionsActions} from './generateCaptionActions'
|
|
25
|
-
import {useDocumentPane} from 'sanity/desk'
|
|
20
|
+
import {aiInspectorId} from '../assistInspector/constants'
|
|
26
21
|
import {useSelectedField, useTypePath} from '../assistInspector/helpers'
|
|
22
|
+
import {pluginTitleShort} from '../constants'
|
|
27
23
|
import {isSchemaAssistEnabled} from '../helpers/assistSupported'
|
|
28
|
-
import {translateActions, TranslateProps} from '../translate/translateActions'
|
|
29
|
-
import {generateImagActions} from './generateImageActions'
|
|
30
24
|
import {getConditionalMembers} from '../helpers/conditionalMembers'
|
|
25
|
+
import {getInstructionTitle, usePathKey} from '../helpers/misc'
|
|
26
|
+
import {useAssistSupported} from '../helpers/useAssistSupported'
|
|
27
|
+
import {translateActions, type TranslateProps} from '../translate/translateActions'
|
|
28
|
+
import {documentRootKey, fieldPathParam, instructionParam, type StudioInstruction} from '../types'
|
|
29
|
+
import {generateCaptionsActions} from './generateCaptionActions'
|
|
30
|
+
import {generateImagActions} from './generateImageActions'
|
|
31
|
+
import {PrivateIcon} from './PrivateIcon'
|
|
31
32
|
|
|
32
33
|
function node(node: DocumentFieldActionItem | DocumentFieldActionGroup) {
|
|
33
34
|
return node
|
|
@@ -87,9 +88,9 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
87
88
|
const fieldAssist = useMemo(
|
|
88
89
|
() =>
|
|
89
90
|
(assistDocument?.fields ?? []).find(
|
|
90
|
-
(f) => f.path === typePath || (pathKey === documentRootKey && f.path === pathKey)
|
|
91
|
+
(f) => f.path === typePath || (pathKey === documentRootKey && f.path === pathKey),
|
|
91
92
|
),
|
|
92
|
-
[assistDocument?.fields, pathKey, typePath]
|
|
93
|
+
[assistDocument?.fields, pathKey, typePath],
|
|
93
94
|
)
|
|
94
95
|
|
|
95
96
|
const fieldAssistKey = fieldAssist?._key
|
|
@@ -105,7 +106,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
105
106
|
documentId: assistableDocumentId,
|
|
106
107
|
documentIsAssistable,
|
|
107
108
|
documentSchemaType,
|
|
108
|
-
})
|
|
109
|
+
}),
|
|
109
110
|
)
|
|
110
111
|
const manageInstructions = useCallback(
|
|
111
112
|
() =>
|
|
@@ -115,7 +116,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
115
116
|
[fieldPathParam]: pathKey,
|
|
116
117
|
[instructionParam]: undefined as any,
|
|
117
118
|
}),
|
|
118
|
-
[openInspector, closeInspector, isSelected, pathKey]
|
|
119
|
+
[openInspector, closeInspector, isSelected, pathKey],
|
|
119
120
|
)
|
|
120
121
|
|
|
121
122
|
const onInstructionAction = useCallback(
|
|
@@ -134,23 +135,23 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
134
135
|
: [],
|
|
135
136
|
})
|
|
136
137
|
},
|
|
137
|
-
[requestRunInstruction, assistableDocId, pathKey, typePath, assistDocumentId, fieldAssistKey]
|
|
138
|
+
[requestRunInstruction, assistableDocId, pathKey, typePath, assistDocumentId, fieldAssistKey],
|
|
138
139
|
)
|
|
139
140
|
|
|
140
141
|
const privateInstructions = useMemo(
|
|
141
142
|
() =>
|
|
142
143
|
fieldAssist?.instructions?.filter((i) => i.userId && i.userId === currentUser?.id) || [],
|
|
143
|
-
[fieldAssist?.instructions, currentUser]
|
|
144
|
+
[fieldAssist?.instructions, currentUser],
|
|
144
145
|
)
|
|
145
146
|
|
|
146
147
|
const sharedInstructions = useMemo(
|
|
147
148
|
() => fieldAssist?.instructions?.filter((i) => !i.userId) || [],
|
|
148
|
-
[fieldAssist?.instructions]
|
|
149
|
+
[fieldAssist?.instructions],
|
|
149
150
|
)
|
|
150
151
|
|
|
151
152
|
const instructions = useMemo(
|
|
152
153
|
() => [...privateInstructions, ...sharedInstructions],
|
|
153
|
-
[privateInstructions, sharedInstructions]
|
|
154
|
+
[privateInstructions, sharedInstructions],
|
|
154
155
|
)
|
|
155
156
|
|
|
156
157
|
const runInstructionsGroup = useMemo(() => {
|
|
@@ -160,7 +161,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
160
161
|
icon: () => null,
|
|
161
162
|
title: 'Run instructions',
|
|
162
163
|
children: [
|
|
163
|
-
...instructions?.map((instruction) =>
|
|
164
|
+
...(instructions?.map((instruction) =>
|
|
164
165
|
instructionItem({
|
|
165
166
|
instruction,
|
|
166
167
|
isPrivate: Boolean(instruction.userId && instruction.userId === currentUser?.id),
|
|
@@ -168,8 +169,8 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
168
169
|
hidden: isHidden,
|
|
169
170
|
documentIsNew: !!documentIsNew,
|
|
170
171
|
assistSupported,
|
|
171
|
-
})
|
|
172
|
-
),
|
|
172
|
+
}),
|
|
173
|
+
) || []),
|
|
173
174
|
imageCaptionAction,
|
|
174
175
|
imageGenAction,
|
|
175
176
|
].filter((a): a is DocumentFieldActionItem => !!a),
|
|
@@ -199,7 +200,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
199
200
|
onAction: manageInstructions,
|
|
200
201
|
selected: isSelected,
|
|
201
202
|
}),
|
|
202
|
-
[manageInstructions, isSelected]
|
|
203
|
+
[manageInstructions, isSelected],
|
|
203
204
|
)
|
|
204
205
|
|
|
205
206
|
const group = useMemo(
|
|
@@ -227,7 +228,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
227
228
|
imageCaptionAction,
|
|
228
229
|
translateAction,
|
|
229
230
|
imageGenAction,
|
|
230
|
-
]
|
|
231
|
+
],
|
|
231
232
|
)
|
|
232
233
|
|
|
233
234
|
const emptyAction = useMemo(
|
|
@@ -241,7 +242,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
241
242
|
title: pluginTitleShort,
|
|
242
243
|
selected: isSelected,
|
|
243
244
|
}),
|
|
244
|
-
[assistSupported, manageInstructions, isSelected]
|
|
245
|
+
[assistSupported, manageInstructions, isSelected],
|
|
245
246
|
)
|
|
246
247
|
|
|
247
248
|
// If there are no instructions, we don't want to render the group
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {DocumentFieldAction, DocumentFieldActionGroup, DocumentFieldActionItem} from 'sanity'
|
|
2
1
|
import {ImageIcon} from '@sanity/icons'
|
|
3
|
-
import {useContext, useMemo} from 'react'
|
|
4
|
-
import {usePathKey} from '../helpers/misc'
|
|
5
|
-
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
6
|
-
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
7
|
-
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
8
|
-
import {ImageContext} from '../components/ImageContext'
|
|
9
2
|
import {Box, Spinner} from '@sanity/ui'
|
|
3
|
+
import {useContext, useMemo} from 'react'
|
|
4
|
+
import {DocumentFieldAction, DocumentFieldActionGroup, DocumentFieldActionItem} from 'sanity'
|
|
10
5
|
import {useDocumentPane} from 'sanity/desk'
|
|
6
|
+
|
|
7
|
+
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
11
8
|
import {aiInspectorId} from '../assistInspector/constants'
|
|
9
|
+
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
10
|
+
import {ImageContext} from '../components/ImageContext'
|
|
11
|
+
import {usePathKey} from '../helpers/misc'
|
|
12
12
|
import {fieldPathParam, instructionParam} from '../types'
|
|
13
|
+
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
13
14
|
|
|
14
15
|
function node(node: DocumentFieldActionItem | DocumentFieldActionGroup) {
|
|
15
16
|
return node
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {DocumentFieldAction, DocumentFieldActionGroup, DocumentFieldActionItem} from 'sanity'
|
|
2
1
|
import {ImageIcon} from '@sanity/icons'
|
|
2
|
+
import {Box, Spinner} from '@sanity/ui'
|
|
3
3
|
import {useContext, useMemo} from 'react'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
4
|
+
import {DocumentFieldAction, DocumentFieldActionGroup, DocumentFieldActionItem} from 'sanity'
|
|
5
|
+
|
|
7
6
|
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
7
|
+
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
8
8
|
import {ImageContext} from '../components/ImageContext'
|
|
9
|
-
import {
|
|
9
|
+
import {usePathKey} from '../helpers/misc'
|
|
10
|
+
import {useApiClient, useGenerateImage} from '../useApiClient'
|
|
10
11
|
|
|
11
12
|
function node(node: DocumentFieldActionItem | DocumentFieldActionGroup) {
|
|
12
13
|
return node
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {describe, expect, test} from 'vitest'
|
|
2
1
|
import {Schema} from '@sanity/schema'
|
|
3
2
|
import {ArraySchemaType, defineField, defineType, ObjectSchemaType} from 'sanity'
|
|
3
|
+
import {describe, expect, test} from 'vitest'
|
|
4
|
+
|
|
4
5
|
import {getConditionalMembers} from './conditionalMembers'
|
|
5
6
|
|
|
6
7
|
describe('conditionalMembers', () => {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable max-depth */
|
|
2
2
|
import {
|
|
3
|
-
ArrayOfObjectsFormNode,
|
|
4
|
-
ArrayOfObjectsItemMember,
|
|
5
|
-
ArrayOfPrimitivesFormNode,
|
|
6
|
-
DocumentFormNode,
|
|
7
|
-
FieldsetState,
|
|
3
|
+
type ArrayOfObjectsFormNode,
|
|
4
|
+
type ArrayOfObjectsItemMember,
|
|
5
|
+
type ArrayOfPrimitivesFormNode,
|
|
6
|
+
type DocumentFormNode,
|
|
7
|
+
type FieldsetState,
|
|
8
8
|
isObjectSchemaType,
|
|
9
|
-
ObjectFormNode,
|
|
10
|
-
Path,
|
|
9
|
+
type ObjectFormNode,
|
|
10
|
+
type Path,
|
|
11
11
|
pathToString,
|
|
12
|
-
SchemaType,
|
|
12
|
+
type SchemaType,
|
|
13
13
|
} from 'sanity'
|
|
14
14
|
|
|
15
15
|
const MAX_DEPTH = 8
|
|
@@ -44,9 +44,12 @@ export function getConditionalMembers(docState: DocumentFormNode): ConditionalMe
|
|
|
44
44
|
readOnly: !!docState.readOnly,
|
|
45
45
|
conditional: typeof docState.schemaType.hidden === 'function',
|
|
46
46
|
}
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return (
|
|
48
|
+
[doc, ...extractConditionalPaths(docState, MAX_DEPTH)]
|
|
49
|
+
.filter((v) => v.conditional)
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
+
.map(({conditional, ...state}) => ({...state}))
|
|
52
|
+
)
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
function isConditional(schemaType: SchemaType) {
|
|
@@ -68,7 +71,7 @@ function conditionalState(memberState: {
|
|
|
68
71
|
|
|
69
72
|
function extractConditionalPaths(
|
|
70
73
|
node: ObjectFormNode | FieldsetState,
|
|
71
|
-
maxDepth: number
|
|
74
|
+
maxDepth: number,
|
|
72
75
|
): ConditionalMemberInnerState[] {
|
|
73
76
|
if (node.path.length >= maxDepth) {
|
|
74
77
|
return []
|
|
@@ -90,7 +93,7 @@ function extractConditionalPaths(
|
|
|
90
93
|
|
|
91
94
|
let arrayPaths: ConditionalMemberInnerState[] = []
|
|
92
95
|
const isObjectsArray = array.members.some(
|
|
93
|
-
(m) => m.kind === 'item' && isObjectSchemaType(m.item.schemaType)
|
|
96
|
+
(m) => m.kind === 'item' && isObjectSchemaType(m.item.schemaType),
|
|
94
97
|
)
|
|
95
98
|
if (!array.readOnly) {
|
|
96
99
|
for (const arrayMember of array.members) {
|
|
@@ -112,7 +115,7 @@ function extractConditionalPaths(
|
|
|
112
115
|
return [...acc, conditionalState(member.field)]
|
|
113
116
|
} else if (member.kind === 'fieldSet') {
|
|
114
117
|
const conditionalFieldset = !!(node as ObjectFormNode).schemaType?.fieldsets?.some(
|
|
115
|
-
(f) => !f.single && f.name === member.fieldSet.name && typeof f.hidden === 'function'
|
|
118
|
+
(f) => !f.single && f.name === member.fieldSet.name && typeof f.hidden === 'function',
|
|
116
119
|
)
|
|
117
120
|
const innerFields = extractConditionalPaths(member.fieldSet, maxDepth).map((f) => ({
|
|
118
121
|
...f,
|
package/src/helpers/misc.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {documentRootKey, StudioInstruction} from '../types'
|
|
2
|
-
import {Path, pathToString} from 'sanity'
|
|
3
1
|
import {useMemo} from 'react'
|
|
2
|
+
import {Path, pathToString} from 'sanity'
|
|
3
|
+
|
|
4
|
+
import {documentRootKey, StudioInstruction} from '../types'
|
|
4
5
|
|
|
5
6
|
export function usePathKey(path: Path | string) {
|
|
6
7
|
return useMemo(() => {
|