@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.
Files changed (91) hide show
  1. package/README.md +233 -214
  2. package/dist/index.esm.js +1769 -1769
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +1767 -1767
  5. package/dist/index.js.map +1 -1
  6. package/package.json +17 -18
  7. package/src/_lib/connector/ConnectFromRegion.tsx +4 -3
  8. package/src/_lib/connector/ConnectToRegion.tsx +1 -0
  9. package/src/_lib/connector/ConnectorRegion.tsx +2 -1
  10. package/src/_lib/connector/ConnectorsProvider.tsx +2 -1
  11. package/src/_lib/connector/ConnectorsStoreContext.ts +1 -0
  12. package/src/_lib/connector/index.ts +1 -1
  13. package/src/_lib/connector/mapConnectorToLine.ts +2 -2
  14. package/src/_lib/connector/useConnectorsStore.ts +2 -1
  15. package/src/_lib/connector/useRegionRects.ts +4 -3
  16. package/src/_lib/fixedListenQuery.ts +11 -11
  17. package/src/_lib/form/DocumentForm.tsx +4 -3
  18. package/src/_lib/form/helpers.ts +2 -1
  19. package/src/_lib/useListeningQuery.ts +4 -3
  20. package/src/assistConnectors/AssistConnectorsOverlay.tsx +1 -0
  21. package/src/assistConnectors/ConnectorPath.tsx +3 -2
  22. package/src/assistConnectors/draw/connectorPath.ts +13 -13
  23. package/src/assistDocument/AssistDocumentContext.tsx +3 -2
  24. package/src/assistDocument/AssistDocumentContextProvider.tsx +2 -1
  25. package/src/assistDocument/AssistDocumentInput.tsx +9 -8
  26. package/src/assistDocument/RequestRunInstructionProvider.tsx +4 -3
  27. package/src/assistDocument/components/AssistDocumentForm.tsx +25 -24
  28. package/src/assistDocument/components/FieldRefPreview.tsx +4 -3
  29. package/src/assistDocument/components/InstructionsArrayInput.tsx +4 -3
  30. package/src/assistDocument/components/SelectedFieldContext.tsx +1 -1
  31. package/src/assistDocument/components/helpers.ts +4 -4
  32. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +3 -2
  33. package/src/assistDocument/components/instruction/FieldRefInput.tsx +5 -4
  34. package/src/assistDocument/components/instruction/InstructionInput.tsx +3 -2
  35. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +2 -1
  36. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +14 -13
  37. package/src/assistDocument/components/instruction/PromptInput.tsx +4 -3
  38. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +2 -2
  39. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +1 -1
  40. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +7 -6
  41. package/src/assistDocument/hooks/useInstructionToaster.tsx +6 -5
  42. package/src/assistDocument/hooks/useStudioAssistDocument.ts +14 -13
  43. package/src/assistFormComponents/AssistField.tsx +9 -8
  44. package/src/assistFormComponents/AssistFormBlock.tsx +5 -4
  45. package/src/assistFormComponents/AssistInlineFormBlock.tsx +1 -1
  46. package/src/assistFormComponents/AssistItem.tsx +3 -2
  47. package/src/assistFormComponents/validation/listItem.tsx +2 -2
  48. package/src/assistFormComponents/validation/validationList.tsx +3 -2
  49. package/src/assistInspector/AssistInspector.tsx +16 -15
  50. package/src/assistInspector/FieldAutocomplete.tsx +4 -3
  51. package/src/assistInspector/InstructionTaskHistoryButton.tsx +19 -18
  52. package/src/assistInspector/helpers.ts +10 -9
  53. package/src/assistInspector/index.ts +4 -3
  54. package/src/assistLayout/AiAssistanceConfigContext.tsx +1 -0
  55. package/src/assistLayout/AssistLayout.tsx +5 -4
  56. package/src/assistLayout/RunInstructionProvider.tsx +18 -15
  57. package/src/components/FadeInContent.tsx +1 -1
  58. package/src/components/HideReferenceChangedBannerInput.tsx +1 -1
  59. package/src/components/ImageContext.tsx +4 -3
  60. package/src/components/SafeValueInput.tsx +7 -6
  61. package/src/components/TimeAgo.tsx +1 -1
  62. package/src/fieldActions/assistFieldActions.tsx +31 -30
  63. package/src/fieldActions/generateCaptionActions.tsx +8 -7
  64. package/src/fieldActions/generateImageActions.tsx +6 -5
  65. package/src/helpers/assistSupported.ts +1 -0
  66. package/src/helpers/conditionalMembers.test.ts +2 -1
  67. package/src/helpers/conditionalMembers.ts +17 -14
  68. package/src/helpers/misc.ts +3 -2
  69. package/src/helpers/typeUtils.ts +1 -1
  70. package/src/helpers/useAssistSupported.ts +2 -1
  71. package/src/onboarding/FieldActionsOnboarding.tsx +2 -1
  72. package/src/onboarding/FirstAssistedPathProvider.tsx +4 -3
  73. package/src/onboarding/InspectorOnboarding.tsx +3 -2
  74. package/src/onboarding/onboardingStore.ts +1 -1
  75. package/src/presence/AiFieldPresence.tsx +3 -1
  76. package/src/presence/AssistDocumentPresence.tsx +7 -6
  77. package/src/presence/useAssistPresence.ts +6 -3
  78. package/src/schemas/assistDocumentSchema.tsx +21 -20
  79. package/src/schemas/contextDocumentSchema.tsx +3 -2
  80. package/src/schemas/index.ts +2 -1
  81. package/src/schemas/serialize/SchemTypeTool.tsx +4 -3
  82. package/src/schemas/serialize/serializeSchema.test.ts +3 -2
  83. package/src/schemas/serialize/serializeSchema.ts +15 -14
  84. package/src/schemas/serializedSchemaTypeSchema.ts +2 -1
  85. package/src/translate/FieldTranslationProvider.tsx +33 -25
  86. package/src/translate/getLanguageParams.ts +3 -3
  87. package/src/translate/paths.test.ts +11 -4
  88. package/src/translate/paths.ts +12 -11
  89. package/src/translate/translateActions.tsx +12 -11
  90. package/src/translate/types.ts +2 -2
  91. package/src/useApiClient.ts +9 -9
