@sanity/assist 5.0.3 → 6.0.0

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 (131) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +28 -254
  3. package/dist/index.d.ts +322 -410
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3182 -2673
  6. package/dist/index.js.map +1 -1
  7. package/package.json +41 -77
  8. package/dist/index.cjs +0 -4264
  9. package/dist/index.cjs.map +0 -1
  10. package/dist/index.d.cts +0 -791
  11. package/sanity.json +0 -8
  12. package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
  13. package/src/_lib/connector/ConnectToRegion.tsx +0 -23
  14. package/src/_lib/connector/ConnectorRegion.tsx +0 -24
  15. package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
  16. package/src/_lib/connector/ConnectorsStore.ts +0 -122
  17. package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
  18. package/src/_lib/connector/helpers.ts +0 -5
  19. package/src/_lib/connector/index.ts +0 -9
  20. package/src/_lib/connector/mapConnectorToLine.ts +0 -83
  21. package/src/_lib/connector/types.ts +0 -56
  22. package/src/_lib/connector/useConnectorsStore.ts +0 -14
  23. package/src/_lib/connector/useRegionRects.ts +0 -142
  24. package/src/_lib/fixedListenQuery.ts +0 -101
  25. package/src/_lib/form/DocumentForm.tsx +0 -201
  26. package/src/_lib/form/constants.ts +0 -1
  27. package/src/_lib/form/helpers.ts +0 -32
  28. package/src/_lib/form/index.ts +0 -1
  29. package/src/_lib/randomKey.ts +0 -29
  30. package/src/_lib/useListeningQuery.ts +0 -62
  31. package/src/_lib/usePrevious.ts +0 -9
  32. package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
  33. package/src/assistConnectors/ConnectorPath.tsx +0 -63
  34. package/src/assistConnectors/draw/arrowPath.ts +0 -9
  35. package/src/assistConnectors/draw/connectorPath.ts +0 -142
  36. package/src/assistConnectors/index.ts +0 -1
  37. package/src/assistDocument/AssistDocumentContext.tsx +0 -51
  38. package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
  39. package/src/assistDocument/AssistDocumentInput.tsx +0 -61
  40. package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
  41. package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
  42. package/src/assistDocument/components/AssistDocumentForm.tsx +0 -286
  43. package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
  44. package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
  45. package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
  46. package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
  47. package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
  48. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
  49. package/src/assistDocument/components/helpers.ts +0 -21
  50. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
  51. package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
  52. package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
  53. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
  54. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
  55. package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
  56. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
  57. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
  58. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -129
  59. package/src/assistDocument/hooks/useDocumentState.ts +0 -6
  60. package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
  61. package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
  62. package/src/assistDocument/index.ts +0 -1
  63. package/src/assistFormComponents/AssistField.tsx +0 -63
  64. package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
  65. package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
  66. package/src/assistFormComponents/AssistItem.tsx +0 -21
  67. package/src/assistFormComponents/validation/listItem.tsx +0 -63
  68. package/src/assistFormComponents/validation/validationList.tsx +0 -90
  69. package/src/assistInspector/AssistInspector.tsx +0 -423
  70. package/src/assistInspector/FieldAutocomplete.tsx +0 -146
  71. package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
  72. package/src/assistInspector/constants.ts +0 -1
  73. package/src/assistInspector/helpers.ts +0 -211
  74. package/src/assistInspector/index.ts +0 -27
  75. package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
  76. package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
  77. package/src/assistLayout/AssistLayout.tsx +0 -39
  78. package/src/assistLayout/RunInstructionProvider.tsx +0 -278
  79. package/src/assistLayout/fieldRefCache.tsx +0 -34
  80. package/src/assistTypes.ts +0 -83
  81. package/src/components/AssistFeatureBadge.tsx +0 -9
  82. package/src/components/FadeInContent.tsx +0 -40
  83. package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
  84. package/src/components/ImageContext.tsx +0 -85
  85. package/src/components/SafeValueInput.tsx +0 -74
  86. package/src/components/TimeAgo.tsx +0 -18
  87. package/src/constants.ts +0 -20
  88. package/src/fieldActions/PrivateIcon.tsx +0 -20
  89. package/src/fieldActions/assistFieldActions.tsx +0 -320
  90. package/src/fieldActions/customFieldActions.tsx +0 -333
  91. package/src/fieldActions/generateCaptionActions.tsx +0 -77
  92. package/src/fieldActions/generateImageActions.tsx +0 -58
  93. package/src/fieldActions/useUserInput.ts +0 -107
  94. package/src/globals.d.ts +0 -4
  95. package/src/helpers/assistSupported.ts +0 -49
  96. package/src/helpers/conditionalMembers.test.ts +0 -319
  97. package/src/helpers/conditionalMembers.ts +0 -134
  98. package/src/helpers/ids.test.ts +0 -28
  99. package/src/helpers/ids.ts +0 -23
  100. package/src/helpers/misc.ts +0 -25
  101. package/src/helpers/styleguide.ts +0 -24
  102. package/src/helpers/typeUtils.ts +0 -60
  103. package/src/helpers/useAssistSupported.ts +0 -8
  104. package/src/index.ts +0 -26
  105. package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
  106. package/src/onboarding/InspectorOnboarding.tsx +0 -47
  107. package/src/onboarding/onboardingStore.ts +0 -32
  108. package/src/plugin.tsx +0 -162
  109. package/src/presence/AiFieldPresence.tsx +0 -28
  110. package/src/presence/AssistAvatar.tsx +0 -96
  111. package/src/presence/AssistDocumentPresence.tsx +0 -50
  112. package/src/presence/useAssistPresence.ts +0 -64
  113. package/src/schemas/assistDocumentSchema.tsx +0 -497
  114. package/src/schemas/contextDocumentSchema.tsx +0 -57
  115. package/src/schemas/index.ts +0 -69
  116. package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
  117. package/src/schemas/serialize/schemaUtils.ts +0 -38
  118. package/src/schemas/serialize/serializeSchema.test.ts +0 -819
  119. package/src/schemas/serialize/serializeSchema.ts +0 -224
  120. package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
  121. package/src/schemas/typeDefExtensions.ts +0 -127
  122. package/src/translate/FieldTranslationProvider.tsx +0 -382
  123. package/src/translate/getLanguageParams.ts +0 -26
  124. package/src/translate/languageStore.ts +0 -18
  125. package/src/translate/paths.test.ts +0 -181
  126. package/src/translate/paths.ts +0 -183
  127. package/src/translate/translateActions.tsx +0 -205
  128. package/src/translate/types.ts +0 -197
  129. package/src/types.ts +0 -220
  130. package/src/useApiClient.ts +0 -338
  131. package/v2-incompatible.js +0 -11
@@ -1,423 +0,0 @@
1
- import {ArrowRightIcon, CloseIcon, PlayIcon, RetryIcon} from '@sanity/icons'
2
- import {Box, Button, Card, Flex, Spinner, Stack, Text} from '@sanity/ui'
3
- import {useCallback, useMemo, useRef} from 'react'
4
- import {
5
- type DocumentInspectorProps,
6
- PresenceOverlay,
7
- VirtualizerScrollInstanceProvider,
8
- } from 'sanity'
9
- import {
10
- DocumentInspectorHeader,
11
- type DocumentPaneNode,
12
- DocumentPaneProvider,
13
- useDocumentPane,
14
- } from 'sanity/structure'
15
- import {styled} from 'styled-components'
16
-
17
- import {DocumentForm} from '../_lib/form'
18
- import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
19
- import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
20
- import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
21
- import {useRequestRunInstruction} from '../assistDocument/RequestRunInstructionProvider'
22
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
23
- import {giveFeedbackUrl, pluginTitle, releaseAnnouncementUrl, salesUrl} from '../constants'
24
- import {getConditionalMembers} from '../helpers/conditionalMembers'
25
- import {assistDocumentId} from '../helpers/ids'
26
- import {InspectorOnboarding} from '../onboarding/InspectorOnboarding'
27
- import {assistDocumentTypeName, fieldPathParam, instructionParam} from '../types'
28
- import {FieldTitle} from './FieldAutocomplete'
29
- import {
30
- type FieldRef,
31
- getFieldTitle,
32
- useAiPaneRouter,
33
- useSelectedField,
34
- useTypePath,
35
- } from './helpers'
36
- import {InstructionTaskHistoryButton} from './InstructionTaskHistoryButton'
37
- import {inspectorOnboardingKey, useOnboardingFeature} from '../onboarding/onboardingStore'
38
-
39
- const CardWithShadowBelow = styled(Card)`
40
- position: relative;
41
-
42
- &:after {
43
- content: '';
44
- display: block;
45
- position: absolute;
46
- left: 0;
47
- right: 0;
48
- bottom: -1px;
49
- border-bottom: 1px solid var(--card-border-color);
50
- opacity: 0.5;
51
- z-index: 100;
52
- }
53
- `
54
-
55
- const CardWithShadowAbove = styled(Card)`
56
- position: relative;
57
-
58
- &:after {
59
- content: '';
60
- display: block;
61
- position: absolute;
62
- left: 0;
63
- right: 0;
64
- top: -1px;
65
- border-top: 1px solid var(--card-border-color);
66
- opacity: 0.5;
67
- z-index: 100;
68
- }
69
- `
70
-
71
- export function AssistInspectorWrapper(props: DocumentInspectorProps) {
72
- const context = useAiAssistanceConfig()
73
-
74
- if (context.statusLoading) {
75
- return (
76
- <Flex align="center" height="fill" justify="center" padding={4} sizing="border">
77
- <Stack space={3} style={{textAlign: 'center'}}>
78
- <Spinner muted />
79
- <Text muted size={1}>
80
- Loading {pluginTitle}...
81
- </Text>
82
- </Stack>
83
- </Flex>
84
- )
85
- }
86
-
87
- const status = context.status
88
-
89
- if (!status?.enabled) {
90
- return (
91
- <Flex direction="column" height="fill">
92
- <DocumentInspectorHeader
93
- closeButtonLabel="Close"
94
- onClose={props.onClose}
95
- title={pluginTitle}
96
- />
97
-
98
- <Stack flex={1} overflow="auto" padding={4} space={3}>
99
- <Text as="p" size={1} weight="semibold">
100
- {pluginTitle} is not available
101
- </Text>
102
-
103
- <Text as="p" muted size={1}>
104
- Please get in touch with a Sanity account manager or{' '}
105
- <a href={salesUrl} target="_blank" rel="noreferrer">
106
- contact our sales team
107
- </a>{' '}
108
- to get started with {pluginTitle}.{' '}
109
- <a href={releaseAnnouncementUrl} target="_blank" rel="noreferrer">
110
- Learn more &rarr;
111
- </a>
112
- </Text>
113
- </Stack>
114
- </Flex>
115
- )
116
- }
117
-
118
- if (!status?.initialized || !status.validToken) {
119
- return (
120
- <Flex direction="column" height="fill">
121
- <DocumentInspectorHeader
122
- closeButtonLabel="Close"
123
- onClose={props.onClose}
124
- title={pluginTitle}
125
- />
126
-
127
- <Stack padding={4} space={3}>
128
- {context.error ? (
129
- <Text size={1} weight="semibold">
130
- Failed to start {pluginTitle}
131
- </Text>
132
- ) : null}
133
-
134
- {!context.error && !status?.initialized ? (
135
- <Text size={1} weight="semibold">
136
- {pluginTitle} is not enabled
137
- </Text>
138
- ) : null}
139
-
140
- {!context.error && status?.initialized && !status.validToken ? (
141
- <>
142
- <Text size={1} weight="semibold">
143
- Invalid token
144
- </Text>
145
- <Text muted size={1}>
146
- The token used by the AI Assistant is not valid and has to be regenerated.
147
- </Text>
148
- </>
149
- ) : null}
150
-
151
- {context.error && (
152
- <Text muted size={1}>
153
- Something went wrong. See console for details.
154
- </Text>
155
- )}
156
-
157
- {!context.error && !status?.initialized && (
158
- <Text size={1} muted>
159
- Please enable {pluginTitle}.
160
- </Text>
161
- )}
162
-
163
- <Button
164
- fontSize={1}
165
- icon={
166
- context.initLoading ? (
167
- <Box marginTop={1}>
168
- <Spinner />
169
- </Box>
170
- ) : context.error ? (
171
- RetryIcon
172
- ) : undefined
173
- }
174
- text={
175
- context.error
176
- ? 'Retry'
177
- : status?.initialized && !status.validToken
178
- ? `Restore ${pluginTitle}`
179
- : `Enable ${pluginTitle} now`
180
- }
181
- tone="primary"
182
- onClick={context.init}
183
- disabled={context.initLoading}
184
- />
185
- </Stack>
186
- </Flex>
187
- )
188
- }
189
-
190
- return <AssistInspector {...props} />
191
- }
192
-
193
- export function AssistInspector(props: DocumentInspectorProps) {
194
- const {params} = useAiPaneRouter()
195
-
196
- const boundary = useRef<HTMLDivElement | null>(null)
197
- const pathKey = params?.[fieldPathParam]
198
- const instructionKey = params?.[instructionParam]
199
- const documentPane = useDocumentPane()
200
- const {
201
- documentId,
202
- documentType,
203
- value: docValue,
204
- schemaType,
205
- onChange: documentOnChange,
206
- formState,
207
- } = documentPane
208
-
209
- const {assistableDocumentId, documentIsAssistable} = useAssistDocumentContext()
210
-
211
- const formStateRef = useRef(formState)
212
- formStateRef.current = formState
213
-
214
- const {instructionLoading, requestRunInstruction} = useRequestRunInstruction({
215
- documentOnChange,
216
- isDocAssistable: documentIsAssistable,
217
- })
218
-
219
- const typePath = useTypePath(docValue, pathKey ?? '')
220
- const selectedField = useSelectedField(schemaType, typePath)
221
-
222
- const aiDocId = assistDocumentId(documentType)
223
-
224
- const assistDocument = useStudioAssistDocument({documentId, schemaType, initDoc: true})
225
- const assistField = assistDocument?.fields?.find((f) => f.path === typePath)
226
- const instruction = assistField?.instructions?.find((i) => i._key === instructionKey)
227
- const tasks = useMemo(
228
- () =>
229
- assistDocument?.tasks?.filter((i) => !instructionKey || i.instructionKey === instructionKey),
230
- [assistDocument?.tasks, instructionKey],
231
- )
232
- const instructions = useMemo(
233
- () => assistDocument?.fields?.flatMap((f) => f.instructions ?? []),
234
- [assistDocument?.fields],
235
- )
236
-
237
- const promptValue = instruction?.prompt
238
- const isEmptyPrompt = useMemo(() => {
239
- if (!promptValue?.length) {
240
- return true
241
- }
242
- const firstBlock = promptValue[0] as any
243
- const children = firstBlock?.children
244
-
245
- return promptValue.length == 1 && children?.length === 1 && !children?.[0]?.text?.length
246
- }, [promptValue])
247
-
248
- const paneNode: DocumentPaneNode = useMemo(
249
- () => ({
250
- type: 'document',
251
- id: aiDocId,
252
- title: pluginTitle,
253
- options: {
254
- id: aiDocId,
255
- type: assistDocumentTypeName,
256
- },
257
- }),
258
- [aiDocId],
259
- )
260
-
261
- const runCurrentInstruction = useCallback(
262
- () =>
263
- instruction &&
264
- pathKey &&
265
- typePath &&
266
- requestRunInstruction({
267
- documentId: assistableDocumentId,
268
- path: pathKey,
269
- typePath,
270
- assistDocumentId: assistDocumentId(documentType),
271
- instruction,
272
- conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : [],
273
- }),
274
- [pathKey, instruction, typePath, documentType, assistableDocumentId, requestRunInstruction],
275
- )
276
-
277
- const Region = useCallback((_props: any) => {
278
- // disabled for now
279
- /* return (
280
- <ConnectToRegion
281
- {..._props}
282
- _key={`${paneKey}_${selectedField?.key || '_field'}`}
283
- style={{height: '100%', flex: 1, overflow: 'auto'}}
284
- />
285
- )*/
286
- return <div {..._props} style={{height: '100%', flex: 1, overflow: 'auto'}} />
287
- }, [])
288
-
289
- const assistTypeContext = useMemo(() => ({typePath, documentType}), [typePath, documentType])
290
-
291
- if (!documentId || !schemaType || schemaType.jsonType !== 'object') {
292
- return (
293
- <Card flex={1} padding={4}>
294
- <Text>Document not ready yet.</Text>
295
- </Card>
296
- )
297
- }
298
-
299
- return (
300
- <Flex
301
- ref={boundary}
302
- direction="column"
303
- height="fill"
304
- overflow="hidden"
305
- sizing="border"
306
- style={{lineHeight: 0}}
307
- >
308
- <AiInspectorHeader
309
- onClose={props.onClose}
310
- field={selectedField}
311
- fieldTitle={getFieldTitle(selectedField)}
312
- />
313
-
314
- <Card as={Region} flex={1} overflow="auto">
315
- <Flex direction="column" style={{minHeight: '100%'}}>
316
- <Box flex={1}>
317
- <PresenceOverlay>
318
- <Box padding={4}>
319
- {selectedField && (
320
- <AssistTypeContext.Provider value={assistTypeContext}>
321
- <VirtualizerScrollInstanceProvider
322
- scrollElement={boundary.current}
323
- containerElement={boundary}
324
- >
325
- <DocumentPaneProvider
326
- paneKey={documentPane.paneKey}
327
- index={documentPane.index}
328
- itemId="ai"
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
- }}
337
- >
338
- <DocumentForm />
339
- </DocumentPaneProvider>
340
- </VirtualizerScrollInstanceProvider>
341
- </AssistTypeContext.Provider>
342
- )}
343
- </Box>
344
- </PresenceOverlay>
345
- </Box>
346
-
347
- <Box flex="none" padding={4}>
348
- <Text muted size={1}>
349
- How is Sanity AI Assist working for you?{' '}
350
- <a
351
- href={giveFeedbackUrl}
352
- target="_blank"
353
- rel="noreferrer"
354
- style={{whiteSpace: 'nowrap'}}
355
- >
356
- Let us know <ArrowRightIcon />
357
- </a>
358
- </Text>
359
- </Box>
360
- </Flex>
361
- </Card>
362
- <CardWithShadowAbove flex="none" paddingX={4} paddingY={3} style={{justifySelf: 'flex-end'}}>
363
- <Flex gap={2} flex={1} justify="flex-end">
364
- {schemaType?.name && pathKey && instructionKey && (
365
- <Stack flex={1}>
366
- <Button
367
- mode="ghost"
368
- disabled={isEmptyPrompt || instructionLoading}
369
- fontSize={1}
370
- icon={instructionLoading ? <Spinner style={{marginTop: 3}} /> : PlayIcon}
371
- onClick={runCurrentInstruction}
372
- padding={3}
373
- text={'Run instruction'}
374
- />
375
- </Stack>
376
- )}
377
-
378
- <InstructionTaskHistoryButton
379
- documentId={assistableDocumentId}
380
- tasks={tasks}
381
- instructions={instructions}
382
- showTitles={!instructionKey}
383
- />
384
- </Flex>
385
- </CardWithShadowAbove>
386
- </Flex>
387
- )
388
- }
389
-
390
- function AiInspectorHeader(props: {fieldTitle: string; field?: FieldRef; onClose: () => void}) {
391
- const {onClose, field, fieldTitle} = props
392
- const {showOnboarding, dismissOnboarding} = useOnboardingFeature(inspectorOnboardingKey)
393
-
394
- return (
395
- <CardWithShadowBelow flex="none" padding={2}>
396
- <Flex flex={1} align="center">
397
- <Flex flex={1} padding={3} gap={2} align="center">
398
- <Flex gap={1} align="center" wrap="wrap" style={{marginTop: '-4px'}}>
399
- <Box marginTop={1}>
400
- <Text size={1} weight="semibold">
401
- AI instructions for
402
- </Text>
403
- </Box>
404
- <Card radius={2} border padding={1} marginTop={1}>
405
- {field ? (
406
- <FieldTitle field={field} />
407
- ) : (
408
- <Text size={1} weight="semibold">
409
- {fieldTitle}
410
- </Text>
411
- )}
412
- </Card>
413
- </Flex>
414
- </Flex>
415
- <Box flex="none">
416
- <Button fontSize={1} icon={CloseIcon} mode="bleed" onClick={onClose} />
417
- </Box>
418
- </Flex>
419
-
420
- {showOnboarding && <InspectorOnboarding onDismiss={dismissOnboarding} />}
421
- </CardWithShadowBelow>
422
- )
423
- }
@@ -1,146 +0,0 @@
1
- import {SearchIcon} from '@sanity/icons'
2
- import {Autocomplete, Box, Breadcrumbs, Card, Flex, Text} from '@sanity/ui'
3
- import {createElement, useCallback, useMemo} from 'react'
4
- import {ObjectSchemaType} from 'sanity'
5
-
6
- import {isType} from '../helpers/typeUtils'
7
- import {FieldRef, getDocumentFieldRef} from './helpers'
8
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
9
-
10
- interface FieldSelectorProps {
11
- id: string
12
- schemaType: ObjectSchemaType
13
- fieldPath?: string
14
- onSelect: (path: string) => void
15
- includeDocument?: boolean
16
- filter?: (field: FieldRef) => boolean
17
- }
18
-
19
- export function FieldAutocomplete(props: FieldSelectorProps) {
20
- const {id, schemaType, fieldPath, onSelect, includeDocument, filter} = props
21
-
22
- const {getFieldRefs} = useAiAssistanceConfig()
23
-
24
- const fieldRefs = useMemo(() => {
25
- const refs = getFieldRefs(schemaType.name)
26
- if (includeDocument) {
27
- return [getDocumentFieldRef(schemaType), ...refs]
28
- }
29
- return refs
30
- }, [schemaType, includeDocument, getFieldRefs])
31
-
32
- const currentField = useMemo(
33
- () => fieldRefs.find((f) => f.key === fieldPath),
34
- [fieldPath, fieldRefs],
35
- )
36
-
37
- const autocompleteOptions = useMemo(
38
- () =>
39
- fieldRefs
40
- .filter((field) => (filter ? filter(field) : true))
41
- .filter((f) => !isType(f.schemaType, 'reference'))
42
- .map((field) => ({value: field.key, field})),
43
- [fieldRefs, filter],
44
- )
45
-
46
- const renderOption = useCallback((option: {value: string; field: FieldRef}) => {
47
- const {value, field} = option
48
-
49
- if (!value) {
50
- return (
51
- <Card as="button" padding={3} radius={1}>
52
- <Text accent size={1}>
53
- {option.value}
54
- </Text>
55
- </Card>
56
- )
57
- }
58
-
59
- if (isType(field.schemaType, 'document')) {
60
- return (
61
- <Card as="button" padding={3} radius={1}>
62
- <Text size={1} weight="semibold">
63
- The entire document
64
- </Text>
65
- </Card>
66
- )
67
- }
68
-
69
- return (
70
- <Card as="button" padding={3} radius={1}>
71
- <Flex gap={3}>
72
- <Text size={1}>{createElement(field.icon)}</Text>
73
-
74
- <FieldTitle field={field} />
75
- </Flex>
76
- </Card>
77
- )
78
- }, [])
79
-
80
- const renderValue = useCallback((value: string, option?: {value: string; field: FieldRef}) => {
81
- return option?.field.title ?? value
82
- }, [])
83
-
84
- const filterOption = useCallback((query: string, option: {value: string; field: FieldRef}) => {
85
- const lQuery = query.toLowerCase()
86
- return (
87
- option?.value?.toLowerCase().includes(lQuery) ||
88
- option?.field?.title?.toLowerCase().includes(lQuery)
89
- )
90
- }, [])
91
-
92
- return (
93
- <Autocomplete
94
- fontSize={1}
95
- icon={currentField ? currentField.icon : SearchIcon}
96
- onChange={onSelect}
97
- openButton
98
- id={id}
99
- options={autocompleteOptions}
100
- placeholder="Search for a field"
101
- radius={2}
102
- renderOption={renderOption}
103
- renderValue={renderValue}
104
- value={currentField?.key}
105
- filterOption={filterOption}
106
- />
107
- )
108
- }
109
-
110
- export function FieldTitle(props: {field: FieldRef}) {
111
- const splitTitle = props.field.title.split('/')
112
- return (
113
- <Box flex="none">
114
- <Breadcrumbs
115
- style={{
116
- display: 'flex',
117
- flexWrap: 'wrap',
118
- alignItems: 'center',
119
- marginTop: '-4px',
120
- }}
121
- separator={
122
- <Box marginTop={1}>
123
- <Text muted size={1}>
124
- /
125
- </Text>
126
- </Box>
127
- }
128
- space={1}
129
- >
130
- {splitTitle.slice(0, splitTitle.length - 1).map((pt, i) => (
131
- // eslint-disable-next-line react/no-array-index-key
132
- <Box key={i} marginTop={1}>
133
- <Text muted size={1}>
134
- {pt.trim()}
135
- </Text>
136
- </Box>
137
- ))}
138
- <Box marginTop={1}>
139
- <Text size={1} weight="medium">
140
- {splitTitle[splitTitle.length - 1]}
141
- </Text>
142
- </Box>
143
- </Breadcrumbs>
144
- </Box>
145
- )
146
- }