@@ -1,5 +1,10 @@
1
- import {AssistTasksStatus, InstructionTask, StudioInstruction, TaskEndedReason} from '../types'
2
- import {createElement, ForwardedRef, forwardRef, useCallback, useMemo, useState} from 'react'
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
- import {assistTasksStatusId} from '../helpers/ids'
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 {SelectedFieldContext} from '../assistDocument/components/SelectedFieldContext'
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
- import {aiInspectorId} from './constants'
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,
@@ -7,6 +7,7 @@ import {
7
7
  useMemo,
8
8
  useState,
9
9
  } from 'react'
10
+
10
11
  import {AssistPluginConfig} from '../plugin'
11
12
  import {InstructStatus, useApiClient, useGetInstructStatus, useInitInstruct} from '../useApiClient'
12
13
 
@@ -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 {AiAssistanceConfigProvider} from './AiAssistanceConfigContext'
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 {UserInputBlock, userInputTypeName} from '../types'
19
- import {RunInstructionArgs} from './AssistLayout'
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 {FormFieldHeaderText} from 'sanity'
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
- [setRunRequest, runInstructionRequest, loading]
86
+ [runInstructionRequest, loading],
85
87
  )
86
88
 
87
89
  const close = useCallback(() => {
88
90
  setRunRequest(undefined)
89
91
  setInputs(NO_INPUT)
90
- }, [setRunRequest, setInputs])
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])
@@ -30,7 +30,7 @@ export const FadeInContent = forwardRef(function FadeInContent(
30
30
  ms?: number
31
31
  durationMs?: number
32
32
  },
33
- ref: any
33
+ ref: any,
34
34
  ): ReactElement {
35
35
  return (
36
36
  <FadeInDiv ref={ref} style={{animationDuration: `${durationMs}ms`}}>
@@ -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 {getDescriptionFieldOption, getImageInstructionFieldOption} from '../helpers/typeUtils'
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 {usePaneRouter} from 'sanity/desk'
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 {isPortableTextArray} from '../helpers/typeUtils'
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,5 +1,5 @@
1
- import {useEffect, useReducer} from 'react'
2
1
  import formatDistanceToNow from 'date-fns/formatDistanceToNow'
2
+ import {useEffect, useReducer} from 'react'
3
3
 
4
4
  function useInterval(ms: number) {
5
5
  const [tick, update] = useReducer((n) => n + 1, 0)
@@ -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 {ControlsIcon, SparklesIcon} from '@sanity/icons'
10
- import {useCallback, useMemo, useRef} from 'react'
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 {PrivateIcon} from './PrivateIcon'
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 {usePathKey} from '../helpers/misc'
5
- import {useApiClient, useGenerateImage} from '../useApiClient'
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 {Box, Spinner} from '@sanity/ui'
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,4 +1,5 @@
1
1
  import {ReferenceOptions, SchemaType} from 'sanity'
2
+
2
3
  import {AssistOptions} from '../schemas/typeDefExtensions'
3
4
  import {isType} from './typeUtils'
4
5
 
@@ -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 [doc, ...extractConditionalPaths(docState, MAX_DEPTH)]
48
- .filter((v) => v.conditional)
49
- .map(({conditional, ...state}) => ({...state}))
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,
@@ -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(() => {