@sanity/vision 6.13.0-next.7 → 6.13.0-next.83

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SanityVision-II_F9zA2.js","names":["() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }","[props.delay]","delay","show ? <Spinner muted size={4} /> : null","createTheme(theme)","useMemo(() => createTheme(theme), [theme])","syntaxHighlighting(createHighlight(theme))","useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])","[cmTheme, cmHighlight]","{children}: {children: ReactNode}","rem(sanity.space[3])","3","rem(sanity.space[4])","4","rem(sanity.space[5])","5","assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })","`${rem(sanity.space[3])}`","`${rem(sanity.space[4])}`","`${rem(sanity.space[5])}`","<div\n className={editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })}\n >\n {children}\n </div>","{\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n} & RefAttributes<VisionCodeMirrorHandle>","(newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }","useCallback((newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }, [])","() => ({\n resetEditorContent,\n })","[resetEditorContent]","<EditorRoot>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={initialValue}\n onChange={onChange}\n />\n </EditorRoot>","{\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>","<Flex {...props} ref={ref} className={root} />","<Card {...props} className={header} />","<Label {...props} className={styledLabel} />","<Box {...props} className={splitpaneContainer} />","<Flex {...props} direction=\"column\" className={queryRecallPaneContainer} />","<Flex\n {...props}\n direction=\"column\"\n flex={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />","<a {...props} className={queryCopyLink} />","<Box {...props} className={inputBackgroundContainer} />","<Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />","<Card {...props} className={inputContainer} />","<Flex {...props} className={resultOuterContainer} />","<Box {...props} className={resultInnerContainer} />","{\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}","<Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />","isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer","<Box {...props} className={result} />","<Flex {...props} className={resultFooter} />","<Card {...props} className={timingsCard} />","rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )","space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight","assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})","`${minHeight}`","<Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />","<Card {...props} className={downloadsCard} />","rem(space[3])","3","assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})","`${rem(space[3])}`","<Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />","<Box {...props} className={controlsContainer} />","(newValue: string) => {\n onChange(newValue)\n }","useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )","debounce(handleChangeRaw, 333)","useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])","t('params.label')","<StyledLabel muted>{t('params.label')}</StyledLabel>","paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />","props.value || defaultValue","<Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>","hasValidParams ? 'default' : 'critical'","{apiVersion: DEFAULT_API_VERSION}","[]","keyValueStore.getKey(keyValueStoreKey)","useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])","(docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n }","id","useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )","() => {\n const sub = personalQueries\n .pipe(\n startWith(defaultValue as any),\n map((data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }),\n )\n .subscribe({\n next: setValue,\n error: (err) => setError(err as Error),\n })\n\n return () => sub?.unsubscribe()\n }","[personalQueries]","(data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }","() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }","[workspaceClient, mapSharedQueries]","docs","err","sub","[...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })","queries","(a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n }","useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])","async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n }","currentUser?.id","saveError","useCallback(\n async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n },\n [currentUser, workspaceClient, keyValueStore, mapSharedQueries, value.queries],\n )","async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n }","query","authError","prev","updateError","useCallback(\n async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n },\n [workspaceClient, currentUser, keyValueStore, mapSharedQueries, value.queries],\n )","async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n }","q","useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n },\n [workspaceClient, currentUser, keyValueStore, sharedQueries, value.queries],\n )","{\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n saving,\n deleting,\n saveQueryError,\n deleteQueryError,\n error,\n }","<Stack {...props} className={fixedHeader} />","<Flex {...props} direction=\"column\" flex={1} overflow=\"hidden\" className={scrollContainer} />","<Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />","{\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}","compactMode = false","{\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }","{}","[]","async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }","queries?.some","q","savedQueryObj","err","useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])","(query: QueryConfig) => {\n setShareDialogQuery(query)\n }","useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])","async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }","useCallback(async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [deleteQuery, saveQuery, shareDialogQuery, t, toast])","async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n }","queries?.find","query","prev","useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n },\n [deleteQuery, formatDate, getStateFromUrl, queries, saveQuery, t, toast],\n )","async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","next","useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )","async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","newUrl","isDuplicate","duplicateQuery","useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )","Stack","QueryList","ScrollContainer","3","filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })","\"vision-query-recall-list\"","<FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>","queries?.filter","t('label.saved-queries')","<StyledLabel muted>{t('label.saved-queries')}</StyledLabel>","t('action.save-query')","() => void handleSave()","<Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />","<Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>","t('label.search-queries')","(event) => setSearchQuery(event.currentTarget.value)","<Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>","t('label.all')","() => setQueryFilter('all')","<Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />","queryFilter === 'all'","t('label.personal')","() => setQueryFilter('personal')","<Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />","queryFilter === 'personal'","t('label.shared')","() => setQueryFilter('shared')","<Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />","queryFilter === 'shared'","<Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>","event","<Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>","<QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>","shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )","<ScrollContainer>\n <FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>","{\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}","() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n })","() => narrowBreakpoint()","() =>\n calculatePaneSizeOptions(undefined)","() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }","[visionRootRef]","visionRootRef.current","{paneSizeOptions, isNarrowBreakpoint, rootSize}","{\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n}: VisionGuiControlsProps","t('params.error.params-invalid-json')","<Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>","<Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>","queryInProgress ? t('action.query-cancel') : t('action.query-execute')","<Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>","queryInProgress ? StopIcon : PlayIcon","listenInProgress || !hasValidParams","queryInProgress ? 'positive' : 'primary'","listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')","<Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>","!hasValidParams","listenInProgress ? 'positive' : 'default'","listenInProgress ? StopIcon : PlayIcon","<Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>","<ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>","<Box {...props} className={perspectivePopoverContent} />","<a {...props} className={perspectivePopoverLink} />","{tone}: {tone: CardTone}","<div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />","`var(--card-badge-${tone}-dot-color)`","() => setOpen((o) => !o)","(o) => !o","useCallback(() => setOpen((o) => !o), [])","() => setOpen(false)","() => [buttonRef.current, popoverRef.current]","t('settings.perspectives.title')","<Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>","t('settings.perspectives.description')","<Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>","t('label.new')","<Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>","<Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>","<Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>","SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null","t('settings.perspectives.action.docs-link')","<Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>","<PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>","<Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />","<Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>","<Popover\n content={\n <PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>","{pinnedPerspective, t}","pinnedPerspective.selectedVariant\n ? getVariantTitle(pinnedPerspective.selectedVariant)\n : pinnedPerspective.selectedVariantName","selectedVariant","selectedVariantName","hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')","[name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')","variantTitle ? `· ${variantTitle}` : undefined","(value) => typeof value !== 'undefined'","hasPinnedPerspective(pinnedPerspective)","<option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>","!hasPinnedPerspective(pinnedPerspective)","{\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps","getActiveVariant(perspective, pinnedPerspective.selectedVariantName)","() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }","useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])","[1, 4, 8, 12]","['span 1 / span 1', 'span 2 / span 2']","t('settings.dataset-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>","datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))","(ds: string) => (\n <option key={ds}>{ds}</option>\n )","<Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>","t('settings.api-version-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>","t('settings.api-version-locked-for-variant')","<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>","API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))","(version) => (\n <option key={version}>{version}</option>\n )","t('settings.other-api-version-label')","<option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>","<Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>","customApiVersion === false ? apiVersion : 'other'","<Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>","!isApiVersionLocked","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>","!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )","t('settings.perspective-label')","<Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>","<Box>\n <PerspectivePopover />\n </Box>","<Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>","SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })","<Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>","perspective || 'default'","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>","typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )","<Header paddingX={3} paddingY={2}>\n <Grid gridTemplateColumns={[1, 4, 8, 12]}>\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>","<Code {...props} className={errorCode} />","{error}: {error: ContentLakeQueryError | Error}","ErrorCode","details.line","dashLine(\n details.column,\n details.columnEnd,\n )","1","details","error.details","<ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>","`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`","t('query.error.line')","t(\n 'query.error.column',\n )","details.lineNumber","<Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>","`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`","<div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>","Stack","5","2","unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null","<ErrorCode size={1}>{error.message}</ErrorCode>","message","<QueryErrorDetails error={error} />","<Stack gap={5} marginTop={2}>\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Stack>","{children}: {children: ReactNode}","rem(space[0])","0","rem(space[2])","2","rem(space[4])","4","rem(space[4] / 2)","space[4] / 2","assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })","boolean","constant","number","property","string","family","`${rem(space[4] / 2)}`","`${codeSize.fontSize}px`","`${codeSize.lineHeight}px`","`${rem(space[0])}`","`${rem(space[2])}`","`${rem(space[4])}`","font.code.family","<div\n className={resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>","<ResultViewWrapper>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={workspaceDataset === datasetName ? DocumentEditLabel : undefined}\n />\n </ResultViewWrapper>","workspaceDataset === datasetName ? DocumentEditLabel : undefined","JSON.stringify(data)","<Code language=\"json\">{JSON.stringify(data)}</Code>","{id: props.value}","value","<LinkIcon />","<IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>","{blobUrl}: SaveButtonProps","t('result.save-result-as-csv.not-csv-encodable')","<Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Tooltip content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>","<Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />","{\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps","compactFooter = false","t('result.label')","<InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>","(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )","listenMutations.length","error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )","hasResult && <ResultView data={queryResult} datasetName={dataset} />","listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )","<Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>","<Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>","<ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>","error ? 'critical' : 'default'","Boolean(error)","compactFooter ? 'column' : ['column', 'column', 'row']","compactFooter ? {width: '100%'} : {minWidth: 0}","t('result.execution-time-label')","typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')","<Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 1 : 2","t('result.end-to-end-time-label')","typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')","<Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>","<Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 3 : 4","<TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>","<TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>","compactFooter ? 2 : 3","hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )","<ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>","compactFooter ? 'flex-start' : 'space-between'","compactFooter ? 'stretch' : undefined","<ResultOuterContainer direction=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>","{queryResult}: {queryResult: unknown}","getJsonBlobUrl(queryResult)","getCsvBlobUrl(queryResult)","<SaveJsonButton blobUrl={jsonUrl} />","<SaveCsvButton blobUrl={csvUrl} />","<>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>","releases = []","() => getLocalStorage(projectId || 'default')","localStorage.get('dataset', defaultDataset)","localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )","defaultApiVersion","localStorage.get('query', '')","localStorage.get('params', '{\\n \\n}')","localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )","() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n }","getActiveVariant(perspective, selectedVariantName)","() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION","() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion","customApiVersion ? validateApiVersion(customApiVersion) : true","() =>\n typeof storedQuery === 'string' ? storedQuery : ''","parseParams(rawParams, t)","useMemo(() => parseParams(rawParams, t), [rawParams, t])","[]","{visionRootRef}","useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])","[...releaseIds, ...defaultPerspective]","(release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled'","(release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id)","isDraftModelEnabled ? ['drafts'] : ['published']","{\n apiVersion: userApiVersion,\n }","_client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })","useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])","() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])","() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])","(options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n }","parsed","useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )","(newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n }","useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n }","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution],\n )","(newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n }","useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n }","evt","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )","(evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n }","useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n }","newPerspective","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )","(evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }","useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])","() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }","error","raw","newUrl","err","useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])","(value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n }","useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )","(data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n }","newApiVersion","newCustomApiVersion","useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )","(parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n }","useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution],\n )","(evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n }","useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )","(event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n }","valid","useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )","() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }","[handleKeyDown, handlePaste]","() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }","[cancelQuerySubscription, cancelListenerSubscription]","() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n }","() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[activeVariant]","(stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n }","() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[perspectiveStack]","(queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n }","urlQueryOpts","useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )","<VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />","activeVariant ? VARIANTS_API_VERSION : apiVersion","activeVariant ? false : customApiVersion","t('query.label')","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />","<InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>","<ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />","<VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />","<InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>","allowResize","maxSize","size","isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize","isNarrowBreakpoint ? paneSizeOptions.minSize : 100","paneSizeOptions.size","paneSizeOptions.allowResize","paneSizeOptions.maxSize","getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })","<VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>","isNarrowBreakpoint ? 'vertical' : 'horizontal'","{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }","() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)","{display: 'flex', alignItems: 'center', height: '100%'}","<div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>","<Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>","params.parsed || {}","<QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>","<QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>","<SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>","isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275","<Root\n direction=\"column\"\n height=\"fill\"\n ref={visionRootRef}\n sizing=\"border\"\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>","release","{\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}","useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])","of(configDatasets)","client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )","datasets","(result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }","(d) => d.name","(ds) => ds.name","(err) => of(err)","{apiVersion: 'v2025-06-27'}","{client: datasetsClient, datasets: props.config.datasets}","datasets","<Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>","<Suspense\n fallback={\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>","{\n datasetsPromise,\n ...props\n}: VisionProps & {datasetsPromise: ObservablePromise<string[] | Error>}","loadedDatasets instanceof Error\n ? // On error, use the clients configured dataset\n [props.client.config().dataset || 'production']\n : // Otherwise use the loaded list, obviously\n loadedDatasets","client","props.client.config()","props.config.defaultDataset || props.client.config().dataset || datasets[0]","datasets[0]","defaultDataset","<VisionGui\n key={projectId}\n {...props}\n datasets={datasets}\n projectId={projectId}\n defaultDataset={defaultDataset}\n />","{apiVersion: '1'}","{\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }","options","<VisionErrorBoundary>\n <VisionContainer client={client} config={config} />\n </VisionErrorBoundary>"],"sources":["../src/apiVersions.ts","../src/components/DelayedSpinner.tsx","../src/codemirror/extensions.ts","../src/codemirror/useCodemirrorTheme.ts","../src/codemirror/VisionCodeMirror.css.ts","../src/codemirror/VisionCodeMirror.tsx","../src/perspectives.ts","../src/util/encodeQueryString.ts","../src/util/isVisionPasteTarget.ts","../src/util/isPlainObject.ts","../src/util/localStorage.ts","../src/util/parseApiQueryString.ts","../src/util/prefixApiVersion.ts","../src/util/validateApiVersion.ts","../src/util/tryParseParams.ts","../src/components/VisionGui.css.ts","../src/components/VisionGui.styled.tsx","../src/components/ParamsEditor.tsx","../src/hooks/useSavedQueries.ts","../src/components/QueryRecall.css.ts","../src/components/QueryRecall.tsx","../src/components/usePaneSize.ts","../src/components/VisionGuiControls.tsx","../src/components/PerspectivePopover.css.ts","../src/components/PerspectivePopover.tsx","../src/components/VisionGuiHeader.tsx","../src/util/getBlobUrl.ts","../src/util/compareApiVersion.ts","../src/util/apiVersionCapabilities.ts","../src/components/QueryErrorDialog.css.ts","../src/components/QueryErrorDialog.styled.tsx","../src/components/QueryErrorDetails.tsx","../src/components/QueryErrorDialog.tsx","../src/components/ResultView.css.ts","../src/components/ResultView.tsx","../src/components/SaveResultButtons.tsx","../src/components/VisionGuiResult.tsx","../src/components/VisionGui.tsx","../src/hooks/useDatasets.ts","../src/containers/VisionContainer.tsx","../src/containers/VisionErrorBoundary.tsx","../src/SanityVision.tsx"],"sourcesContent":["export const API_VERSIONS = [\n 'v1',\n 'vX',\n 'v2021-03-25',\n 'v2021-10-21',\n 'v2022-03-07',\n 'v2025-02-19',\n `v${new Date().toISOString().split('T')[0]}`,\n]\nexport const [DEFAULT_API_VERSION] = API_VERSIONS.slice(-1)\n","import {Spinner} from '@sanity/ui'\nimport {useEffect, useState} from 'react'\n\ninterface DelayedSpinnerProps {\n delay?: number\n}\n\n// Waits for X ms before showing a spinner\nexport function DelayedSpinner(props: DelayedSpinnerProps) {\n const [show, setShow] = useState(false)\n\n useEffect(() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }, [props.delay])\n\n return show ? <Spinner muted size={4} /> : null\n}\n","import {closeBrackets} from '@codemirror/autocomplete'\nimport {defaultKeymap, history, historyKeymap} from '@codemirror/commands'\nimport {javascriptLanguage} from '@codemirror/lang-javascript'\nimport {\n bracketMatching,\n defaultHighlightStyle,\n indentOnInput,\n syntaxHighlighting,\n} from '@codemirror/language'\nimport {highlightSelectionMatches} from '@codemirror/search'\nimport {type Extension} from '@codemirror/state'\nimport {\n drawSelection,\n highlightActiveLine,\n highlightActiveLineGutter,\n highlightSpecialChars,\n keymap,\n lineNumbers,\n type KeyBinding,\n} from '@codemirror/view'\nimport {groq} from '@sanity/lezer-groq'\n\nconst sharedExtensions: Extension[] = [\n lineNumbers(),\n highlightActiveLine(),\n highlightActiveLineGutter(),\n highlightSelectionMatches(),\n highlightSpecialChars(),\n indentOnInput(),\n bracketMatching(),\n closeBrackets(),\n history(),\n drawSelection(),\n syntaxHighlighting(defaultHighlightStyle, {fallback: true}),\n keymap.of([\n // Override the default keymap for Mod-Enter to not insert a new line, we have a custom event handler for executing queries\n {key: 'Mod-Enter', run: () => true},\n\n // Add the default keymap and history keymap\n ...defaultKeymap,\n ...historyKeymap,\n ] as unknown as readonly KeyBinding[]),\n]\n\nexport const groqExtensions: Extension[] = [groq(), ...sharedExtensions]\n\nexport const paramsExtensions: Extension[] = [javascriptLanguage, ...sharedExtensions]\n","import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'\nimport {type Extension} from '@codemirror/state'\nimport {EditorView} from '@codemirror/view'\nimport {tags as t} from '@lezer/highlight'\nimport {hues} from '@sanity/color'\nimport {rem, type Theme} from '@sanity/ui'\nimport {useMemo} from 'react'\n\n// The explicit return type keeps declaration emit portable (TS2883): without it the inferred\n// type references `Extension` from @codemirror/state through a non-portable .pnpm path\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nexport function useCodemirrorTheme(theme: Theme): Extension[] {\n const cmTheme = useMemo(() => createTheme(theme), [theme])\n const cmHighlight = useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])\n\n return [cmTheme, cmHighlight]\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createTheme(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {color, fonts} = theme.sanity\n const card = color.card.enabled\n const cursor = hues.blue[color.dark ? 400 : 500].hex\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const selection = hues.gray[theme.sanity.color.dark ? 900 : 100].hex\n\n return EditorView.theme(\n {\n '&': {\n color: card.fg,\n backgroundColor: card.bg,\n },\n\n '.cm-content': {\n caretColor: cursor,\n },\n\n '.cm-editor': {\n fontFamily: fonts.code.family,\n fontSize: rem(fonts.code.sizes[1].fontSize),\n lineHeight: 'inherit',\n },\n\n '.cm-cursor, .cm-dropCursor': {borderLeftColor: cursor},\n '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {\n backgroundColor: selection,\n },\n\n '.cm-panels': {backgroundColor: card.bg, color: card.fg},\n '.cm-panels.cm-panels-top': {borderBottom: `2px solid ${card.border}`},\n '.cm-panels.cm-panels-bottom': {borderTop: `2px solid ${card.border}`},\n },\n {dark: color.dark},\n )\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createHighlight(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const c = theme.sanity.color.base\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const s = theme.sanity.color.syntax\n return HighlightStyle.define([\n {tag: t.keyword, color: s.keyword},\n {tag: [t.propertyName, t.name, t.deleted, t.character, t.macroName], color: s.property},\n {tag: [t.function(t.variableName), t.labelName], color: s.function},\n {tag: [t.color, t.constant(t.name), t.standard(t.name)], color: s.variable},\n {tag: [t.definition(t.name), t.separator], color: s.constant},\n {\n tag: [\n t.typeName,\n t.className,\n t.number,\n t.changed,\n t.annotation,\n t.modifier,\n t.self,\n t.namespace,\n ],\n color: s.number,\n },\n {\n tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],\n color: s.operator,\n },\n {tag: [t.meta, t.comment], color: s.comment},\n {tag: t.strong, fontWeight: 'bold'},\n {tag: t.emphasis, fontStyle: 'italic'},\n {tag: t.strikethrough, textDecoration: 'line-through'},\n {tag: t.heading, fontWeight: 'bold', color: s.property},\n {tag: [t.atom, t.bool, t.special(t.variableName)], color: s.boolean},\n {tag: [t.processingInstruction, t.string, t.inserted], color: s.string},\n {tag: t.invalid, color: c.fg},\n ])\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const linePaddingLeftVar = createVar()\nexport const contentBorderRightWidthVar = createVar()\nexport const contentPaddingTopVar = createVar()\n\nexport const editorRoot = style({\n width: '100%',\n boxSizing: 'border-box',\n height: '100%',\n overflow: ['hidden', 'clip'],\n position: 'relative',\n display: 'flex',\n})\n\nglobalStyle(`${editorRoot} .cm-theme`, {\n width: '100%',\n})\n\nglobalStyle(`${editorRoot} .cm-editor`, {\n height: '100%',\n fontSize: '16px',\n lineHeight: '21px',\n})\n\nglobalStyle(`${editorRoot} .cm-line`, {\n paddingLeft: linePaddingLeftVar,\n})\n\nglobalStyle(`${editorRoot} .cm-content`, {\n borderRightWidth: `${contentBorderRightWidthVar} !important`,\n paddingTop: contentPaddingTopVar,\n})\n","import {type Extension} from '@codemirror/state'\nimport {rem, useTheme} from '@sanity/ui'\nimport CodeMirror, {\n EditorSelection,\n type ReactCodeMirrorProps,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {\n type ReactNode,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n type RefAttributes,\n} from 'react'\n\nimport {useCodemirrorTheme} from './useCodemirrorTheme'\nimport {\n contentBorderRightWidthVar,\n contentPaddingTopVar,\n editorRoot,\n linePaddingLeftVar,\n} from './VisionCodeMirror.css'\n\nfunction EditorRoot({children}: {children: ReactNode}) {\n const {sanity} = useTheme()\n\n return (\n <div\n className={editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })}\n >\n {children}\n </div>\n )\n}\n\nexport interface VisionCodeMirrorHandle {\n resetEditorContent: (newContent: string) => void\n}\n\nexport function VisionCodeMirror({\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n} & RefAttributes<VisionCodeMirrorHandle>) {\n // The value prop is only passed for initial value, and is not updated when the parent component updates the value.\n // If you need to update the value, use the resetEditorContent function.\n const [initialValue] = useState(initialValueProp)\n const sanityTheme = useTheme()\n const theme = useCodemirrorTheme(sanityTheme)\n const codeMirrorRef = useRef<ReactCodeMirrorRef>(null)\n\n const resetEditorContent = useCallback((newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }, [])\n\n useImperativeHandle(\n ref,\n () => ({\n resetEditorContent,\n }),\n [resetEditorContent],\n )\n\n return (\n <EditorRoot>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={initialValue}\n onChange={onChange}\n />\n </EditorRoot>\n )\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {type PerspectiveContextValue, type PerspectiveStack} from 'sanity'\n\nexport const SUPPORTED_PERSPECTIVES = [\n 'pinnedRelease',\n 'scheduledDrafts',\n 'raw',\n 'published',\n 'drafts',\n] as const\n\nexport type SupportedPerspective = (typeof SUPPORTED_PERSPECTIVES)[number]\n\n/**\n * Virtual perspectives are recognised by Vision, but do not concretely reflect the names of real\n * perspectives. Virtual perspectives are transformed into real perspectives before being used to\n * interact with data.\n *\n * For example, the `pinnedRelease` virtual perspective is transformed to the real perspective\n * currently pinned in Studio, and `scheduledDrafts` is transformed to a stack of all scheduled\n * draft release IDs.\n */\nexport const VIRTUAL_PERSPECTIVES = ['pinnedRelease', 'scheduledDrafts'] as const\n\nexport type VirtualPerspective = (typeof VIRTUAL_PERSPECTIVES)[number]\n\nexport function isSupportedPerspective(p: string): p is SupportedPerspective {\n return SUPPORTED_PERSPECTIVES.includes(p as SupportedPerspective)\n}\n\nexport function isVirtualPerspective(\n maybeVirtualPerspective: unknown,\n): maybeVirtualPerspective is VirtualPerspective {\n return (\n typeof maybeVirtualPerspective === 'string' &&\n VIRTUAL_PERSPECTIVES.includes(maybeVirtualPerspective as VirtualPerspective)\n )\n}\n\nexport function hasPinnedPerspective({selectedPerspectiveName}: PerspectiveContextValue): boolean {\n return typeof selectedPerspectiveName !== 'undefined'\n}\n\nexport function getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n}: {\n visionPerspective: ClientPerspective | SupportedPerspective | undefined\n perspectiveStack: PerspectiveContextValue['perspectiveStack']\n scheduledDraftsStack?: PerspectiveStack\n}): ClientPerspective | undefined {\n if (visionPerspective === 'pinnedRelease') {\n return perspectiveStack\n }\n if (visionPerspective === 'scheduledDrafts') {\n return scheduledDraftsStack\n }\n return visionPerspective\n}\n\n/**\n * The navbar variant is only sent with Vision queries when the virtual \"Pinned release\"\n * perspective is selected. Other Vision perspectives stay local and do not attach a variant.\n */\nexport function getActiveVariant(\n visionPerspective: ClientPerspective | SupportedPerspective | undefined,\n selectedVariantName: string | undefined,\n): string | undefined {\n if (visionPerspective !== 'pinnedRelease') {\n return undefined\n }\n return selectedVariantName\n}\n","export function encodeQueryString(\n query: string,\n params: Record<string, unknown> = {},\n options: Record<string, string | string[]> = {},\n): string {\n const searchParams = new URLSearchParams()\n searchParams.set('query', query)\n\n for (const [key, value] of Object.entries(params)) {\n searchParams.set(`$${key}`, JSON.stringify(value))\n }\n\n for (const [key, value] of Object.entries(options)) {\n if (value) searchParams.set(key, `${value}`)\n }\n\n return `?${searchParams}`\n}\n","function acceptsNativePaste(node: EventTarget | undefined): boolean {\n const element = node as Partial<HTMLInputElement | HTMLTextAreaElement> | undefined\n const isTextField = element?.tagName === 'INPUT' || element?.tagName === 'TEXTAREA'\n return isTextField && element?.readOnly === false\n}\n\n/**\n * Whether a paste seen by Vision's `document` level listener was meant for Vision. The listener is\n * global, so it also observes pastes aimed at unrelated elements such as the Studio search field.\n *\n * Uses the dispatch path rather than `event.target`, because CodeMirror handles the paste and\n * re-renders the pasted line before the event reaches `document`, detaching the original target.\n */\nexport function isVisionPasteTarget(root: Node | null, event: ClipboardEvent): boolean {\n const path = event.composedPath()\n const [target] = path\n\n // A readonly field keeps focus after Copy URL but drops the paste, so Vision still claims it\n if (acceptsNativePaste(target)) {\n return false\n }\n\n // Nothing focused\n if (target === window.document || target === window.document.body) {\n return true\n }\n\n return root !== null && path.includes(root)\n}\n","export function isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n !!obj && typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]'\n )\n}\n","import {isPlainObject} from './isPlainObject'\n\nconst hasLocalStorage = supportsLocalStorage()\nconst keyPrefix = 'sanityVision:'\n\nexport interface LocalStorageish {\n get: <T>(key: string, defaultVal: T) => T\n set: <T>(key: string, value: T) => T\n merge: <T>(props: T) => T\n}\n\nexport function clearLocalStorage() {\n if (!hasLocalStorage) {\n return\n }\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(keyPrefix)) {\n localStorage.removeItem(key)\n }\n }\n}\n\nexport function getLocalStorage(namespace: string): LocalStorageish {\n const storageKey = `${keyPrefix}${namespace}`\n let loadedState: Record<string, unknown> | null = null\n\n return {get, set, merge}\n\n function get<T>(key: string, defaultVal: T): T {\n const state = ensureState()\n return typeof state[key] === 'undefined' ? defaultVal : (state[key] as T)\n }\n\n function set<T>(key: string, value: T): T {\n const state = ensureState()\n state[key] = value\n localStorage.setItem(storageKey, JSON.stringify(loadedState))\n return value\n }\n\n function merge<T>(props: T): T {\n const state = {...ensureState(), ...props}\n localStorage.setItem(storageKey, JSON.stringify(state))\n return state\n }\n\n function ensureState(): Record<string, unknown> {\n if (loadedState === null) {\n loadedState = loadState()\n }\n\n return loadedState\n }\n\n function loadState() {\n if (!hasLocalStorage) {\n return {}\n }\n\n try {\n const stored = JSON.parse(localStorage.getItem(storageKey) || '{}')\n return isPlainObject(stored) ? stored : {}\n } catch {\n return {}\n }\n }\n}\n\nfunction supportsLocalStorage() {\n const mod = 'lsCheck'\n try {\n localStorage.setItem(mod, mod)\n localStorage.removeItem(mod)\n return true\n } catch {\n return false\n }\n}\n","export interface ParsedApiQueryString {\n query: string\n params: Record<string, unknown>\n options: Record<string, string>\n}\n\nexport function parseApiQueryString(qs: URLSearchParams): ParsedApiQueryString {\n const params: Record<string, unknown> = {}\n const options: Record<string, string> = {}\n\n for (const [key, value] of qs.entries()) {\n if (key[0] === '$') {\n params[key.slice(1)] = JSON.parse(value)\n continue\n }\n\n if (key === 'perspective') {\n options[key] = value\n continue\n }\n }\n\n return {query: qs.get('query') || '', params, options}\n}\n","export function prefixApiVersion(version: string): string {\n if (version[0] !== 'v' && version !== 'other') {\n return `v${version}`\n }\n\n return version\n}\n","export function validateApiVersion(apiVersion: string): boolean {\n const parseableApiVersion = apiVersion.replace(/^v/, '').trim().toUpperCase()\n\n const isValidApiVersion =\n parseableApiVersion.length > 0 &&\n (parseableApiVersion === 'X' ||\n parseableApiVersion === '1' ||\n (/^\\d{4}-\\d{2}-\\d{2}$/.test(parseableApiVersion) && !isNaN(Date.parse(parseableApiVersion))))\n\n return isValidApiVersion\n}\n","import JSON5 from 'json5'\nimport {type TFunction} from 'sanity'\n\nexport function tryParseParams(\n val: string,\n t: TFunction<'vision'>,\n): Record<string, unknown> | Error {\n try {\n const parsed = val ? JSON5.parse(val) : {}\n return typeof parsed === 'object' && parsed && !Array.isArray(parsed) ? parsed : {}\n } catch (err) {\n // JSON5 always prefixes the error message with JSON5:, so we remove it\n // to clean up the error tooltip\n err.message = `${t('params.error.params-invalid-json')}:\\n\\n${err.message.replace(\n 'JSON5:',\n '',\n )}`\n return err\n }\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const root = style({})\n\nglobalStyle(`${root} .sidebarPanes .Pane`, {\n overflowY: 'auto',\n overflowX: 'hidden',\n})\n\nexport const queryRecallPaneContainer = style({\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n})\n\nexport const queryRecallPaneWrapper = style({\n minHeight: 0,\n})\n\nglobalStyle(`${root} .Resizer`, {\n background: 'var(--card-border-color)',\n opacity: 1,\n zIndex: 1,\n boxSizing: 'border-box',\n backgroundClip: 'padding-box',\n border: 'solid transparent',\n})\n\nglobalStyle(`${root} .Resizer:hover`, {\n borderColor: 'var(--card-shadow-ambient-color)',\n})\n\nglobalStyle(`${root} .Resizer.horizontal`, {\n height: '11px',\n margin: '-5px 0',\n borderWidth: '5px 0',\n cursor: 'row-resize',\n width: '100%',\n zIndex: 4,\n})\n\nglobalStyle(`${root} .Resizer.vertical`, {\n width: '11px',\n margin: '0 -5px',\n borderWidth: '0 5px',\n cursor: 'col-resize',\n zIndex: 2 /* To prevent the resizer from being hidden behind CodeMirror scroll area */,\n})\n\nglobalStyle(`${root} .Resizer.disabled`, {\n cursor: 'not-allowed',\n})\n\nglobalStyle(`${root} .Resizer.disabled:hover`, {\n borderColor: 'transparent',\n})\n\nexport const header = style({\n position: 'relative',\n flexShrink: 0,\n zIndex: 6,\n overflow: 'visible',\n borderBottom: '1px solid var(--card-border-color)',\n selectors: {\n // Override the background-color @sanity/ui's Card sets on itself\n '&&': {\n background: 'var(--card-bg-color)',\n },\n },\n})\n\nexport const styledLabel = style({\n flex: 1,\n})\n\nexport const splitpaneContainer = style({\n position: 'relative',\n minHeight: 0,\n zIndex: 1,\n})\n\nexport const queryCopyLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const inputBackgroundContainer = style({\n position: 'absolute',\n top: '1rem',\n left: 0,\n padding: 0,\n margin: 0,\n zIndex: 10,\n right: 0,\n})\n\nglobalStyle(`${inputBackgroundContainer} ${styledLabel}`, {\n userSelect: 'none',\n})\n\nexport const inputBackgroundContainerLeft = style({\n // This is so its aligned with the gutters of CodeMirror\n left: '33px',\n})\n\nexport const inputContainer = style({\n width: '100%',\n height: '100%',\n position: 'relative',\n flexDirection: 'column',\n})\n\nexport const resultOuterContainer = style({\n height: '100%',\n})\n\nexport const resultInnerContainer = style({\n position: 'relative',\n})\n\nexport const resultContainer = style({\n height: '100%',\n width: '100%',\n position: 'absolute',\n maxWidth: '100%',\n})\n\nexport const resultContainerInvalid = style({\n selectors: {\n '&&::after': {\n backgroundColor: 'var(--card-bg-color)',\n content: '\"\"',\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '100%',\n },\n },\n})\n\nexport const result = style({\n position: 'relative',\n width: '100%',\n height: '100%',\n zIndex: 20,\n})\n\nexport const resultFooter = style({\n borderTop: '1px solid var(--card-border-color)',\n flexWrap: 'wrap',\n})\n\nexport const timingsCard = style({\n position: 'relative',\n})\n\nexport const timingsTextMinHeightVar = createVar()\n\nexport const timingsTextContainer = style({\n height: '100%',\n minHeight: timingsTextMinHeightVar,\n})\n\nexport const downloadsCard = style({\n position: 'relative',\n})\n\nexport const saveResultSpanGapVar = createVar()\n\nexport const saveResultLabel = style({\n selectors: {\n // Override the transform/pseudo-elements @sanity/ui's Text applies for baseline trimming\n '&&': {\n transform: 'initial',\n },\n '&&::before': {\n content: 'none',\n },\n '&&::after': {\n content: 'none',\n },\n },\n})\n\nglobalStyle(`${saveResultLabel} > span`, {\n display: 'flex !important',\n flexWrap: 'wrap',\n gap: saveResultSpanGapVar,\n alignItems: 'center',\n})\n\nexport const controlsContainer = style({\n borderTop: '1px solid var(--card-border-color)',\n})\n","import {Card, Flex, Label, rem, Text, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {type ComponentProps, type ComponentPropsWithoutRef, type RefAttributes} from 'react'\nimport {Box} from 'ui5'\n\nimport {\n controlsContainer,\n downloadsCard,\n header,\n inputBackgroundContainer,\n inputBackgroundContainerLeft,\n inputContainer,\n queryCopyLink,\n queryRecallPaneContainer,\n queryRecallPaneWrapper,\n result,\n resultContainer,\n resultContainerInvalid,\n resultFooter,\n resultInnerContainer,\n resultOuterContainer,\n root,\n saveResultLabel,\n saveResultSpanGapVar,\n splitpaneContainer,\n styledLabel,\n timingsCard,\n timingsTextContainer,\n timingsTextMinHeightVar,\n} from './VisionGui.css'\n\nexport function Root({\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>) {\n return <Flex {...props} ref={ref} className={root} />\n}\n\nexport function Header(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={header} />\n}\n\nexport function StyledLabel(props: ComponentProps<typeof Label>) {\n return <Label {...props} className={styledLabel} />\n}\n\nexport function SplitpaneContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={splitpaneContainer} />\n}\n\nexport function QueryRecallPaneContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} direction=\"column\" className={queryRecallPaneContainer} />\n}\n\nexport function QueryRecallPaneWrapper(props: ComponentProps<typeof Flex>) {\n return (\n <Flex\n {...props}\n direction=\"column\"\n flex={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />\n )\n}\n\nexport function QueryCopyLink(props: ComponentProps<'a'>) {\n return <a {...props} className={queryCopyLink} />\n}\n\nexport function InputBackgroundContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={inputBackgroundContainer} />\n}\n\nexport function InputBackgroundContainerLeft(props: ComponentProps<typeof Box>) {\n return (\n <Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />\n )\n}\n\nexport function InputContainer(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={inputContainer} />\n}\n\nexport function ResultOuterContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultOuterContainer} />\n}\n\nexport function ResultInnerContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={resultInnerContainer} />\n}\n\nexport function ResultContainer({\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}) {\n return (\n <Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />\n )\n}\n\nexport function Result(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={result} />\n}\n\nexport function ResultFooter(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultFooter} />\n}\n\nexport function TimingsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={timingsCard} />\n}\n\nexport function TimingsTextContainer(props: ComponentProps<typeof Flex>) {\n const {space, font} = useThemeV2()\n const textSize = font.text.sizes[2]\n const minHeight = rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )\n\n return (\n <Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />\n )\n}\n\nexport function DownloadsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={downloadsCard} />\n}\n\nexport function SaveResultLabel(props: ComponentProps<typeof Text>) {\n const {space} = useThemeV2()\n\n return (\n <Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />\n )\n}\n\nexport function ControlsContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={controlsContainer} />\n}\n","import {ErrorOutlineIcon} from '@sanity/icons/ErrorOutline'\nimport {Card, Flex, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport debounce from 'lodash-es/debounce.js'\nimport {type RefObject, useCallback, useMemo} from 'react'\nimport {type TFunction, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {paramsExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {tryParseParams} from '../util/tryParseParams'\nimport {type Params} from './VisionGui'\nimport {InputBackgroundContainerLeft, StyledLabel} from './VisionGui.styled'\n\nconst defaultValue = `{\\n \\n}`\n\nexport interface ParamsEditorProps {\n value: string\n onChange: (changeEvt: string) => void\n paramsError: string | undefined\n hasValidParams: boolean\n editorRef: RefObject<VisionCodeMirrorHandle | null>\n}\n\nexport function ParamsEditor(props: ParamsEditorProps) {\n const {onChange, paramsError, hasValidParams, editorRef} = props\n const {t} = useTranslation(visionLocaleNamespace)\n\n const handleChangeRaw = useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )\n\n const handleChange = useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])\n return (\n <Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>\n )\n}\n\nexport function parseParams(value: string, t: TFunction<typeof visionLocaleNamespace>): Params {\n const parsedParams = tryParseParams(value, t)\n const params = parsedParams instanceof Error ? {} : parsedParams\n const validationError = parsedParams instanceof Error ? parsedParams.message : undefined\n const isValid = !validationError\n\n return {\n parsed: params,\n raw: value,\n valid: isValid,\n error: validationError,\n }\n}\n","import {type ListenOptions} from '@sanity/client'\nimport {uuid} from '@sanity/uuid' // Import the UUID library\nimport {useCallback, useEffect, useMemo, useState} from 'react'\nimport {map, startWith} from 'rxjs/operators'\nimport {type KeyValueStoreValue, useClient, useCurrentUser, useKeyValueStore} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from '../apiVersions'\n\nconst STORED_QUERIES_NAMESPACE = 'studio.vision-tool.saved-queries'\nconst SHARED_QUERY_DOCUMENT_TYPE = 'vision.sharedQuery'\nconst SHARED_QUERIES_QUERY = `*[_type == $sharedQueryType]{\n _id,\n authorId,\n savedAt,\n title,\n url\n} | order(savedAt desc)`\nconst SHARED_QUERY_LISTEN_OPTIONS: ListenOptions = {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: true,\n visibility: 'query',\n}\n\nexport interface QueryConfig {\n _key: string\n url: string\n savedAt: string\n title?: string\n shared?: boolean\n authorId?: string\n isOwnedByCurrentUser?: boolean\n}\n\nexport interface StoredQueries {\n queries: QueryConfig[]\n}\n\nconst defaultValue = {\n queries: [],\n}\nconst keyValueStoreKey = STORED_QUERIES_NAMESPACE\n\ninterface SharedQueryDocument {\n _id: string\n _type?: string\n authorId: string\n savedAt: string\n title?: string\n url: string\n}\n\nexport function useSavedQueries(): {\n queries: QueryConfig[]\n saveQuery: (query: Omit<QueryConfig, '_key'>) => Promise<void>\n updateQuery: (query: QueryConfig) => Promise<void>\n deleteQuery: (key: string) => Promise<void>\n saving: boolean\n deleting: string[]\n saveQueryError: Error | undefined\n deleteQueryError: Error | undefined\n error: Error | undefined\n} {\n const keyValueStore = useKeyValueStore()\n const workspaceClient = useClient({apiVersion: DEFAULT_API_VERSION})\n const currentUser = useCurrentUser()\n\n const [value, setValue] = useState<StoredQueries>(defaultValue)\n const [sharedQueries, setSharedQueries] = useState<QueryConfig[]>([])\n const [saving, setSaving] = useState(false)\n const [deleting, setDeleting] = useState<string[]>([])\n const [saveQueryError, setSaveQueryError] = useState<Error | undefined>()\n const [deleteQueryError, setDeleteQueryError] = useState<Error | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const personalQueries = useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])\n\n const mapSharedQueries = useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )\n\n useEffect(() => {\n const sub = personalQueries\n .pipe(\n startWith(defaultValue as any),\n map((data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }),\n )\n .subscribe({\n next: setValue,\n error: (err) => setError(err as Error),\n })\n\n return () => sub?.unsubscribe()\n }, [personalQueries])\n\n useEffect(() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [workspaceClient, mapSharedQueries])\n\n const queries = useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])\n\n const saveQuery = useCallback(\n async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n },\n [currentUser, workspaceClient, keyValueStore, mapSharedQueries, value.queries],\n )\n\n const updateQuery = useCallback(\n async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n },\n [workspaceClient, currentUser, keyValueStore, mapSharedQueries, value.queries],\n )\n\n const deleteQuery = useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n },\n [workspaceClient, currentUser, keyValueStore, sharedQueries, value.queries],\n )\n\n return {\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n saving,\n deleting,\n saveQueryError,\n deleteQueryError,\n error,\n }\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const fixedHeader = style({\n flexShrink: 0,\n background: 'var(--card-bg-color)',\n zIndex: 1,\n})\n\nexport const scrollContainer = style({\n minHeight: 0,\n width: '100%',\n minWidth: 0,\n})\n\nexport const queryList = style({\n minHeight: 0,\n})\n","import {AddIcon} from '@sanity/icons/Add'\nimport {LockIcon} from '@sanity/icons/Lock'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {TrashIcon} from '@sanity/icons/Trash'\nimport {UnpublishIcon} from '@sanity/icons/Unpublish'\nimport {UsersIcon} from '@sanity/icons/Users'\nimport {Badge, Button, Card, Dialog, Flex, Stack, Tab, TabList, Text, TextInput} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Menu, MenuButton, MenuItem} from '@sanity/ui/menu'\nimport {useToast} from '@sanity/ui/toast'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport isEqual from 'lodash-es/isEqual.js'\nimport {type ComponentProps, type ReactElement, useCallback, useState} from 'react'\nimport {ContextMenuButton, UserAvatar, useDateTimeFormat, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {type QueryConfig, useSavedQueries} from '../hooks/useSavedQueries'\nimport {visionLocaleNamespace} from '../i18n'\nimport {fixedHeader, queryList, scrollContainer} from './QueryRecall.css'\nimport {type ParsedUrlState} from './VisionGui'\nimport {StyledLabel} from './VisionGui.styled'\n\nfunction FixedHeader(props: ComponentProps<typeof Stack>) {\n return <Stack {...props} className={fixedHeader} />\n}\n\nfunction ScrollContainer(props: ComponentProps<typeof Flex>) {\n return (\n <Flex {...props} direction=\"column\" flex={1} overflow=\"hidden\" className={scrollContainer} />\n )\n}\n\nfunction QueryList(props: ComponentProps<typeof Box>) {\n return <Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />\n}\n\nexport function QueryRecall({\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}): ReactElement {\n type QueryFilter = 'all' | 'personal' | 'shared'\n const toast = useToast()\n const {saveQuery, updateQuery, queries, deleteQuery, saving, deleting} = useSavedQueries()\n const {t} = useTranslation(visionLocaleNamespace)\n const formatDate = useDateTimeFormat({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n const [editingKey, setEditingKey] = useState<string | null>(null)\n const [editingTitle, setEditingTitle] = useState('')\n const [optimisticTitles, setOptimisticTitles] = useState<Record<string, string>>({})\n const [searchQuery, setSearchQuery] = useState('')\n const [queryFilter, setQueryFilter] = useState<QueryFilter>('all')\n const [selectedUrl, setSelectedUrl] = useState<string | undefined>(url)\n const [pendingUnshareKeys, setPendingUnshareKeys] = useState<string[]>([])\n const [shareDialogQuery, setShareDialogQuery] = useState<QueryConfig | null>(null)\n\n const handleSave = useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])\n\n const handleShareQuery = useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])\n\n const handleConfirmShareQuery = useCallback(async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [deleteQuery, saveQuery, shareDialogQuery, t, toast])\n\n const handleUnshareQuery = useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n },\n [deleteQuery, formatDate, getStateFromUrl, queries, saveQuery, t, toast],\n )\n\n const handleTitleSave = useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )\n\n const handleUpdate = useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )\n\n const visibleQueries = queries?.filter((q) => !pendingUnshareKeys.includes(q._key))\n\n const filteredQueries = visibleQueries?.filter((q) => {\n const matchesSearch = (q.title ?? '').toLowerCase().includes(searchQuery.toLowerCase())\n const matchesFilter =\n queryFilter === 'all' ||\n (queryFilter === 'personal' && !q.shared) ||\n (queryFilter === 'shared' && q.shared)\n return matchesSearch && matchesFilter\n })\n\n return (\n <ScrollContainer>\n <FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>\n )\n}\n","import {useEffect, useState} from 'react'\n\ninterface PaneSizeOptions {\n defaultSize: number\n size?: number\n allowResize: boolean\n minSize: number\n maxSize: number\n}\n\ninterface RootSize {\n width: number\n height: number\n}\nfunction narrowBreakpoint(): boolean {\n return typeof window !== 'undefined' && window.innerWidth > 600\n}\n\nfunction calculatePaneSizeOptions(height: number | undefined): PaneSizeOptions {\n let rootHeight = height\n\n if (!rootHeight) {\n // Initial root height without header\n rootHeight =\n typeof window !== 'undefined' && typeof document !== 'undefined'\n ? document.body.getBoundingClientRect().height - 60\n : 0\n }\n return {\n defaultSize: rootHeight / (narrowBreakpoint() ? 2 : 1),\n size: rootHeight > 550 ? undefined : rootHeight * 0.4,\n allowResize: rootHeight > 550,\n minSize: Math.min(170, Math.max(170, rootHeight / 2)),\n maxSize: rootHeight > 650 ? rootHeight * 0.7 : rootHeight * 0.6,\n }\n}\n\nexport function usePaneSize({\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}) {\n const [rootSize, setRootSize] = useState<RootSize>(() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n }))\n const [isNarrowBreakpoint, setIsNarrowBreakpoint] = useState(() => narrowBreakpoint())\n const [paneSizeOptions, setPaneSizeOptions] = useState<PaneSizeOptions>(() =>\n calculatePaneSizeOptions(undefined),\n )\n\n useEffect(() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [visionRootRef])\n\n return {paneSizeOptions, isNarrowBreakpoint, rootSize}\n}\n","import {PlayIcon} from '@sanity/icons/Play'\nimport {StopIcon} from '@sanity/icons/Stop'\nimport {Button, Card, Flex, Hotkeys, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ControlsContainer} from './VisionGui.styled'\n\nexport interface VisionGuiControlsProps {\n hasValidParams: boolean\n queryInProgress: boolean\n listenInProgress: boolean\n onQueryExecution: () => void\n onListenExecution: () => void\n}\n\n/**\n * Vision GUI controls\n * To handle query and listen execution.\n */\nexport function VisionGuiControls({\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n}: VisionGuiControlsProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n return (\n <ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>\n )\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const perspectivePopoverContent = style({\n /* This limits the width of the popover content */\n maxWidth: '240px',\n})\n\nexport const perspectivePopoverLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const dot = style({\n width: '4px',\n height: '4px',\n borderRadius: '3px',\n boxShadow: '0 0 0 1px var(--card-bg-color)',\n})\n","import {HelpCircleIcon} from '@sanity/icons/HelpCircle'\nimport {\n Badge,\n Button,\n Card,\n type CardTone,\n Inline,\n Stack,\n Text,\n useClickOutsideEvent,\n} from '@sanity/ui'\nimport {Popover} from '@sanity/ui/popover'\nimport {type ComponentProps, useCallback, useRef, useState} from 'react'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {dot, perspectivePopoverContent, perspectivePopoverLink} from './PerspectivePopover.css'\n\nfunction PerspectivePopoverContent(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={perspectivePopoverContent} />\n}\n\nfunction PerspectivePopoverLink(props: ComponentProps<'a'>) {\n return <a {...props} className={perspectivePopoverLink} />\n}\n\nfunction Dot({tone}: {tone: CardTone}) {\n return <div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />\n}\n\nconst SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION = false\n\nexport function PerspectivePopover() {\n const [open, setOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement | null>(null)\n const popoverRef = useRef<HTMLDivElement | null>(null)\n\n const handleClick = useCallback(() => setOpen((o) => !o), [])\n\n const {t} = useTranslation(visionLocaleNamespace)\n\n useClickOutsideEvent(\n () => setOpen(false),\n () => [buttonRef.current, popoverRef.current],\n )\n\n return (\n <Popover\n content={\n <PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>\n )\n}\n","import {CopyIcon} from '@sanity/icons/Copy'\nimport {Button, Card, Flex, Grid, Inline, Select, Stack, Text, TextInput} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {\n type ChangeEvent,\n type ComponentType,\n Fragment,\n type RefObject,\n useCallback,\n useMemo,\n useRef,\n} from 'react'\nimport {\n getVariantTitle,\n type PerspectiveContextValue,\n type TFunction,\n usePerspective,\n useTranslation,\n} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {API_VERSIONS} from '../apiVersions'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActiveVariant,\n hasPinnedPerspective,\n SUPPORTED_PERSPECTIVES,\n type SupportedPerspective,\n} from '../perspectives'\nimport {PerspectivePopover} from './PerspectivePopover'\nimport {Header, QueryCopyLink, StyledLabel} from './VisionGui.styled'\n\nconst PinnedReleasePerspectiveOption: ComponentType<{\n pinnedPerspective: PerspectiveContextValue\n t: TFunction\n}> = ({pinnedPerspective, t}) => {\n const name =\n typeof pinnedPerspective.selectedPerspective === 'object'\n ? pinnedPerspective.selectedPerspective.metadata.title\n : pinnedPerspective.selectedPerspectiveName\n\n const variantTitle = pinnedPerspective.selectedVariant\n ? getVariantTitle(pinnedPerspective.selectedVariant)\n : pinnedPerspective.selectedVariantName\n\n const label = hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')\n\n const text = useMemo(\n () =>\n [name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')\n .join(' '),\n [label, name, variantTitle],\n )\n\n return (\n <option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>\n )\n}\n\nexport interface VisionGuiHeaderProps {\n onChangeDataset: (evt: ChangeEvent<HTMLSelectElement>) => void\n dataset: string\n customApiVersion: string | false\n apiVersion: string\n onChangeApiVersion: (evt: ChangeEvent<HTMLSelectElement>) => void\n datasets: string[]\n customApiVersionElementRef: RefObject<HTMLInputElement | null>\n onCustomApiVersionChange: (evt: ChangeEvent<HTMLInputElement>) => void\n isValidApiVersion: boolean\n onChangePerspective: (evt: ChangeEvent<HTMLSelectElement>) => void\n url?: string\n perspective?: SupportedPerspective\n isScheduledDraftsEnabled: boolean\n}\n\nexport function VisionGuiHeader({\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps) {\n const pinnedPerspective = usePerspective()\n const isApiVersionLocked = Boolean(\n getActiveVariant(perspective, pinnedPerspective.selectedVariantName),\n )\n const {t} = useTranslation(visionLocaleNamespace)\n const operationUrlElement = useRef<HTMLInputElement | null>(null)\n const handleCopyUrl = useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])\n\n return (\n <Header paddingX={3} paddingY={2}>\n <Grid gridTemplateColumns={[1, 4, 8, 12]}>\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>\n )\n}\n","import {json2csv} from 'json-2-csv'\n\nfunction getBlobUrl(content: string, mimeType: string): string {\n return URL.createObjectURL(\n new Blob([content], {\n type: mimeType,\n }),\n )\n}\n\nfunction getMemoizedBlobUrlResolver(mimeType: string, stringEncoder: (input: any) => string) {\n return (() => {\n let prevResult = ''\n let prevContent = ''\n return (input: unknown) => {\n const content = stringEncoder(input)\n if (typeof content !== 'string' || content === '') {\n return undefined\n }\n\n if (content === prevContent) {\n return prevResult\n }\n\n prevContent = content\n if (prevResult) {\n URL.revokeObjectURL(prevResult)\n }\n\n prevResult = getBlobUrl(content, mimeType)\n return prevResult\n }\n })()\n}\n\nexport const getJsonBlobUrl = getMemoizedBlobUrlResolver('application/json', (input) =>\n JSON.stringify(input, null, 2),\n)\n\nexport const getCsvBlobUrl = getMemoizedBlobUrlResolver('text/csv', (input) => {\n return json2csv(Array.isArray(input) ? input : [input]).trim()\n})\n","type ParsedApiVersion =\n | {kind: 'experimental'}\n | {kind: 'legacy'}\n | {kind: 'dated'; value: string}\n | {kind: 'unknown'}\n\n/**\n * Returns true when `selected` does not satisfy `required`.\n *\n * `X` is the experimental API: it satisfies every requirement, and when it is\n * the requirement only `X` satisfies it. Dated versions compare\n * lexicographically. `v1` sits below every dated version and `X`.\n */\nexport function isApiVersionBelow(selected: string, required: string): boolean {\n const parsedSelected = parseApiVersion(selected)\n const parsedRequired = parseApiVersion(required)\n\n if (parsedSelected.kind === 'unknown' || parsedRequired.kind === 'unknown') {\n return false\n }\n\n if (parsedSelected.kind === 'experimental') {\n return false\n }\n\n if (parsedRequired.kind === 'experimental') {\n return true\n }\n\n if (parsedSelected.kind === 'legacy') {\n return parsedRequired.kind !== 'legacy'\n }\n\n if (parsedRequired.kind === 'legacy') {\n return false\n }\n\n return parsedSelected.value < parsedRequired.value\n}\n\nfunction parseApiVersion(version: string): ParsedApiVersion {\n const normalized = version.replace(/^v/i, '').trim()\n\n if (!normalized) {\n return {kind: 'unknown'}\n }\n\n if (normalized.toUpperCase() === 'X') {\n return {kind: 'experimental'}\n }\n\n if (normalized === '1') {\n return {kind: 'legacy'}\n }\n\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(normalized)) {\n return {kind: 'dated', value: normalized}\n }\n\n return {kind: 'unknown'}\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {RELEASES_STUDIO_CLIENT_OPTIONS, VARIANTS_STUDIO_CLIENT_OPTIONS} from 'sanity'\n\nimport {type VisionLocaleResourceKeys} from '../i18n/resources'\nimport {isApiVersionBelow} from './compareApiVersion'\n\nconst NAMED_PERSPECTIVES = new Set(['raw', 'published', 'drafts', 'previewDrafts'])\n\nexport interface ApiVersionCapabilityContext {\n statusCode: number | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport interface ApiVersionCapabilityRequirement {\n id: string\n requiredApiVersion: string\n explanationKey: VisionLocaleResourceKeys\n applies: (context: ApiVersionCapabilityContext) => boolean\n}\n\n/**\n * Capability floors for Vision error copy. Order is precedence: the first\n * unsatisfied entry wins.\n *\n * Variant before releases matches `variantApiVersion()` in\n * `packages/sanity/src/core/variants/util/variantApiVersion.ts` — a variant\n * requirement takes precedence over the releases version for stacked\n * perspectives.\n *\n * Add a capability by appending an entry. Do not add a branch in the error\n * dialog.\n */\nexport const API_VERSION_CAPABILITIES: readonly ApiVersionCapabilityRequirement[] = [\n {\n id: 'variants',\n // `query.error.unsupported-variant` names the experimental API; reword it if this floor becomes dated.\n requiredApiVersion: VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-variant',\n applies: ({variant}) => Boolean(variant),\n },\n {\n id: 'releases',\n // Matches any stacked perspective, including scheduled drafts and agent bundles, so the copy\n // stays generic rather than naming releases.\n requiredApiVersion: RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-release-perspective',\n applies: ({perspective}) => hasReleaseInPerspective(perspective),\n },\n]\n\nexport function hasReleaseInPerspective(perspective: ClientPerspective | undefined): boolean {\n if (!Array.isArray(perspective)) {\n return false\n }\n\n return perspective.some((entry) => !NAMED_PERSPECTIVES.has(entry))\n}\n\nexport function getUnsatisfiedApiVersionCapability(\n context: ApiVersionCapabilityContext,\n capabilities: readonly ApiVersionCapabilityRequirement[] = API_VERSION_CAPABILITIES,\n): ApiVersionCapabilityRequirement | undefined {\n if (context.statusCode !== 400) {\n return undefined\n }\n\n return capabilities.find(\n (capability) =>\n capability.applies(context) &&\n isApiVersionBelow(context.apiVersion, capability.requiredApiVersion),\n )\n}\n","import {style} from '@vanilla-extract/css'\n\n// `ErrorCode` always renders inside a critical-tone `Card`, so the card sets\n// `--card-muted-fg-color` to the muted critical foreground color we want here.\n// `&&` is needed to override the color @sanity/ui's Code sets on itself.\nexport const errorCode = style({\n selectors: {\n '&&': {\n color: 'var(--card-muted-fg-color)',\n },\n },\n})\n","import {Code} from '@sanity/ui/code'\nimport {type ComponentProps} from 'react'\n\nimport {errorCode} from './QueryErrorDialog.css'\n\nexport function ErrorCode(props: ComponentProps<typeof Code>) {\n return <Code {...props} className={errorCode} />\n}\n","import {useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface ContentLakeQueryError {\n details: {\n query: string\n start: number\n end: number\n\n lineNumber?: number\n column?: number\n }\n}\n\nexport function QueryErrorDetails({error}: {error: ContentLakeQueryError | Error}) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n if (!('details' in error)) {\n return null\n }\n\n const details = {...error.details, ...mapToLegacyDetails(error.details)}\n if (!details.line) {\n return null\n }\n\n return (\n <div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>\n )\n}\n\nfunction mapToLegacyDetails(details: ContentLakeQueryError['details']) {\n if (!details || typeof details.query !== 'string' || typeof details.start !== 'number') {\n return {}\n }\n\n const {query, start, end} = details\n const lineStart = query.slice(0, start).lastIndexOf('\\n') + 1\n const lineNumber = (query.slice(0, lineStart).match(/\\n/g) || []).length\n const line = query.slice(lineStart, query.indexOf('\\n', lineStart))\n const column = start - lineStart\n const columnEnd = typeof end === 'number' ? end - lineStart : undefined\n\n return {line, lineNumber, column, columnEnd}\n}\n\nfunction dashLine(column: number, columnEnd: number | undefined): string {\n const line = '-'.repeat(column)\n const hats = `^`.repeat(columnEnd ? columnEnd - column : 1)\n return `${line}${hats}`\n}\n","import {type ClientPerspective, isHttpError} from '@sanity/client'\nimport {Stack, Text} from '@sanity/ui'\nimport {useTranslation} from 'sanity'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getUnsatisfiedApiVersionCapability} from '../util/apiVersionCapabilities'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {QueryErrorDetails} from './QueryErrorDetails'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface QueryErrorDialogProps {\n error: Error\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport function QueryErrorDialog(props: QueryErrorDialogProps) {\n const {error, apiVersion, perspective, variant} = props\n const {t} = useTranslation(visionLocaleNamespace)\n const unsatisfiedCapability = getUnsatisfiedApiVersionCapability({\n statusCode: isHttpError(error) ? error.statusCode : undefined,\n apiVersion,\n perspective,\n variant,\n })\n\n return (\n <Stack gap={5} marginTop={2}>\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Stack>\n )\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const codeFamilyVar = createVar()\nexport const codeFontSizeVar = createVar()\nexport const codeLineHeightVar = createVar()\nexport const space0Var = createVar()\nexport const space2Var = createVar()\nexport const space4Var = createVar()\nexport const space4HalfVar = createVar()\nexport const syntaxPropertyVar = createVar()\nexport const syntaxConstantVar = createVar()\nexport const syntaxStringVar = createVar()\nexport const syntaxBooleanVar = createVar()\nexport const syntaxNumberVar = createVar()\n\nexport const resultViewWrapper = style({})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector, ${resultViewWrapper} .json-inspector .json-inspector__selection`,\n {\n fontFamily: codeFamilyVar,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n color: 'var(--card-code-fg-color)',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__leaf`, {\n paddingLeft: space4Var,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf.json-inspector__leaf_root`,\n {\n paddingTop: space0Var,\n paddingLeft: 0,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line`, {\n display: 'block',\n position: 'relative',\n cursor: 'default',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line::after`, {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: '-200px',\n right: '-50px',\n bottom: 0,\n zIndex: -1,\n pointerEvents: 'none',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line:hover::after`, {\n background: 'var(--card-code-bg-color)',\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line`,\n {\n cursor: 'pointer',\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▸ '\",\n marginLeft: `calc(0px - ${space4Var})`,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_expanded.json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▾ '\",\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__radio, ${resultViewWrapper} .json-inspector .json-inspector__flatpath`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value`, {\n marginLeft: space4HalfVar,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key + .json-inspector__value`,\n {\n margin: 0,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__key`, {\n color: syntaxPropertyVar,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__value_helper, ${resultViewWrapper} .json-inspector .json-inspector__value_null`,\n {\n color: syntaxConstantVar,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__not-found`, {\n paddingTop: space2Var,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_string`, {\n color: syntaxStringVar,\n wordBreak: 'break-word',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_boolean`, {\n color: syntaxBooleanVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_number`, {\n color: syntaxNumberVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original`, {\n display: 'inline-block',\n padding: '0 6px',\n cursor: 'pointer',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover`, {\n color: 'inherit',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original::before`, {\n content: \"'↔'\",\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover::after`, {\n content: \"' expand'\",\n})\n","import {JsonInspector} from '@rexxars/react-json-inspector'\nimport {LinkIcon} from '@sanity/icons/Link'\nimport {rem, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport LRU from 'quick-lru'\nimport {type ReactNode} from 'react'\nimport {useDataset} from 'sanity'\nimport {IntentLink} from 'sanity/router'\n\nimport {\n codeFamilyVar,\n codeFontSizeVar,\n codeLineHeightVar,\n resultViewWrapper,\n space0Var,\n space2Var,\n space4HalfVar,\n space4Var,\n syntaxBooleanVar,\n syntaxConstantVar,\n syntaxNumberVar,\n syntaxPropertyVar,\n syntaxStringVar,\n} from './ResultView.css'\n\nconst lru = new LRU({maxSize: 50000})\n\nfunction ResultViewWrapper({children}: {children: ReactNode}) {\n const {color, font, space} = useThemeV2()\n const codeSize = font.code.sizes[2]\n\n return (\n <div\n className={resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>\n )\n}\n\nexport function ResultView(props: {data: unknown; datasetName: string}): React.JSX.Element {\n const {data, datasetName} = props\n const workspaceDataset = useDataset()\n\n if (isRecord(data) || Array.isArray(data)) {\n return (\n <ResultViewWrapper>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={workspaceDataset === datasetName ? DocumentEditLabel : undefined}\n />\n </ResultViewWrapper>\n )\n }\n\n return <Code language=\"json\">{JSON.stringify(data)}</Code>\n}\n\nfunction DocumentEditLabel(props: {value: string; isKey: boolean; keypath: string}) {\n if (props.isKey || (!props.keypath.endsWith('_id') && !props.keypath.endsWith('_ref'))) {\n return null\n }\n\n return (\n <IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>\n )\n}\n\nfunction isExpanded(keyPath: string, value: unknown): boolean {\n const depthLimit = 4\n const cached = lru.get(keyPath) as boolean | undefined\n\n if (typeof cached === 'boolean') {\n return cached\n }\n\n const segments = keyPath.split('.', depthLimit)\n if (segments.length === depthLimit) {\n return false\n }\n\n if (Array.isArray(value)) {\n return true\n }\n\n return isRecord(value) && !segments.some((key) => isArrayKeyOverLimit(key))\n}\n\nfunction toggleExpanded(event: {path: string}): void {\n const {path} = event\n const current = lru.get(path)\n\n if (current === undefined) {\n // something is wrong\n return\n }\n\n lru.set(path, !current)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst numeric = /^\\d+$/\nfunction isArrayKeyOverLimit(segment: string, limit = 10) {\n return numeric.test(segment) && parseInt(segment, 10) > limit\n}\n","import {DocumentSheetIcon} from '@sanity/icons/DocumentSheet'\nimport {Button} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\n\nimport {visionLocaleNamespace} from '../i18n'\n\ninterface SaveButtonProps {\n blobUrl: string | undefined\n}\n\nexport function SaveCsvButton({blobUrl}: SaveButtonProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n // An anchor cannot be disabled, so when there is nothing to download we render a plain\n // disabled button (which also prevents the click natively) instead of a disabled link.\n if (!blobUrl) {\n return (\n <Tooltip content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>\n )\n }\n\n return (\n <Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n\nexport function SaveJsonButton({blobUrl}: SaveButtonProps) {\n return (\n <Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n","import {type ClientPerspective, type MutationEvent} from '@sanity/client'\nimport {Text} from '@sanity/ui'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getCsvBlobUrl, getJsonBlobUrl} from '../util/getBlobUrl'\nimport {DelayedSpinner} from './DelayedSpinner'\nimport {QueryErrorDialog} from './QueryErrorDialog'\nimport {ResultView} from './ResultView'\nimport {SaveCsvButton, SaveJsonButton} from './SaveResultButtons'\nimport {\n DownloadsCard,\n InputBackgroundContainer,\n Result,\n ResultContainer,\n ResultFooter,\n ResultInnerContainer,\n ResultOuterContainer,\n SaveResultLabel,\n StyledLabel,\n TimingsCard,\n TimingsTextContainer,\n} from './VisionGui.styled'\n\ninterface VisionGuiResultProps {\n error?: Error | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n queryInProgress: boolean\n queryResult?: unknown | undefined\n listenInProgress: boolean\n listenMutations: MutationEvent[]\n dataset: string\n queryTime: number | undefined\n e2eTime: number | undefined\n compactFooter?: boolean\n}\n\nexport function VisionGuiResult({\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n const hasResult = !error && !queryInProgress && typeof queryResult !== 'undefined'\n\n return (\n <ResultOuterContainer direction=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>\n )\n}\n\nfunction SaveResultButtons({queryResult}: {queryResult: unknown}) {\n // This only renders when `hasResult` is true, and falsy values like `null`, `0`, `false` or ''\n // are valid GROQ results — the resolvers themselves return `undefined` for non-encodable input.\n const jsonUrl = getJsonBlobUrl(queryResult)\n const csvUrl = getCsvBlobUrl(queryResult)\n\n return (\n <>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>\n )\n}\n","import {SplitPane} from '@rexxars/react-split-pane'\nimport {\n type ClientPerspective,\n type ListenEvent,\n type MutationEvent,\n type ReleaseDocument,\n type StackablePerspective,\n} from '@sanity/client'\nimport {ChevronLeftIcon} from '@sanity/icons/ChevronLeft'\nimport {ChevronRightIcon} from '@sanity/icons/ChevronRight'\nimport {Button, Flex} from '@sanity/ui'\nimport {useToast} from '@sanity/ui/toast'\nimport {isHotkey} from 'is-hotkey-esm'\nimport {type ChangeEvent, useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {\n getReleaseIdFromReleaseDocumentId,\n isCardinalityOneRelease,\n type PerspectiveStack,\n sortReleases,\n useActiveReleases,\n useClient,\n usePerspective,\n useScheduledDraftsEnabled,\n useTranslation,\n useWorkspace,\n VARIANTS_STUDIO_CLIENT_OPTIONS,\n} from 'sanity'\nimport {Box} from 'ui5'\nimport {useEffectEvent} from 'use-effect-event'\n\nimport {API_VERSIONS, DEFAULT_API_VERSION} from '../apiVersions'\nimport {groqExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActivePerspective,\n getActiveVariant,\n isSupportedPerspective,\n isVirtualPerspective,\n type SupportedPerspective,\n} from '../perspectives'\nimport {type VisionProps} from '../types'\nimport {encodeQueryString} from '../util/encodeQueryString'\nimport {isVisionPasteTarget} from '../util/isVisionPasteTarget'\nimport {getLocalStorage} from '../util/localStorage'\nimport {parseApiQueryString, type ParsedApiQueryString} from '../util/parseApiQueryString'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {validateApiVersion} from '../util/validateApiVersion'\nimport {ParamsEditor, parseParams} from './ParamsEditor'\nimport {QueryRecall} from './QueryRecall'\nimport {usePaneSize} from './usePaneSize'\nimport {\n InputBackgroundContainerLeft,\n InputContainer,\n QueryRecallPaneContainer,\n QueryRecallPaneWrapper,\n Root,\n SplitpaneContainer,\n StyledLabel,\n} from './VisionGui.styled'\nimport {VisionGuiControls} from './VisionGuiControls'\nimport {VisionGuiHeader} from './VisionGuiHeader'\nimport {VisionGuiResult} from './VisionGuiResult'\n\nfunction nodeContains(node: Node, other: EventTarget | Node | null): boolean {\n if (!node || !other) {\n return false\n }\n\n return node === other || !!(node.compareDocumentPosition(other as Node) & 16)\n}\n\n// Match Sanity API URLs with any domain (supports custom CDN domains like foolcdn.com)\nconst sanityUrl = /\\/(vX|v1|v\\d{4}-\\d\\d-\\d\\d)\\/.*?(?:query|listen)\\/(.*?)\\?(.*)/\nconst VARIANTS_API_VERSION = prefixApiVersion(VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion)\n\nconst isRunHotkey = (event: KeyboardEvent) =>\n isHotkey('ctrl+enter', event) || isHotkey('mod+enter', event)\n\ninterface Subscription {\n unsubscribe: () => void\n}\nexport interface Params {\n raw: string\n parsed: Record<string, unknown> | undefined\n valid: boolean\n error: string | undefined\n}\n\ninterface QueryExecutionOptions {\n apiVersion?: string\n dataset?: string\n perspective?: SupportedPerspective | undefined\n query?: string\n params?: Record<string, unknown>\n}\n\ninterface VisionGuiProps extends VisionProps {\n datasets: string[]\n projectId: string | undefined\n defaultDataset: string\n}\n\nexport interface ParsedUrlState {\n query: string\n params: Record<string, unknown>\n rawParams: string\n dataset: string\n apiVersion: string\n customApiVersion: string | false | undefined\n perspective: SupportedPerspective | undefined\n url: string\n}\n\nexport function VisionGui(props: VisionGuiProps) {\n const {datasets, config, projectId, defaultDataset} = props\n const toast = useToast()\n const {t} = useTranslation(visionLocaleNamespace)\n const {perspectiveStack, selectedVariantName} = usePerspective()\n const isScheduledDraftsEnabled = useScheduledDraftsEnabled()\n const {data: releases = []} = useActiveReleases()\n const workspace = useWorkspace()\n const isDraftModelEnabled = workspace.document.drafts.enabled\n\n const editorQueryRef = useRef<VisionCodeMirrorHandle>(null)\n const editorParamsRef = useRef<VisionCodeMirrorHandle>(null)\n const visionRootRef = useRef<HTMLDivElement | null>(null)\n const customApiVersionElementRef = useRef<HTMLInputElement | null>(null)\n const querySubscriptionRef = useRef<Subscription | undefined>(undefined)\n const listenSubscriptionRef = useRef<Subscription | undefined>(undefined)\n\n const [localStorage] = useState(() => getLocalStorage(projectId || 'default'))\n\n const storedDataset = localStorage.get('dataset', defaultDataset)\n const storedApiVersion = localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )\n const storedQuery = localStorage.get('query', '')\n const storedParams = localStorage.get('params', '{\\n \\n}')\n const storedPerspective = localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )\n\n const [dataset, setDataset] = useState<string>(() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n })\n const [perspective, setPerspectiveState] = useState<SupportedPerspective | undefined>(\n storedPerspective || 'raw',\n )\n const activeVariant = getActiveVariant(perspective, selectedVariantName)\n\n const [apiVersion, setApiVersion] = useState<string>(() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION,\n )\n const [customApiVersion, setCustomApiVersion] = useState<string | false>(() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion,\n )\n const isValidApiVersion = customApiVersion ? validateApiVersion(customApiVersion) : true\n\n const [url, setUrl] = useState<string | undefined>(undefined)\n const [query, setQuery] = useState<string>(() =>\n typeof storedQuery === 'string' ? storedQuery : '',\n )\n const [rawParams, setRawParams] = useState<string>(storedParams)\n const params = useMemo(() => parseParams(rawParams, t), [rawParams, t])\n const [queryResult, setQueryResult] = useState<unknown | undefined>(undefined)\n const [listenMutations, setListenMutations] = useState<MutationEvent[]>([])\n const [error, setError] = useState<Error | undefined>(undefined)\n const [queryTime, setQueryTime] = useState<number | undefined>(undefined)\n const [e2eTime, setE2eTime] = useState<number | undefined>(undefined)\n const [queryInProgress, setQueryInProgress] = useState<boolean>(false)\n const [listenInProgress, setListenInProgress] = useState<boolean>(false)\n const [isQueryRecallCollapsed, setIsQueryRecallCollapsed] = useState(false)\n\n const {paneSizeOptions, isNarrowBreakpoint} = usePaneSize({visionRootRef})\n\n // Compute scheduled drafts perspective stack\n const scheduledDraftsStack = useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])\n\n const userApiVersion = activeVariant\n ? VARIANTS_API_VERSION\n : isValidApiVersion && customApiVersion\n ? customApiVersion\n : apiVersion\n\n // Client with memoized initial value\n const _client = useClient({\n apiVersion: userApiVersion,\n })\n const client = useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])\n\n const cancelQuerySubscription = useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])\n\n const cancelListenerSubscription = useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])\n\n const handleQueryExecution = useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )\n\n const setPerspective = useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution],\n )\n\n const handleChangeDataset = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution],\n )\n\n const changeApiVersion = useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )\n\n const handleChangeApiVersion = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )\n\n // Handle custom API version change\n const handleCustomApiVersionChange = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )\n\n // Handle perspective change\n const handleChangePerspective = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )\n\n const handleListenerEvent = useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])\n const handleListenExecution = useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])\n\n const handleParamsChange = useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )\n\n // Get object of state values from provided URL\n const getStateFromUrl = useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )\n\n // Use state object from parsed URL to update state\n const setStateFromParsedUrl = useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution],\n )\n\n const handlePaste = useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )\n\n useEffect(() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }, [handleKeyDown, handlePaste])\n\n useEffect(() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }, [cancelQuerySubscription, cancelListenerSubscription])\n\n const handleStudioVariantChange = useEffectEvent(() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n })\n\n useEffect(() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [activeVariant])\n\n const handleStudioPerspectiveChange = useEffectEvent((stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n })\n // Handle pinned perspective changes\n useEffect(() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [perspectiveStack])\n\n const generateUrl = useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )\n\n return (\n <Root\n direction=\"column\"\n height=\"fill\"\n ref={visionRootRef}\n sizing=\"border\"\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>\n )\n}\n","import {type SanityClient} from '@sanity/client'\nimport {useMemo} from 'react'\nimport {type ObservablePromise, useObservablePromise} from 'react-rx'\nimport {catchError, map, type Observable, of} from 'rxjs'\n\nimport {type VisionConfig} from '../types'\n\nexport function useDatasets({\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}): ObservablePromise<string[] | Error> {\n const datasets$: Observable<string[] | Error> = useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])\n\n return useObservablePromise(datasets$)\n}\n","import {Flex} from '@sanity/ui'\nimport {Suspense, use} from 'react'\nimport {type ObservablePromise} from 'react-rx'\nimport {useClient} from 'sanity'\n\nimport {DelayedSpinner} from '../components/DelayedSpinner'\nimport {VisionGui} from '../components/VisionGui'\nimport {useDatasets} from '../hooks/useDatasets'\nimport {type VisionProps} from '../types'\n\nexport function VisionContainer(props: VisionProps) {\n const datasetsClient = useClient({apiVersion: 'v2025-06-27'})\n const datasetsPromise = useDatasets({client: datasetsClient, datasets: props.config.datasets})\n\n return (\n <Suspense\n fallback={\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>\n )\n}\n\nfunction LoadedVisionContainer({\n datasetsPromise,\n ...props\n}: VisionProps & {datasetsPromise: ObservablePromise<string[] | Error>}) {\n const loadedDatasets = use(datasetsPromise)\n\n const datasets =\n loadedDatasets instanceof Error\n ? // On error, use the clients configured dataset\n [props.client.config().dataset || 'production']\n : // Otherwise use the loaded list, obviously\n loadedDatasets\n\n const projectId = props.client.config().projectId\n const defaultDataset = props.config.defaultDataset || props.client.config().dataset || datasets[0]\n\n return (\n <VisionGui\n key={projectId}\n {...props}\n datasets={datasets}\n projectId={projectId}\n defaultDataset={defaultDataset}\n />\n )\n}\n","/* oxlint-disable @sanity/i18n/no-attribute-string-literals */\n/* oxlint-disable i18next/no-literal-string */\nimport {Button, Card, Container, Heading, Stack} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Component, type PropsWithChildren} from 'react'\n\nimport {clearLocalStorage} from '../util/localStorage'\n\n/**\n * @internal\n */\nexport type VisionErrorBoundaryProps = PropsWithChildren\n\n/**\n * @internal\n */\ninterface VisionErrorBoundaryState {\n error: string | null\n numRetries: number\n}\n\n/**\n * @internal\n */\nexport class VisionErrorBoundary extends Component<\n VisionErrorBoundaryProps,\n VisionErrorBoundaryState\n> {\n constructor(props: VisionErrorBoundaryProps) {\n super(props)\n this.state = {error: null, numRetries: 0}\n }\n\n static getDerivedStateFromError(error: unknown) {\n // oxlint-disable-next-line restrict-template-expressions - @TODO use new Error(msg, {cause: error}) instead of casting to string, and console.error() the full error\n return {error: error instanceof Error ? error.message : `${error}`}\n }\n\n handleRetryRender = () =>\n this.setState((prev) => ({error: null, numRetries: prev.numRetries + 1}))\n\n handleRetryWithCacheClear = () => {\n clearLocalStorage()\n this.handleRetryRender()\n }\n\n render() {\n if (!this.state.error) {\n return this.props.children\n }\n\n const message = this.state.error\n const withCacheClear = this.state.numRetries > 0\n\n return (\n <Card\n height=\"fill\"\n overflow=\"auto\"\n paddingY={[4, 5, 6, 7]}\n paddingX={4}\n sizing=\"border\"\n tone=\"critical\"\n >\n <Container width={3}>\n <Stack gap={4}>\n <div>\n <Button\n onClick={withCacheClear ? this.handleRetryWithCacheClear : this.handleRetryRender}\n text={withCacheClear ? 'Clear cache and retry' : 'Retry'}\n tone=\"default\"\n />\n </div>\n\n <Heading>An error occurred</Heading>\n\n <Card border radius={2} overflow=\"auto\" padding={4} tone=\"inherit\">\n <Stack gap={4}>\n {message && (\n <Code size={1}>\n <strong>Error: {message}</strong>\n </Code>\n )}\n </Stack>\n </Card>\n </Stack>\n </Container>\n </Card>\n )\n }\n}\n","import {type Tool, useClient} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from './apiVersions'\nimport {VisionContainer} from './containers/VisionContainer'\nimport {VisionErrorBoundary} from './containers/VisionErrorBoundary'\nimport {type VisionConfig} from './types'\n\ninterface SanityVisionProps {\n tool: Tool<VisionConfig>\n}\n\nfunction SanityVision(props: SanityVisionProps) {\n const client = useClient({apiVersion: '1'})\n const config: VisionConfig = {\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }\n\n return (\n <VisionErrorBoundary>\n <VisionContainer client={client} config={config} />\n </VisionErrorBoundary>\n )\n}\n\nexport default SanityVision\n"],"mappings":"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"}
1
+ {"version":3,"file":"SanityVision-CLaQvTR9.js","names":["() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }","[props.delay]","delay","show ? <Spinner muted size={4} /> : null","createTheme(theme)","useMemo(() => createTheme(theme), [theme])","syntaxHighlighting(createHighlight(theme))","useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])","[cmTheme, cmHighlight]","{children}: {children: ReactNode}","rem(sanity.space[3])","3","rem(sanity.space[4])","4","rem(sanity.space[5])","5","assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })","`${rem(sanity.space[3])}`","`${rem(sanity.space[4])}`","`${rem(sanity.space[5])}`","<div\n className={editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })}\n >\n {children}\n </div>","{\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n} & RefAttributes<VisionCodeMirrorHandle>","(newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }","useCallback((newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }, [])","() => ({\n resetEditorContent,\n })","[resetEditorContent]","<EditorRoot>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={initialValue}\n onChange={onChange}\n />\n </EditorRoot>","{\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>","<Flex {...props} ref={ref} className={root} />","<Card {...props} className={header} />","<Label {...props} className={styledLabel} />","<Box {...props} className={splitpaneContainer} />","<Flex {...props} direction=\"column\" className={queryRecallPaneContainer} />","<Flex\n {...props}\n direction=\"column\"\n flex={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />","<a {...props} className={queryCopyLink} />","<Box {...props} className={inputBackgroundContainer} />","<Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />","<Card {...props} className={inputContainer} />","<Flex {...props} className={resultOuterContainer} />","<Box {...props} className={resultInnerContainer} />","{\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}","<Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />","isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer","<Box {...props} className={result} />","<Flex {...props} className={resultFooter} />","<Card {...props} className={timingsCard} />","rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )","space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight","assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})","`${minHeight}`","<Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />","<Card {...props} className={downloadsCard} />","rem(space[3])","3","assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})","`${rem(space[3])}`","<Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />","<Box {...props} className={controlsContainer} />","(newValue: string) => {\n onChange(newValue)\n }","useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )","debounce(handleChangeRaw, 333)","useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])","t('params.label')","<StyledLabel muted>{t('params.label')}</StyledLabel>","paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />","props.value || defaultValue","<Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>","hasValidParams ? 'default' : 'critical'","{apiVersion: DEFAULT_API_VERSION}","[]","keyValueStore.getKey(keyValueStoreKey)","useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])","(docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n }","id","useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )","() => {\n const sub = personalQueries\n .pipe(\n startWith(defaultValue as any),\n map((data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }),\n )\n .subscribe({\n next: setValue,\n error: (err) => setError(err as Error),\n })\n\n return () => sub?.unsubscribe()\n }","[personalQueries]","(data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }","() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }","[workspaceClient, mapSharedQueries]","docs","err","sub","[...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })","queries","(a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n }","useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])","async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n }","currentUser?.id","saveError","useCallback(\n async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n },\n [currentUser, workspaceClient, keyValueStore, mapSharedQueries, value.queries],\n )","async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n }","query","authError","prev","updateError","useCallback(\n async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n },\n [workspaceClient, currentUser, keyValueStore, mapSharedQueries, value.queries],\n )","async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n }","q","useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n },\n [workspaceClient, currentUser, keyValueStore, sharedQueries, value.queries],\n )","{\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n saving,\n deleting,\n saveQueryError,\n deleteQueryError,\n error,\n }","<Stack {...props} className={fixedHeader} />","<Flex {...props} direction=\"column\" flex={1} overflow=\"hidden\" className={scrollContainer} />","<Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />","{\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}","compactMode = false","{\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }","{}","[]","async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }","queries?.some","q","savedQueryObj","err","useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])","(query: QueryConfig) => {\n setShareDialogQuery(query)\n }","useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])","async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }","useCallback(async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [deleteQuery, saveQuery, shareDialogQuery, t, toast])","async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n }","queries?.find","query","prev","useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n },\n [deleteQuery, formatDate, getStateFromUrl, queries, saveQuery, t, toast],\n )","async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","next","useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )","async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","newUrl","isDuplicate","duplicateQuery","useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )","Stack","QueryList","ScrollContainer","3","filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })","\"vision-query-recall-list\"","<FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>","queries?.filter","t('label.saved-queries')","<StyledLabel muted>{t('label.saved-queries')}</StyledLabel>","t('action.save-query')","() => void handleSave()","<Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />","<Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>","t('label.search-queries')","(event) => setSearchQuery(event.currentTarget.value)","<Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>","t('label.all')","() => setQueryFilter('all')","<Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />","queryFilter === 'all'","t('label.personal')","() => setQueryFilter('personal')","<Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />","queryFilter === 'personal'","t('label.shared')","() => setQueryFilter('shared')","<Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />","queryFilter === 'shared'","<Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>","event","<Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>","<QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>","shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )","<ScrollContainer>\n <FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>","{\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}","() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n })","() => narrowBreakpoint()","() =>\n calculatePaneSizeOptions(undefined)","() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }","[visionRootRef]","visionRootRef.current","{paneSizeOptions, isNarrowBreakpoint, rootSize}","{\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n}: VisionGuiControlsProps","t('params.error.params-invalid-json')","<Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>","<Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>","queryInProgress ? t('action.query-cancel') : t('action.query-execute')","<Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>","queryInProgress ? StopIcon : PlayIcon","listenInProgress || !hasValidParams","queryInProgress ? 'positive' : 'primary'","listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')","<Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>","!hasValidParams","listenInProgress ? 'positive' : 'default'","listenInProgress ? StopIcon : PlayIcon","<Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>","<ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>","<Box {...props} className={perspectivePopoverContent} />","<a {...props} className={perspectivePopoverLink} />","{tone}: {tone: CardTone}","<div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />","`var(--card-badge-${tone}-dot-color)`","() => setOpen((o) => !o)","(o) => !o","useCallback(() => setOpen((o) => !o), [])","() => setOpen(false)","() => [buttonRef.current, popoverRef.current]","t('settings.perspectives.title')","<Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>","t('settings.perspectives.description')","<Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>","t('label.new')","<Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>","<Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>","<Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>","SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null","t('settings.perspectives.action.docs-link')","<Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>","<PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>","<Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />","<Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>","<Popover\n content={\n <PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>","{pinnedPerspective, t}","pinnedPerspective.selectedVariant\n ? getVariantTitle(pinnedPerspective.selectedVariant)\n : pinnedPerspective.selectedVariantName","selectedVariant","selectedVariantName","hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')","[name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')","variantTitle ? `· ${variantTitle}` : undefined","(value) => typeof value !== 'undefined'","hasPinnedPerspective(pinnedPerspective)","<option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>","!hasPinnedPerspective(pinnedPerspective)","{\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps","getActiveVariant(perspective, pinnedPerspective.selectedVariantName)","() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }","useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])","[1, 4, 8, 12]","['span 1 / span 1', 'span 2 / span 2']","t('settings.dataset-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>","datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))","(ds: string) => (\n <option key={ds}>{ds}</option>\n )","<Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>","t('settings.api-version-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>","t('settings.api-version-locked-for-variant')","<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>","API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))","(version) => (\n <option key={version}>{version}</option>\n )","t('settings.other-api-version-label')","<option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>","<Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>","customApiVersion === false ? apiVersion : 'other'","<Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>","!isApiVersionLocked","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>","!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )","t('settings.perspective-label')","<Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>","<Box>\n <PerspectivePopover />\n </Box>","<Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>","SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })","<Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>","perspective || 'default'","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>","typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )","<Header paddingX={3} paddingY={2}>\n <Grid gridTemplateColumns={[1, 4, 8, 12]}>\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>","<Code {...props} className={errorCode} />","{error}: {error: ContentLakeQueryError | Error}","ErrorCode","details.line","dashLine(\n details.column,\n details.columnEnd,\n )","1","details","error.details","<ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>","`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`","t('query.error.line')","t(\n 'query.error.column',\n )","details.lineNumber","<Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>","`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`","<div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>","Stack","5","2","unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null","<ErrorCode size={1}>{error.message}</ErrorCode>","message","<QueryErrorDetails error={error} />","<Stack gap={5} marginTop={2}>\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Stack>","{children}: {children: ReactNode}","rem(space[0])","0","rem(space[2])","2","rem(space[4])","4","rem(space[4] / 2)","space[4] / 2","assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })","boolean","constant","number","property","string","family","`${rem(space[4] / 2)}`","`${codeSize.fontSize}px`","`${codeSize.lineHeight}px`","`${rem(space[0])}`","`${rem(space[2])}`","`${rem(space[4])}`","font.code.family","<div\n className={resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>","<ResultViewWrapper>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={workspaceDataset === datasetName ? DocumentEditLabel : undefined}\n />\n </ResultViewWrapper>","workspaceDataset === datasetName ? DocumentEditLabel : undefined","JSON.stringify(data)","<Code language=\"json\">{JSON.stringify(data)}</Code>","{id: props.value}","value","<LinkIcon />","<IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>","{blobUrl}: SaveButtonProps","t('result.save-result-as-csv.not-csv-encodable')","<Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Tooltip content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>","<Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />","{\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps","compactFooter = false","t('result.label')","<InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>","(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )","listenMutations.length","error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )","hasResult && <ResultView data={queryResult} datasetName={dataset} />","listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )","<Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>","<Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>","<ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>","error ? 'critical' : 'default'","Boolean(error)","compactFooter ? 'column' : ['column', 'column', 'row']","compactFooter ? {width: '100%'} : {minWidth: 0}","t('result.execution-time-label')","typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')","<Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 1 : 2","t('result.end-to-end-time-label')","typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')","<Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>","<Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 3 : 4","<TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>","<TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>","compactFooter ? 2 : 3","hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )","<ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>","compactFooter ? 'flex-start' : 'space-between'","compactFooter ? 'stretch' : undefined","<ResultOuterContainer direction=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>","{queryResult}: {queryResult: unknown}","getJsonBlobUrl(queryResult)","getCsvBlobUrl(queryResult)","<SaveJsonButton blobUrl={jsonUrl} />","<SaveCsvButton blobUrl={csvUrl} />","<>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>","releases = []","() => getLocalStorage(projectId || 'default')","localStorage.get('dataset', defaultDataset)","localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )","defaultApiVersion","localStorage.get('query', '')","localStorage.get('params', '{\\n \\n}')","localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )","() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n }","getActiveVariant(perspective, selectedVariantName)","() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION","() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion","customApiVersion ? validateApiVersion(customApiVersion) : true","() =>\n typeof storedQuery === 'string' ? storedQuery : ''","parseParams(rawParams, t)","useMemo(() => parseParams(rawParams, t), [rawParams, t])","[]","{visionRootRef}","useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])","[...releaseIds, ...defaultPerspective]","(release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled'","(release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id)","isDraftModelEnabled ? ['drafts'] : ['published']","{\n apiVersion: userApiVersion,\n }","_client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })","useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])","() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])","() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])","(options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n }","parsed","useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )","(newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n }","useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n }","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution],\n )","(newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n }","useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n }","evt","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )","(evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n }","useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n }","newPerspective","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )","(evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }","useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])","() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }","error","raw","newUrl","err","useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])","(value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n }","useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )","(data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n }","newApiVersion","newCustomApiVersion","useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )","(parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n }","useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution],\n )","(evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n }","useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )","(event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n }","valid","useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )","() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }","[handleKeyDown, handlePaste]","() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }","[cancelQuerySubscription, cancelListenerSubscription]","() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n }","() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[activeVariant]","(stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n }","() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[perspectiveStack]","(queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n }","urlQueryOpts","useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )","<VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />","activeVariant ? VARIANTS_API_VERSION : apiVersion","activeVariant ? false : customApiVersion","t('query.label')","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />","<InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>","<ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />","<VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />","<InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>","allowResize","maxSize","size","isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize","isNarrowBreakpoint ? paneSizeOptions.minSize : 100","paneSizeOptions.size","paneSizeOptions.allowResize","paneSizeOptions.maxSize","getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })","<VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>","isNarrowBreakpoint ? 'vertical' : 'horizontal'","{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }","() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)","{display: 'flex', alignItems: 'center', height: '100%'}","<div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>","<Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>","params.parsed || {}","<QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>","<QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>","<SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>","isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275","<Root\n direction=\"column\"\n height=\"fill\"\n ref={visionRootRef}\n sizing=\"border\"\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>","release","{\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}","useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])","of(configDatasets)","client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )","datasets","(result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }","(d) => d.name","(ds) => ds.name","(err) => of(err)","{apiVersion: 'v2025-06-27'}","{client: datasetsClient, datasets: props.config.datasets}","datasets","<Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>","<Suspense\n fallback={\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>","{\n datasetsPromise,\n ...props\n}: VisionProps & {datasetsPromise: ObservablePromise<string[] | Error>}","loadedDatasets instanceof Error\n ? // On error, use the clients configured dataset\n [props.client.config().dataset || 'production']\n : // Otherwise use the loaded list, obviously\n loadedDatasets","client","props.client.config()","props.config.defaultDataset || props.client.config().dataset || datasets[0]","datasets[0]","defaultDataset","<VisionGui\n key={projectId}\n {...props}\n datasets={datasets}\n projectId={projectId}\n defaultDataset={defaultDataset}\n />","{apiVersion: '1'}","{\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }","options","<VisionErrorBoundary>\n <VisionContainer client={client} config={config} />\n </VisionErrorBoundary>"],"sources":["../src/apiVersions.ts","../src/components/DelayedSpinner.tsx","../src/codemirror/extensions.ts","../src/codemirror/useCodemirrorTheme.ts","../src/codemirror/VisionCodeMirror.css.ts","../src/codemirror/VisionCodeMirror.tsx","../src/perspectives.ts","../src/util/encodeQueryString.ts","../src/util/isVisionPasteTarget.ts","../src/util/isPlainObject.ts","../src/util/localStorage.ts","../src/util/parseApiQueryString.ts","../src/util/prefixApiVersion.ts","../src/util/validateApiVersion.ts","../src/util/tryParseParams.ts","../src/components/VisionGui.css.ts","../src/components/VisionGui.styled.tsx","../src/components/ParamsEditor.tsx","../src/hooks/useSavedQueries.ts","../src/components/QueryRecall.css.ts","../src/components/QueryRecall.tsx","../src/components/usePaneSize.ts","../src/components/VisionGuiControls.tsx","../src/components/PerspectivePopover.css.ts","../src/components/PerspectivePopover.tsx","../src/components/VisionGuiHeader.tsx","../src/util/getBlobUrl.ts","../src/util/compareApiVersion.ts","../src/util/apiVersionCapabilities.ts","../src/components/QueryErrorDialog.css.ts","../src/components/QueryErrorDialog.styled.tsx","../src/components/QueryErrorDetails.tsx","../src/components/QueryErrorDialog.tsx","../src/components/ResultView.css.ts","../src/components/ResultView.tsx","../src/components/SaveResultButtons.tsx","../src/components/VisionGuiResult.tsx","../src/components/VisionGui.tsx","../src/hooks/useDatasets.ts","../src/containers/VisionContainer.tsx","../src/containers/VisionErrorBoundary.tsx","../src/SanityVision.tsx"],"sourcesContent":["export const API_VERSIONS = [\n 'v1',\n 'vX',\n 'v2021-03-25',\n 'v2021-10-21',\n 'v2022-03-07',\n 'v2025-02-19',\n `v${new Date().toISOString().split('T')[0]}`,\n]\nexport const [DEFAULT_API_VERSION] = API_VERSIONS.slice(-1)\n","import {Spinner} from '@sanity/ui'\nimport {useEffect, useState} from 'react'\n\ninterface DelayedSpinnerProps {\n delay?: number\n}\n\n// Waits for X ms before showing a spinner\nexport function DelayedSpinner(props: DelayedSpinnerProps) {\n const [show, setShow] = useState(false)\n\n useEffect(() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }, [props.delay])\n\n return show ? <Spinner muted size={4} /> : null\n}\n","import {closeBrackets} from '@codemirror/autocomplete'\nimport {defaultKeymap, history, historyKeymap} from '@codemirror/commands'\nimport {javascriptLanguage} from '@codemirror/lang-javascript'\nimport {\n bracketMatching,\n defaultHighlightStyle,\n indentOnInput,\n syntaxHighlighting,\n} from '@codemirror/language'\nimport {highlightSelectionMatches} from '@codemirror/search'\nimport {type Extension} from '@codemirror/state'\nimport {\n drawSelection,\n highlightActiveLine,\n highlightActiveLineGutter,\n highlightSpecialChars,\n keymap,\n lineNumbers,\n type KeyBinding,\n} from '@codemirror/view'\nimport {groq} from '@sanity/lezer-groq'\n\nconst sharedExtensions: Extension[] = [\n lineNumbers(),\n highlightActiveLine(),\n highlightActiveLineGutter(),\n highlightSelectionMatches(),\n highlightSpecialChars(),\n indentOnInput(),\n bracketMatching(),\n closeBrackets(),\n history(),\n drawSelection(),\n syntaxHighlighting(defaultHighlightStyle, {fallback: true}),\n keymap.of([\n // Override the default keymap for Mod-Enter to not insert a new line, we have a custom event handler for executing queries\n {key: 'Mod-Enter', run: () => true},\n\n // Add the default keymap and history keymap\n ...defaultKeymap,\n ...historyKeymap,\n ] as unknown as readonly KeyBinding[]),\n]\n\nexport const groqExtensions: Extension[] = [groq(), ...sharedExtensions]\n\nexport const paramsExtensions: Extension[] = [javascriptLanguage, ...sharedExtensions]\n","import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'\nimport {type Extension} from '@codemirror/state'\nimport {EditorView} from '@codemirror/view'\nimport {tags as t} from '@lezer/highlight'\nimport {hues} from '@sanity/color'\nimport {rem, type Theme} from '@sanity/ui'\nimport {useMemo} from 'react'\n\n// The explicit return type keeps declaration emit portable (TS2883): without it the inferred\n// type references `Extension` from @codemirror/state through a non-portable .pnpm path\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nexport function useCodemirrorTheme(theme: Theme): Extension[] {\n const cmTheme = useMemo(() => createTheme(theme), [theme])\n const cmHighlight = useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])\n\n return [cmTheme, cmHighlight]\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createTheme(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {color, fonts} = theme.sanity\n const card = color.card.enabled\n const cursor = hues.blue[color.dark ? 400 : 500].hex\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const selection = hues.gray[theme.sanity.color.dark ? 900 : 100].hex\n\n return EditorView.theme(\n {\n '&': {\n color: card.fg,\n backgroundColor: card.bg,\n },\n\n '.cm-content': {\n caretColor: cursor,\n },\n\n '.cm-editor': {\n fontFamily: fonts.code.family,\n fontSize: rem(fonts.code.sizes[1].fontSize),\n lineHeight: 'inherit',\n },\n\n '.cm-cursor, .cm-dropCursor': {borderLeftColor: cursor},\n '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {\n backgroundColor: selection,\n },\n\n '.cm-panels': {backgroundColor: card.bg, color: card.fg},\n '.cm-panels.cm-panels-top': {borderBottom: `2px solid ${card.border}`},\n '.cm-panels.cm-panels-bottom': {borderTop: `2px solid ${card.border}`},\n },\n {dark: color.dark},\n )\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createHighlight(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const c = theme.sanity.color.base\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const s = theme.sanity.color.syntax\n return HighlightStyle.define([\n {tag: t.keyword, color: s.keyword},\n {tag: [t.propertyName, t.name, t.deleted, t.character, t.macroName], color: s.property},\n {tag: [t.function(t.variableName), t.labelName], color: s.function},\n {tag: [t.color, t.constant(t.name), t.standard(t.name)], color: s.variable},\n {tag: [t.definition(t.name), t.separator], color: s.constant},\n {\n tag: [\n t.typeName,\n t.className,\n t.number,\n t.changed,\n t.annotation,\n t.modifier,\n t.self,\n t.namespace,\n ],\n color: s.number,\n },\n {\n tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],\n color: s.operator,\n },\n {tag: [t.meta, t.comment], color: s.comment},\n {tag: t.strong, fontWeight: 'bold'},\n {tag: t.emphasis, fontStyle: 'italic'},\n {tag: t.strikethrough, textDecoration: 'line-through'},\n {tag: t.heading, fontWeight: 'bold', color: s.property},\n {tag: [t.atom, t.bool, t.special(t.variableName)], color: s.boolean},\n {tag: [t.processingInstruction, t.string, t.inserted], color: s.string},\n {tag: t.invalid, color: c.fg},\n ])\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const linePaddingLeftVar = createVar()\nexport const contentBorderRightWidthVar = createVar()\nexport const contentPaddingTopVar = createVar()\n\nexport const editorRoot = style({\n width: '100%',\n boxSizing: 'border-box',\n height: '100%',\n overflow: ['hidden', 'clip'],\n position: 'relative',\n display: 'flex',\n})\n\nglobalStyle(`${editorRoot} .cm-theme`, {\n width: '100%',\n})\n\nglobalStyle(`${editorRoot} .cm-editor`, {\n height: '100%',\n fontSize: '16px',\n lineHeight: '21px',\n})\n\nglobalStyle(`${editorRoot} .cm-line`, {\n paddingLeft: linePaddingLeftVar,\n})\n\nglobalStyle(`${editorRoot} .cm-content`, {\n borderRightWidth: `${contentBorderRightWidthVar} !important`,\n paddingTop: contentPaddingTopVar,\n})\n","import {type Extension} from '@codemirror/state'\nimport {rem, useTheme} from '@sanity/ui'\nimport CodeMirror, {\n EditorSelection,\n type ReactCodeMirrorProps,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {\n type ReactNode,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n type RefAttributes,\n} from 'react'\n\nimport {useCodemirrorTheme} from './useCodemirrorTheme'\nimport {\n contentBorderRightWidthVar,\n contentPaddingTopVar,\n editorRoot,\n linePaddingLeftVar,\n} from './VisionCodeMirror.css'\n\nfunction EditorRoot({children}: {children: ReactNode}) {\n const {sanity} = useTheme()\n\n return (\n <div\n className={editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[5])}`,\n })}\n >\n {children}\n </div>\n )\n}\n\nexport interface VisionCodeMirrorHandle {\n resetEditorContent: (newContent: string) => void\n}\n\nexport function VisionCodeMirror({\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n} & RefAttributes<VisionCodeMirrorHandle>) {\n // The value prop is only passed for initial value, and is not updated when the parent component updates the value.\n // If you need to update the value, use the resetEditorContent function.\n const [initialValue] = useState(initialValueProp)\n const sanityTheme = useTheme()\n const theme = useCodemirrorTheme(sanityTheme)\n const codeMirrorRef = useRef<ReactCodeMirrorRef>(null)\n\n const resetEditorContent = useCallback((newContent: string) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n }\n }, [])\n\n useImperativeHandle(\n ref,\n () => ({\n resetEditorContent,\n }),\n [resetEditorContent],\n )\n\n return (\n <EditorRoot>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={initialValue}\n onChange={onChange}\n />\n </EditorRoot>\n )\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {type PerspectiveContextValue, type PerspectiveStack} from 'sanity'\n\nexport const SUPPORTED_PERSPECTIVES = [\n 'pinnedRelease',\n 'scheduledDrafts',\n 'raw',\n 'published',\n 'drafts',\n] as const\n\nexport type SupportedPerspective = (typeof SUPPORTED_PERSPECTIVES)[number]\n\n/**\n * Virtual perspectives are recognised by Vision, but do not concretely reflect the names of real\n * perspectives. Virtual perspectives are transformed into real perspectives before being used to\n * interact with data.\n *\n * For example, the `pinnedRelease` virtual perspective is transformed to the real perspective\n * currently pinned in Studio, and `scheduledDrafts` is transformed to a stack of all scheduled\n * draft release IDs.\n */\nexport const VIRTUAL_PERSPECTIVES = ['pinnedRelease', 'scheduledDrafts'] as const\n\nexport type VirtualPerspective = (typeof VIRTUAL_PERSPECTIVES)[number]\n\nexport function isSupportedPerspective(p: string): p is SupportedPerspective {\n return SUPPORTED_PERSPECTIVES.includes(p as SupportedPerspective)\n}\n\nexport function isVirtualPerspective(\n maybeVirtualPerspective: unknown,\n): maybeVirtualPerspective is VirtualPerspective {\n return (\n typeof maybeVirtualPerspective === 'string' &&\n VIRTUAL_PERSPECTIVES.includes(maybeVirtualPerspective as VirtualPerspective)\n )\n}\n\nexport function hasPinnedPerspective({selectedPerspectiveName}: PerspectiveContextValue): boolean {\n return typeof selectedPerspectiveName !== 'undefined'\n}\n\nexport function getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n}: {\n visionPerspective: ClientPerspective | SupportedPerspective | undefined\n perspectiveStack: PerspectiveContextValue['perspectiveStack']\n scheduledDraftsStack?: PerspectiveStack\n}): ClientPerspective | undefined {\n if (visionPerspective === 'pinnedRelease') {\n return perspectiveStack\n }\n if (visionPerspective === 'scheduledDrafts') {\n return scheduledDraftsStack\n }\n return visionPerspective\n}\n\n/**\n * The navbar variant is only sent with Vision queries when the virtual \"Pinned release\"\n * perspective is selected. Other Vision perspectives stay local and do not attach a variant.\n */\nexport function getActiveVariant(\n visionPerspective: ClientPerspective | SupportedPerspective | undefined,\n selectedVariantName: string | undefined,\n): string | undefined {\n if (visionPerspective !== 'pinnedRelease') {\n return undefined\n }\n return selectedVariantName\n}\n","export function encodeQueryString(\n query: string,\n params: Record<string, unknown> = {},\n options: Record<string, string | string[]> = {},\n): string {\n const searchParams = new URLSearchParams()\n searchParams.set('query', query)\n\n for (const [key, value] of Object.entries(params)) {\n searchParams.set(`$${key}`, JSON.stringify(value))\n }\n\n for (const [key, value] of Object.entries(options)) {\n if (value) searchParams.set(key, `${value}`)\n }\n\n return `?${searchParams}`\n}\n","function acceptsNativePaste(node: EventTarget | undefined): boolean {\n const element = node as Partial<HTMLInputElement | HTMLTextAreaElement> | undefined\n const isTextField = element?.tagName === 'INPUT' || element?.tagName === 'TEXTAREA'\n return isTextField && element?.readOnly === false\n}\n\n/**\n * Whether a paste seen by Vision's `document` level listener was meant for Vision. The listener is\n * global, so it also observes pastes aimed at unrelated elements such as the Studio search field.\n *\n * Uses the dispatch path rather than `event.target`, because CodeMirror handles the paste and\n * re-renders the pasted line before the event reaches `document`, detaching the original target.\n */\nexport function isVisionPasteTarget(root: Node | null, event: ClipboardEvent): boolean {\n const path = event.composedPath()\n const [target] = path\n\n // A readonly field keeps focus after Copy URL but drops the paste, so Vision still claims it\n if (acceptsNativePaste(target)) {\n return false\n }\n\n // Nothing focused\n if (target === window.document || target === window.document.body) {\n return true\n }\n\n return root !== null && path.includes(root)\n}\n","export function isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n !!obj && typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]'\n )\n}\n","import {isPlainObject} from './isPlainObject'\n\nconst hasLocalStorage = supportsLocalStorage()\nconst keyPrefix = 'sanityVision:'\n\nexport interface LocalStorageish {\n get: <T>(key: string, defaultVal: T) => T\n set: <T>(key: string, value: T) => T\n merge: <T>(props: T) => T\n}\n\nexport function clearLocalStorage() {\n if (!hasLocalStorage) {\n return\n }\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(keyPrefix)) {\n localStorage.removeItem(key)\n }\n }\n}\n\nexport function getLocalStorage(namespace: string): LocalStorageish {\n const storageKey = `${keyPrefix}${namespace}`\n let loadedState: Record<string, unknown> | null = null\n\n return {get, set, merge}\n\n function get<T>(key: string, defaultVal: T): T {\n const state = ensureState()\n return typeof state[key] === 'undefined' ? defaultVal : (state[key] as T)\n }\n\n function set<T>(key: string, value: T): T {\n const state = ensureState()\n state[key] = value\n localStorage.setItem(storageKey, JSON.stringify(loadedState))\n return value\n }\n\n function merge<T>(props: T): T {\n const state = {...ensureState(), ...props}\n localStorage.setItem(storageKey, JSON.stringify(state))\n return state\n }\n\n function ensureState(): Record<string, unknown> {\n if (loadedState === null) {\n loadedState = loadState()\n }\n\n return loadedState\n }\n\n function loadState() {\n if (!hasLocalStorage) {\n return {}\n }\n\n try {\n const stored = JSON.parse(localStorage.getItem(storageKey) || '{}')\n return isPlainObject(stored) ? stored : {}\n } catch {\n return {}\n }\n }\n}\n\nfunction supportsLocalStorage() {\n const mod = 'lsCheck'\n try {\n localStorage.setItem(mod, mod)\n localStorage.removeItem(mod)\n return true\n } catch {\n return false\n }\n}\n","export interface ParsedApiQueryString {\n query: string\n params: Record<string, unknown>\n options: Record<string, string>\n}\n\nexport function parseApiQueryString(qs: URLSearchParams): ParsedApiQueryString {\n const params: Record<string, unknown> = {}\n const options: Record<string, string> = {}\n\n for (const [key, value] of qs.entries()) {\n if (key[0] === '$') {\n params[key.slice(1)] = JSON.parse(value)\n continue\n }\n\n if (key === 'perspective') {\n options[key] = value\n continue\n }\n }\n\n return {query: qs.get('query') || '', params, options}\n}\n","export function prefixApiVersion(version: string): string {\n if (version[0] !== 'v' && version !== 'other') {\n return `v${version}`\n }\n\n return version\n}\n","export function validateApiVersion(apiVersion: string): boolean {\n const parseableApiVersion = apiVersion.replace(/^v/, '').trim().toUpperCase()\n\n const isValidApiVersion =\n parseableApiVersion.length > 0 &&\n (parseableApiVersion === 'X' ||\n parseableApiVersion === '1' ||\n (/^\\d{4}-\\d{2}-\\d{2}$/.test(parseableApiVersion) && !isNaN(Date.parse(parseableApiVersion))))\n\n return isValidApiVersion\n}\n","import JSON5 from 'json5'\nimport {type TFunction} from 'sanity'\n\nexport function tryParseParams(\n val: string,\n t: TFunction<'vision'>,\n): Record<string, unknown> | Error {\n try {\n const parsed = val ? JSON5.parse(val) : {}\n return typeof parsed === 'object' && parsed && !Array.isArray(parsed) ? parsed : {}\n } catch (err) {\n // JSON5 always prefixes the error message with JSON5:, so we remove it\n // to clean up the error tooltip\n err.message = `${t('params.error.params-invalid-json')}:\\n\\n${err.message.replace(\n 'JSON5:',\n '',\n )}`\n return err\n }\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const root = style({})\n\nglobalStyle(`${root} .sidebarPanes .Pane`, {\n overflowY: 'auto',\n overflowX: 'hidden',\n})\n\nexport const queryRecallPaneContainer = style({\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n})\n\nexport const queryRecallPaneWrapper = style({\n minHeight: 0,\n})\n\nglobalStyle(`${root} .Resizer`, {\n background: 'var(--card-border-color)',\n opacity: 1,\n zIndex: 1,\n boxSizing: 'border-box',\n backgroundClip: 'padding-box',\n border: 'solid transparent',\n})\n\nglobalStyle(`${root} .Resizer:hover`, {\n borderColor: 'var(--card-shadow-ambient-color)',\n})\n\nglobalStyle(`${root} .Resizer.horizontal`, {\n height: '11px',\n margin: '-5px 0',\n borderWidth: '5px 0',\n cursor: 'row-resize',\n width: '100%',\n zIndex: 4,\n})\n\nglobalStyle(`${root} .Resizer.vertical`, {\n width: '11px',\n margin: '0 -5px',\n borderWidth: '0 5px',\n cursor: 'col-resize',\n zIndex: 2 /* To prevent the resizer from being hidden behind CodeMirror scroll area */,\n})\n\nglobalStyle(`${root} .Resizer.disabled`, {\n cursor: 'not-allowed',\n})\n\nglobalStyle(`${root} .Resizer.disabled:hover`, {\n borderColor: 'transparent',\n})\n\nexport const header = style({\n position: 'relative',\n flexShrink: 0,\n zIndex: 6,\n overflow: 'visible',\n borderBottom: '1px solid var(--card-border-color)',\n selectors: {\n // Override the background-color @sanity/ui's Card sets on itself\n '&&': {\n background: 'var(--card-bg-color)',\n },\n },\n})\n\nexport const styledLabel = style({\n flex: 1,\n})\n\nexport const splitpaneContainer = style({\n position: 'relative',\n minHeight: 0,\n zIndex: 1,\n})\n\nexport const queryCopyLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const inputBackgroundContainer = style({\n position: 'absolute',\n top: '1rem',\n left: 0,\n padding: 0,\n margin: 0,\n zIndex: 10,\n right: 0,\n})\n\nglobalStyle(`${inputBackgroundContainer} ${styledLabel}`, {\n userSelect: 'none',\n})\n\nexport const inputBackgroundContainerLeft = style({\n // This is so its aligned with the gutters of CodeMirror\n left: '33px',\n})\n\nexport const inputContainer = style({\n width: '100%',\n height: '100%',\n position: 'relative',\n flexDirection: 'column',\n})\n\nexport const resultOuterContainer = style({\n height: '100%',\n})\n\nexport const resultInnerContainer = style({\n position: 'relative',\n})\n\nexport const resultContainer = style({\n height: '100%',\n width: '100%',\n position: 'absolute',\n maxWidth: '100%',\n})\n\nexport const resultContainerInvalid = style({\n selectors: {\n '&&::after': {\n backgroundColor: 'var(--card-bg-color)',\n content: '\"\"',\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '100%',\n },\n },\n})\n\nexport const result = style({\n position: 'relative',\n width: '100%',\n height: '100%',\n zIndex: 20,\n})\n\nexport const resultFooter = style({\n borderTop: '1px solid var(--card-border-color)',\n flexWrap: 'wrap',\n})\n\nexport const timingsCard = style({\n position: 'relative',\n})\n\nexport const timingsTextMinHeightVar = createVar()\n\nexport const timingsTextContainer = style({\n height: '100%',\n minHeight: timingsTextMinHeightVar,\n})\n\nexport const downloadsCard = style({\n position: 'relative',\n})\n\nexport const saveResultSpanGapVar = createVar()\n\nexport const saveResultLabel = style({\n selectors: {\n // Override the transform/pseudo-elements @sanity/ui's Text applies for baseline trimming\n '&&': {\n transform: 'initial',\n },\n '&&::before': {\n content: 'none',\n },\n '&&::after': {\n content: 'none',\n },\n },\n})\n\nglobalStyle(`${saveResultLabel} > span`, {\n display: 'flex !important',\n flexWrap: 'wrap',\n gap: saveResultSpanGapVar,\n alignItems: 'center',\n})\n\nexport const controlsContainer = style({\n borderTop: '1px solid var(--card-border-color)',\n})\n","import {Card, Flex, Label, rem, Text, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {type ComponentProps, type ComponentPropsWithoutRef, type RefAttributes} from 'react'\nimport {Box} from 'ui5'\n\nimport {\n controlsContainer,\n downloadsCard,\n header,\n inputBackgroundContainer,\n inputBackgroundContainerLeft,\n inputContainer,\n queryCopyLink,\n queryRecallPaneContainer,\n queryRecallPaneWrapper,\n result,\n resultContainer,\n resultContainerInvalid,\n resultFooter,\n resultInnerContainer,\n resultOuterContainer,\n root,\n saveResultLabel,\n saveResultSpanGapVar,\n splitpaneContainer,\n styledLabel,\n timingsCard,\n timingsTextContainer,\n timingsTextMinHeightVar,\n} from './VisionGui.css'\n\nexport function Root({\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>) {\n return <Flex {...props} ref={ref} className={root} />\n}\n\nexport function Header(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={header} />\n}\n\nexport function StyledLabel(props: ComponentProps<typeof Label>) {\n return <Label {...props} className={styledLabel} />\n}\n\nexport function SplitpaneContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={splitpaneContainer} />\n}\n\nexport function QueryRecallPaneContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} direction=\"column\" className={queryRecallPaneContainer} />\n}\n\nexport function QueryRecallPaneWrapper(props: ComponentProps<typeof Flex>) {\n return (\n <Flex\n {...props}\n direction=\"column\"\n flex={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />\n )\n}\n\nexport function QueryCopyLink(props: ComponentProps<'a'>) {\n return <a {...props} className={queryCopyLink} />\n}\n\nexport function InputBackgroundContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={inputBackgroundContainer} />\n}\n\nexport function InputBackgroundContainerLeft(props: ComponentProps<typeof Box>) {\n return (\n <Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />\n )\n}\n\nexport function InputContainer(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={inputContainer} />\n}\n\nexport function ResultOuterContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultOuterContainer} />\n}\n\nexport function ResultInnerContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={resultInnerContainer} />\n}\n\nexport function ResultContainer({\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}) {\n return (\n <Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />\n )\n}\n\nexport function Result(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={result} />\n}\n\nexport function ResultFooter(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultFooter} />\n}\n\nexport function TimingsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={timingsCard} />\n}\n\nexport function TimingsTextContainer(props: ComponentProps<typeof Flex>) {\n const {space, font} = useThemeV2()\n const textSize = font.text.sizes[2]\n const minHeight = rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )\n\n return (\n <Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />\n )\n}\n\nexport function DownloadsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={downloadsCard} />\n}\n\nexport function SaveResultLabel(props: ComponentProps<typeof Text>) {\n const {space} = useThemeV2()\n\n return (\n <Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />\n )\n}\n\nexport function ControlsContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={controlsContainer} />\n}\n","import {ErrorOutlineIcon} from '@sanity/icons/ErrorOutline'\nimport {Card, Flex, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport debounce from 'lodash-es/debounce.js'\nimport {type RefObject, useCallback, useMemo} from 'react'\nimport {type TFunction, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {paramsExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {tryParseParams} from '../util/tryParseParams'\nimport {type Params} from './VisionGui'\nimport {InputBackgroundContainerLeft, StyledLabel} from './VisionGui.styled'\n\nconst defaultValue = `{\\n \\n}`\n\nexport interface ParamsEditorProps {\n value: string\n onChange: (changeEvt: string) => void\n paramsError: string | undefined\n hasValidParams: boolean\n editorRef: RefObject<VisionCodeMirrorHandle | null>\n}\n\nexport function ParamsEditor(props: ParamsEditorProps) {\n const {onChange, paramsError, hasValidParams, editorRef} = props\n const {t} = useTranslation(visionLocaleNamespace)\n\n const handleChangeRaw = useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )\n\n const handleChange = useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])\n return (\n <Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>\n )\n}\n\nexport function parseParams(value: string, t: TFunction<typeof visionLocaleNamespace>): Params {\n const parsedParams = tryParseParams(value, t)\n const params = parsedParams instanceof Error ? {} : parsedParams\n const validationError = parsedParams instanceof Error ? parsedParams.message : undefined\n const isValid = !validationError\n\n return {\n parsed: params,\n raw: value,\n valid: isValid,\n error: validationError,\n }\n}\n","import {type ListenOptions} from '@sanity/client'\nimport {uuid} from '@sanity/uuid' // Import the UUID library\nimport {useCallback, useEffect, useMemo, useState} from 'react'\nimport {map, startWith} from 'rxjs/operators'\nimport {type KeyValueStoreValue, useClient, useCurrentUser, useKeyValueStore} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from '../apiVersions'\n\nconst STORED_QUERIES_NAMESPACE = 'studio.vision-tool.saved-queries'\nconst SHARED_QUERY_DOCUMENT_TYPE = 'vision.sharedQuery'\nconst SHARED_QUERIES_QUERY = `*[_type == $sharedQueryType]{\n _id,\n authorId,\n savedAt,\n title,\n url\n} | order(savedAt desc)`\nconst SHARED_QUERY_LISTEN_OPTIONS: ListenOptions = {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: true,\n visibility: 'query',\n}\n\nexport interface QueryConfig {\n _key: string\n url: string\n savedAt: string\n title?: string\n shared?: boolean\n authorId?: string\n isOwnedByCurrentUser?: boolean\n}\n\nexport interface StoredQueries {\n queries: QueryConfig[]\n}\n\nconst defaultValue = {\n queries: [],\n}\nconst keyValueStoreKey = STORED_QUERIES_NAMESPACE\n\ninterface SharedQueryDocument {\n _id: string\n _type?: string\n authorId: string\n savedAt: string\n title?: string\n url: string\n}\n\nexport function useSavedQueries(): {\n queries: QueryConfig[]\n saveQuery: (query: Omit<QueryConfig, '_key'>) => Promise<void>\n updateQuery: (query: QueryConfig) => Promise<void>\n deleteQuery: (key: string) => Promise<void>\n saving: boolean\n deleting: string[]\n saveQueryError: Error | undefined\n deleteQueryError: Error | undefined\n error: Error | undefined\n} {\n const keyValueStore = useKeyValueStore()\n const workspaceClient = useClient({apiVersion: DEFAULT_API_VERSION})\n const currentUser = useCurrentUser()\n\n const [value, setValue] = useState<StoredQueries>(defaultValue)\n const [sharedQueries, setSharedQueries] = useState<QueryConfig[]>([])\n const [saving, setSaving] = useState(false)\n const [deleting, setDeleting] = useState<string[]>([])\n const [saveQueryError, setSaveQueryError] = useState<Error | undefined>()\n const [deleteQueryError, setDeleteQueryError] = useState<Error | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const personalQueries = useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])\n\n const mapSharedQueries = useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )\n\n useEffect(() => {\n const sub = personalQueries\n .pipe(\n startWith(defaultValue as any),\n map((data: StoredQueries) => {\n if (!data) {\n return defaultValue\n }\n return data\n }),\n )\n .subscribe({\n next: setValue,\n error: (err) => setError(err as Error),\n })\n\n return () => sub?.unsubscribe()\n }, [personalQueries])\n\n useEffect(() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [workspaceClient, mapSharedQueries])\n\n const queries = useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])\n\n const saveQuery = useCallback(\n async (query: Omit<QueryConfig, '_key'>) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id) {\n const authError = new Error('No current user found. Unable to save shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n setSaving(false)\n return\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n }\n\n try {\n const newQuery = {...query, _key: uuid()} // Add a unique _key to the query\n const newQueries = [newQuery, ...value.queries]\n setValue({queries: newQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: newQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n setSaving(false)\n throw saveError\n }\n setSaving(false)\n },\n [currentUser, workspaceClient, keyValueStore, mapSharedQueries, value.queries],\n )\n\n const updateQuery = useCallback(\n async (query: QueryConfig) => {\n setSaving(true)\n setSaveQueryError(undefined)\n\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n const authError = new Error('Only the author can update a shared query.')\n setSaveQueryError(authError)\n setSaving(false)\n throw authError\n }\n\n try {\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n setSaving(false)\n return\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n }\n\n try {\n const updatedQueries = value.queries.map((q) =>\n q._key === query._key ? {...q, ...query} : q,\n )\n setValue({queries: updatedQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: updatedQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n const updateError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(updateError)\n setSaving(false)\n throw updateError\n }\n setSaving(false)\n },\n [workspaceClient, currentUser, keyValueStore, mapSharedQueries, value.queries],\n )\n\n const deleteQuery = useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n const clearDeleting = () => setDeleting((prev) => prev.filter((k) => k !== key))\n\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (sharedQuery) {\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n setDeleteQueryError(new Error('Only the author can delete a shared query.'))\n clearDeleting()\n return\n }\n\n try {\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n return\n }\n\n try {\n const filteredQueries = value.queries.filter((q) => q._key !== key)\n setValue({queries: filteredQueries})\n await keyValueStore.setKey(keyValueStoreKey, {\n queries: filteredQueries,\n } as unknown as KeyValueStoreValue)\n } catch (err) {\n setDeleteQueryError(err as Error)\n }\n clearDeleting()\n },\n [workspaceClient, currentUser, keyValueStore, sharedQueries, value.queries],\n )\n\n return {\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n saving,\n deleting,\n saveQueryError,\n deleteQueryError,\n error,\n }\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const fixedHeader = style({\n flexShrink: 0,\n background: 'var(--card-bg-color)',\n zIndex: 1,\n})\n\nexport const scrollContainer = style({\n minHeight: 0,\n width: '100%',\n minWidth: 0,\n})\n\nexport const queryList = style({\n minHeight: 0,\n})\n","import {AddIcon} from '@sanity/icons/Add'\nimport {LockIcon} from '@sanity/icons/Lock'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {TrashIcon} from '@sanity/icons/Trash'\nimport {UnpublishIcon} from '@sanity/icons/Unpublish'\nimport {UsersIcon} from '@sanity/icons/Users'\nimport {Badge, Button, Card, Dialog, Flex, Stack, Tab, TabList, Text, TextInput} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Menu, MenuButton, MenuItem} from '@sanity/ui/menu'\nimport {useToast} from '@sanity/ui/toast'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {type ComponentProps, type ReactElement, useCallback, useState} from 'react'\nimport {ContextMenuButton, UserAvatar, useDateTimeFormat, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {type QueryConfig, useSavedQueries} from '../hooks/useSavedQueries'\nimport {visionLocaleNamespace} from '../i18n'\nimport {fixedHeader, queryList, scrollContainer} from './QueryRecall.css'\nimport {type ParsedUrlState} from './VisionGui'\nimport {StyledLabel} from './VisionGui.styled'\n\nfunction FixedHeader(props: ComponentProps<typeof Stack>) {\n return <Stack {...props} className={fixedHeader} />\n}\n\nfunction ScrollContainer(props: ComponentProps<typeof Flex>) {\n return (\n <Flex {...props} direction=\"column\" flex={1} overflow=\"hidden\" className={scrollContainer} />\n )\n}\n\nfunction QueryList(props: ComponentProps<typeof Box>) {\n return <Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />\n}\n\nexport function QueryRecall({\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}): ReactElement {\n type QueryFilter = 'all' | 'personal' | 'shared'\n const toast = useToast()\n const {saveQuery, updateQuery, queries, deleteQuery, saving, deleting} = useSavedQueries()\n const {t} = useTranslation(visionLocaleNamespace)\n const formatDate = useDateTimeFormat({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n const [editingKey, setEditingKey] = useState<string | null>(null)\n const [editingTitle, setEditingTitle] = useState('')\n const [optimisticTitles, setOptimisticTitles] = useState<Record<string, string>>({})\n const [searchQuery, setSearchQuery] = useState('')\n const [queryFilter, setQueryFilter] = useState<QueryFilter>('all')\n const [selectedUrl, setSelectedUrl] = useState<string | undefined>(url)\n const [pendingUnshareKeys, setPendingUnshareKeys] = useState<string[]>([])\n const [shareDialogQuery, setShareDialogQuery] = useState<QueryConfig | null>(null)\n\n const handleSave = useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])\n\n const handleShareQuery = useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])\n\n const handleConfirmShareQuery = useCallback(async () => {\n if (!shareDialogQuery) return\n\n const sharedQueryKey = shareDialogQuery._key\n const sharedQueryUrl = shareDialogQuery.url\n const sharedQueryTitle = shareDialogQuery.title || t('label.untitled-query')\n\n try {\n await saveQuery({\n shared: true,\n title: sharedQueryTitle,\n url: sharedQueryUrl,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(sharedQueryKey)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [deleteQuery, saveQuery, shareDialogQuery, t, toast])\n\n const handleUnshareQuery = useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n const unsharedQueryTitle = query.title || t('label.untitled-query')\n\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n await saveQuery({\n shared: false,\n title: unsharedQueryTitle,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n\n await deleteQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n clearPending()\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n clearPending()\n }\n },\n [deleteQuery, formatDate, getStateFromUrl, queries, saveQuery, t, toast],\n )\n\n const handleTitleSave = useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )\n\n const handleUpdate = useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )\n\n const visibleQueries = queries?.filter((q) => !pendingUnshareKeys.includes(q._key))\n\n const filteredQueries = visibleQueries?.filter((q) => {\n const matchesSearch = (q.title ?? '').toLowerCase().includes(searchQuery.toLowerCase())\n const matchesFilter =\n queryFilter === 'all' ||\n (queryFilter === 'personal' && !q.shared) ||\n (queryFilter === 'shared' && q.shared)\n return matchesSearch && matchesFilter\n })\n\n return (\n <ScrollContainer>\n <FixedHeader gap={3}>\n <Flex padding={3} paddingTop={2} paddingBottom={0} justify=\"space-between\" align=\"center\">\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Stack paddingY={3}>\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <Stack gap={compactMode ? 2 : 3}>\n <Flex justify=\"space-between\" align={'center'} style={{minHeight: '25px'}}>\n <Flex align=\"center\" gap={2} paddingRight={1} style={{minWidth: 0, flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{portal: true, placement: 'bottom-end', tone: 'default'}}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <Stack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex align=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Stack>\n ) : (\n <Flex align=\"center\" gap={2} style={{paddingTop: '2px', minHeight: '20px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justify=\"flex-end\" gap={3} padding={3} align=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>\n )\n}\n","import {useEffect, useState} from 'react'\n\ninterface PaneSizeOptions {\n defaultSize: number\n size?: number\n allowResize: boolean\n minSize: number\n maxSize: number\n}\n\ninterface RootSize {\n width: number\n height: number\n}\nfunction narrowBreakpoint(): boolean {\n return typeof window !== 'undefined' && window.innerWidth > 600\n}\n\nfunction calculatePaneSizeOptions(height: number | undefined): PaneSizeOptions {\n let rootHeight = height\n\n if (!rootHeight) {\n // Initial root height without header\n rootHeight =\n typeof window !== 'undefined' && typeof document !== 'undefined'\n ? document.body.getBoundingClientRect().height - 60\n : 0\n }\n return {\n defaultSize: rootHeight / (narrowBreakpoint() ? 2 : 1),\n size: rootHeight > 550 ? undefined : rootHeight * 0.4,\n allowResize: rootHeight > 550,\n minSize: Math.min(170, Math.max(170, rootHeight / 2)),\n maxSize: rootHeight > 650 ? rootHeight * 0.7 : rootHeight * 0.6,\n }\n}\n\nexport function usePaneSize({\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}) {\n const [rootSize, setRootSize] = useState<RootSize>(() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n }))\n const [isNarrowBreakpoint, setIsNarrowBreakpoint] = useState(() => narrowBreakpoint())\n const [paneSizeOptions, setPaneSizeOptions] = useState<PaneSizeOptions>(() =>\n calculatePaneSizeOptions(undefined),\n )\n\n useEffect(() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [visionRootRef])\n\n return {paneSizeOptions, isNarrowBreakpoint, rootSize}\n}\n","import {PlayIcon} from '@sanity/icons/Play'\nimport {StopIcon} from '@sanity/icons/Stop'\nimport {Button, Card, Flex, Hotkeys, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ControlsContainer} from './VisionGui.styled'\n\nexport interface VisionGuiControlsProps {\n hasValidParams: boolean\n queryInProgress: boolean\n listenInProgress: boolean\n onQueryExecution: () => void\n onListenExecution: () => void\n}\n\n/**\n * Vision GUI controls\n * To handle query and listen execution.\n */\nexport function VisionGuiControls({\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n}: VisionGuiControlsProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n return (\n <ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justify=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>\n )\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const perspectivePopoverContent = style({\n /* This limits the width of the popover content */\n maxWidth: '240px',\n})\n\nexport const perspectivePopoverLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const dot = style({\n width: '4px',\n height: '4px',\n borderRadius: '3px',\n boxShadow: '0 0 0 1px var(--card-bg-color)',\n})\n","import {HelpCircleIcon} from '@sanity/icons/HelpCircle'\nimport {\n Badge,\n Button,\n Card,\n type CardTone,\n Inline,\n Stack,\n Text,\n useClickOutsideEvent,\n} from '@sanity/ui'\nimport {Popover} from '@sanity/ui/popover'\nimport {type ComponentProps, useCallback, useRef, useState} from 'react'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {dot, perspectivePopoverContent, perspectivePopoverLink} from './PerspectivePopover.css'\n\nfunction PerspectivePopoverContent(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={perspectivePopoverContent} />\n}\n\nfunction PerspectivePopoverLink(props: ComponentProps<'a'>) {\n return <a {...props} className={perspectivePopoverLink} />\n}\n\nfunction Dot({tone}: {tone: CardTone}) {\n return <div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />\n}\n\nconst SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION = false\n\nexport function PerspectivePopover() {\n const [open, setOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement | null>(null)\n const popoverRef = useRef<HTMLDivElement | null>(null)\n\n const handleClick = useCallback(() => setOpen((o) => !o), [])\n\n const {t} = useTranslation(visionLocaleNamespace)\n\n useClickOutsideEvent(\n () => setOpen(false),\n () => [buttonRef.current, popoverRef.current],\n )\n\n return (\n <Popover\n content={\n <PerspectivePopoverContent>\n <Stack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <Stack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </Stack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} &rarr;\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </Stack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>\n )\n}\n","import {CopyIcon} from '@sanity/icons/Copy'\nimport {Button, Card, Flex, Grid, Inline, Select, Stack, Text, TextInput} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {\n type ChangeEvent,\n type ComponentType,\n Fragment,\n type RefObject,\n useCallback,\n useMemo,\n useRef,\n} from 'react'\nimport {\n getVariantTitle,\n type PerspectiveContextValue,\n type TFunction,\n usePerspective,\n useTranslation,\n} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {API_VERSIONS} from '../apiVersions'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActiveVariant,\n hasPinnedPerspective,\n SUPPORTED_PERSPECTIVES,\n type SupportedPerspective,\n} from '../perspectives'\nimport {PerspectivePopover} from './PerspectivePopover'\nimport {Header, QueryCopyLink, StyledLabel} from './VisionGui.styled'\n\nconst PinnedReleasePerspectiveOption: ComponentType<{\n pinnedPerspective: PerspectiveContextValue\n t: TFunction\n}> = ({pinnedPerspective, t}) => {\n const name =\n typeof pinnedPerspective.selectedPerspective === 'object'\n ? pinnedPerspective.selectedPerspective.metadata.title\n : pinnedPerspective.selectedPerspectiveName\n\n const variantTitle = pinnedPerspective.selectedVariant\n ? getVariantTitle(pinnedPerspective.selectedVariant)\n : pinnedPerspective.selectedVariantName\n\n const label = hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')\n\n const text = useMemo(\n () =>\n [name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')\n .join(' '),\n [label, name, variantTitle],\n )\n\n return (\n <option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>\n )\n}\n\nexport interface VisionGuiHeaderProps {\n onChangeDataset: (evt: ChangeEvent<HTMLSelectElement>) => void\n dataset: string\n customApiVersion: string | false\n apiVersion: string\n onChangeApiVersion: (evt: ChangeEvent<HTMLSelectElement>) => void\n datasets: string[]\n customApiVersionElementRef: RefObject<HTMLInputElement | null>\n onCustomApiVersionChange: (evt: ChangeEvent<HTMLInputElement>) => void\n isValidApiVersion: boolean\n onChangePerspective: (evt: ChangeEvent<HTMLSelectElement>) => void\n url?: string\n perspective?: SupportedPerspective\n isScheduledDraftsEnabled: boolean\n}\n\nexport function VisionGuiHeader({\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps) {\n const pinnedPerspective = usePerspective()\n const isApiVersionLocked = Boolean(\n getActiveVariant(perspective, pinnedPerspective.selectedVariantName),\n )\n const {t} = useTranslation(visionLocaleNamespace)\n const operationUrlElement = useRef<HTMLInputElement | null>(null)\n const handleCopyUrl = useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])\n\n return (\n <Header paddingX={3} paddingY={2}>\n <Grid gridTemplateColumns={[1, 4, 8, 12]}>\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </Stack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </Stack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </Stack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <Stack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </Stack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <Stack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')}&nbsp;\n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flex={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </Stack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>\n )\n}\n","import {json2csv} from 'json-2-csv'\n\nfunction getBlobUrl(content: string, mimeType: string): string {\n return URL.createObjectURL(\n new Blob([content], {\n type: mimeType,\n }),\n )\n}\n\nfunction getMemoizedBlobUrlResolver(mimeType: string, stringEncoder: (input: any) => string) {\n return (() => {\n let prevResult = ''\n let prevContent = ''\n return (input: unknown) => {\n const content = stringEncoder(input)\n if (typeof content !== 'string' || content === '') {\n return undefined\n }\n\n if (content === prevContent) {\n return prevResult\n }\n\n prevContent = content\n if (prevResult) {\n URL.revokeObjectURL(prevResult)\n }\n\n prevResult = getBlobUrl(content, mimeType)\n return prevResult\n }\n })()\n}\n\nexport const getJsonBlobUrl = getMemoizedBlobUrlResolver('application/json', (input) =>\n JSON.stringify(input, null, 2),\n)\n\nexport const getCsvBlobUrl = getMemoizedBlobUrlResolver('text/csv', (input) => {\n return json2csv(Array.isArray(input) ? input : [input]).trim()\n})\n","type ParsedApiVersion =\n | {kind: 'experimental'}\n | {kind: 'legacy'}\n | {kind: 'dated'; value: string}\n | {kind: 'unknown'}\n\n/**\n * Returns true when `selected` does not satisfy `required`.\n *\n * `X` is the experimental API: it satisfies every requirement, and when it is\n * the requirement only `X` satisfies it. Dated versions compare\n * lexicographically. `v1` sits below every dated version and `X`.\n */\nexport function isApiVersionBelow(selected: string, required: string): boolean {\n const parsedSelected = parseApiVersion(selected)\n const parsedRequired = parseApiVersion(required)\n\n if (parsedSelected.kind === 'unknown' || parsedRequired.kind === 'unknown') {\n return false\n }\n\n if (parsedSelected.kind === 'experimental') {\n return false\n }\n\n if (parsedRequired.kind === 'experimental') {\n return true\n }\n\n if (parsedSelected.kind === 'legacy') {\n return parsedRequired.kind !== 'legacy'\n }\n\n if (parsedRequired.kind === 'legacy') {\n return false\n }\n\n return parsedSelected.value < parsedRequired.value\n}\n\nfunction parseApiVersion(version: string): ParsedApiVersion {\n const normalized = version.replace(/^v/i, '').trim()\n\n if (!normalized) {\n return {kind: 'unknown'}\n }\n\n if (normalized.toUpperCase() === 'X') {\n return {kind: 'experimental'}\n }\n\n if (normalized === '1') {\n return {kind: 'legacy'}\n }\n\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(normalized)) {\n return {kind: 'dated', value: normalized}\n }\n\n return {kind: 'unknown'}\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {RELEASES_STUDIO_CLIENT_OPTIONS, VARIANTS_STUDIO_CLIENT_OPTIONS} from 'sanity'\n\nimport {type VisionLocaleResourceKeys} from '../i18n/resources'\nimport {isApiVersionBelow} from './compareApiVersion'\n\nconst NAMED_PERSPECTIVES = new Set(['raw', 'published', 'drafts', 'previewDrafts'])\n\nexport interface ApiVersionCapabilityContext {\n statusCode: number | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport interface ApiVersionCapabilityRequirement {\n id: string\n requiredApiVersion: string\n explanationKey: VisionLocaleResourceKeys\n applies: (context: ApiVersionCapabilityContext) => boolean\n}\n\n/**\n * Capability floors for Vision error copy. Order is precedence: the first\n * unsatisfied entry wins.\n *\n * Variant before releases matches `variantApiVersion()` in\n * `packages/sanity/src/core/variants/util/variantApiVersion.ts` — a variant\n * requirement takes precedence over the releases version for stacked\n * perspectives.\n *\n * Add a capability by appending an entry. Do not add a branch in the error\n * dialog.\n */\nexport const API_VERSION_CAPABILITIES: readonly ApiVersionCapabilityRequirement[] = [\n {\n id: 'variants',\n // `query.error.unsupported-variant` names the experimental API; reword it if this floor becomes dated.\n requiredApiVersion: VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-variant',\n applies: ({variant}) => Boolean(variant),\n },\n {\n id: 'releases',\n // Matches any stacked perspective, including scheduled drafts and agent bundles, so the copy\n // stays generic rather than naming releases.\n requiredApiVersion: RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-release-perspective',\n applies: ({perspective}) => hasReleaseInPerspective(perspective),\n },\n]\n\nexport function hasReleaseInPerspective(perspective: ClientPerspective | undefined): boolean {\n if (!Array.isArray(perspective)) {\n return false\n }\n\n return perspective.some((entry) => !NAMED_PERSPECTIVES.has(entry))\n}\n\nexport function getUnsatisfiedApiVersionCapability(\n context: ApiVersionCapabilityContext,\n capabilities: readonly ApiVersionCapabilityRequirement[] = API_VERSION_CAPABILITIES,\n): ApiVersionCapabilityRequirement | undefined {\n if (context.statusCode !== 400) {\n return undefined\n }\n\n return capabilities.find(\n (capability) =>\n capability.applies(context) &&\n isApiVersionBelow(context.apiVersion, capability.requiredApiVersion),\n )\n}\n","import {style} from '@vanilla-extract/css'\n\n// `ErrorCode` always renders inside a critical-tone `Card`, so the card sets\n// `--card-muted-fg-color` to the muted critical foreground color we want here.\n// `&&` is needed to override the color @sanity/ui's Code sets on itself.\nexport const errorCode = style({\n selectors: {\n '&&': {\n color: 'var(--card-muted-fg-color)',\n },\n },\n})\n","import {Code} from '@sanity/ui/code'\nimport {type ComponentProps} from 'react'\n\nimport {errorCode} from './QueryErrorDialog.css'\n\nexport function ErrorCode(props: ComponentProps<typeof Code>) {\n return <Code {...props} className={errorCode} />\n}\n","import {useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface ContentLakeQueryError {\n details: {\n query: string\n start: number\n end: number\n\n lineNumber?: number\n column?: number\n }\n}\n\nexport function QueryErrorDetails({error}: {error: ContentLakeQueryError | Error}) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n if (!('details' in error)) {\n return null\n }\n\n const details = {...error.details, ...mapToLegacyDetails(error.details)}\n if (!details.line) {\n return null\n }\n\n return (\n <div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>\n )\n}\n\nfunction mapToLegacyDetails(details: ContentLakeQueryError['details']) {\n if (!details || typeof details.query !== 'string' || typeof details.start !== 'number') {\n return {}\n }\n\n const {query, start, end} = details\n const lineStart = query.slice(0, start).lastIndexOf('\\n') + 1\n const lineNumber = (query.slice(0, lineStart).match(/\\n/g) || []).length\n const line = query.slice(lineStart, query.indexOf('\\n', lineStart))\n const column = start - lineStart\n const columnEnd = typeof end === 'number' ? end - lineStart : undefined\n\n return {line, lineNumber, column, columnEnd}\n}\n\nfunction dashLine(column: number, columnEnd: number | undefined): string {\n const line = '-'.repeat(column)\n const hats = `^`.repeat(columnEnd ? columnEnd - column : 1)\n return `${line}${hats}`\n}\n","import {type ClientPerspective, isHttpError} from '@sanity/client'\nimport {Stack, Text} from '@sanity/ui'\nimport {useTranslation} from 'sanity'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getUnsatisfiedApiVersionCapability} from '../util/apiVersionCapabilities'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {QueryErrorDetails} from './QueryErrorDetails'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface QueryErrorDialogProps {\n error: Error\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport function QueryErrorDialog(props: QueryErrorDialogProps) {\n const {error, apiVersion, perspective, variant} = props\n const {t} = useTranslation(visionLocaleNamespace)\n const unsatisfiedCapability = getUnsatisfiedApiVersionCapability({\n statusCode: isHttpError(error) ? error.statusCode : undefined,\n apiVersion,\n perspective,\n variant,\n })\n\n return (\n <Stack gap={5} marginTop={2}>\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Stack>\n )\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const codeFamilyVar = createVar()\nexport const codeFontSizeVar = createVar()\nexport const codeLineHeightVar = createVar()\nexport const space0Var = createVar()\nexport const space2Var = createVar()\nexport const space4Var = createVar()\nexport const space4HalfVar = createVar()\nexport const syntaxPropertyVar = createVar()\nexport const syntaxConstantVar = createVar()\nexport const syntaxStringVar = createVar()\nexport const syntaxBooleanVar = createVar()\nexport const syntaxNumberVar = createVar()\n\nexport const resultViewWrapper = style({})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector, ${resultViewWrapper} .json-inspector .json-inspector__selection`,\n {\n fontFamily: codeFamilyVar,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n color: 'var(--card-code-fg-color)',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__leaf`, {\n paddingLeft: space4Var,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf.json-inspector__leaf_root`,\n {\n paddingTop: space0Var,\n paddingLeft: 0,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line`, {\n display: 'block',\n position: 'relative',\n cursor: 'default',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line::after`, {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: '-200px',\n right: '-50px',\n bottom: 0,\n zIndex: -1,\n pointerEvents: 'none',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line:hover::after`, {\n background: 'var(--card-code-bg-color)',\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line`,\n {\n cursor: 'pointer',\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▸ '\",\n marginLeft: `calc(0px - ${space4Var})`,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_expanded.json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▾ '\",\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__radio, ${resultViewWrapper} .json-inspector .json-inspector__flatpath`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value`, {\n marginLeft: space4HalfVar,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key + .json-inspector__value`,\n {\n margin: 0,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__key`, {\n color: syntaxPropertyVar,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__value_helper, ${resultViewWrapper} .json-inspector .json-inspector__value_null`,\n {\n color: syntaxConstantVar,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__not-found`, {\n paddingTop: space2Var,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_string`, {\n color: syntaxStringVar,\n wordBreak: 'break-word',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_boolean`, {\n color: syntaxBooleanVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_number`, {\n color: syntaxNumberVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original`, {\n display: 'inline-block',\n padding: '0 6px',\n cursor: 'pointer',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover`, {\n color: 'inherit',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original::before`, {\n content: \"'↔'\",\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover::after`, {\n content: \"' expand'\",\n})\n","import {JsonInspector} from '@rexxars/react-json-inspector'\nimport {LinkIcon} from '@sanity/icons/Link'\nimport {rem, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport LRU from 'quick-lru'\nimport {type ReactNode} from 'react'\nimport {useDataset} from 'sanity'\nimport {IntentLink} from 'sanity/router'\n\nimport {\n codeFamilyVar,\n codeFontSizeVar,\n codeLineHeightVar,\n resultViewWrapper,\n space0Var,\n space2Var,\n space4HalfVar,\n space4Var,\n syntaxBooleanVar,\n syntaxConstantVar,\n syntaxNumberVar,\n syntaxPropertyVar,\n syntaxStringVar,\n} from './ResultView.css'\n\nconst lru = new LRU({maxSize: 50000})\n\nfunction ResultViewWrapper({children}: {children: ReactNode}) {\n const {color, font, space} = useThemeV2()\n const codeSize = font.code.sizes[2]\n\n return (\n <div\n className={resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>\n )\n}\n\nexport function ResultView(props: {data: unknown; datasetName: string}): React.JSX.Element {\n const {data, datasetName} = props\n const workspaceDataset = useDataset()\n\n if (isRecord(data) || Array.isArray(data)) {\n return (\n <ResultViewWrapper>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={workspaceDataset === datasetName ? DocumentEditLabel : undefined}\n />\n </ResultViewWrapper>\n )\n }\n\n return <Code language=\"json\">{JSON.stringify(data)}</Code>\n}\n\nfunction DocumentEditLabel(props: {value: string; isKey: boolean; keypath: string}) {\n if (props.isKey || (!props.keypath.endsWith('_id') && !props.keypath.endsWith('_ref'))) {\n return null\n }\n\n return (\n <IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>\n )\n}\n\nfunction isExpanded(keyPath: string, value: unknown): boolean {\n const depthLimit = 4\n const cached = lru.get(keyPath) as boolean | undefined\n\n if (typeof cached === 'boolean') {\n return cached\n }\n\n const segments = keyPath.split('.', depthLimit)\n if (segments.length === depthLimit) {\n return false\n }\n\n if (Array.isArray(value)) {\n return true\n }\n\n return isRecord(value) && !segments.some((key) => isArrayKeyOverLimit(key))\n}\n\nfunction toggleExpanded(event: {path: string}): void {\n const {path} = event\n const current = lru.get(path)\n\n if (current === undefined) {\n // something is wrong\n return\n }\n\n lru.set(path, !current)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst numeric = /^\\d+$/\nfunction isArrayKeyOverLimit(segment: string, limit = 10) {\n return numeric.test(segment) && parseInt(segment, 10) > limit\n}\n","import {DocumentSheetIcon} from '@sanity/icons/DocumentSheet'\nimport {Button} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\n\nimport {visionLocaleNamespace} from '../i18n'\n\ninterface SaveButtonProps {\n blobUrl: string | undefined\n}\n\nexport function SaveCsvButton({blobUrl}: SaveButtonProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n // An anchor cannot be disabled, so when there is nothing to download we render a plain\n // disabled button (which also prevents the click natively) instead of a disabled link.\n if (!blobUrl) {\n return (\n <Tooltip content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>\n )\n }\n\n return (\n <Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n\nexport function SaveJsonButton({blobUrl}: SaveButtonProps) {\n return (\n <Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n","import {type ClientPerspective, type MutationEvent} from '@sanity/client'\nimport {Text} from '@sanity/ui'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getCsvBlobUrl, getJsonBlobUrl} from '../util/getBlobUrl'\nimport {DelayedSpinner} from './DelayedSpinner'\nimport {QueryErrorDialog} from './QueryErrorDialog'\nimport {ResultView} from './ResultView'\nimport {SaveCsvButton, SaveJsonButton} from './SaveResultButtons'\nimport {\n DownloadsCard,\n InputBackgroundContainer,\n Result,\n ResultContainer,\n ResultFooter,\n ResultInnerContainer,\n ResultOuterContainer,\n SaveResultLabel,\n StyledLabel,\n TimingsCard,\n TimingsTextContainer,\n} from './VisionGui.styled'\n\ninterface VisionGuiResultProps {\n error?: Error | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n queryInProgress: boolean\n queryResult?: unknown | undefined\n listenInProgress: boolean\n listenMutations: MutationEvent[]\n dataset: string\n queryTime: number | undefined\n e2eTime: number | undefined\n compactFooter?: boolean\n}\n\nexport function VisionGuiResult({\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n const hasResult = !error && !queryInProgress && typeof queryResult !== 'undefined'\n\n return (\n <ResultOuterContainer direction=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justify={compactFooter ? 'flex-start' : 'space-between'}\n align={compactFooter ? 'stretch' : undefined}\n direction={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer align=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>\n )\n}\n\nfunction SaveResultButtons({queryResult}: {queryResult: unknown}) {\n // This only renders when `hasResult` is true, and falsy values like `null`, `0`, `false` or ''\n // are valid GROQ results — the resolvers themselves return `undefined` for non-encodable input.\n const jsonUrl = getJsonBlobUrl(queryResult)\n const csvUrl = getCsvBlobUrl(queryResult)\n\n return (\n <>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>\n )\n}\n","import {SplitPane} from '@rexxars/react-split-pane'\nimport {\n type ClientPerspective,\n type ListenEvent,\n type MutationEvent,\n type ReleaseDocument,\n type StackablePerspective,\n} from '@sanity/client'\nimport {ChevronLeftIcon} from '@sanity/icons/ChevronLeft'\nimport {ChevronRightIcon} from '@sanity/icons/ChevronRight'\nimport {Button, Flex} from '@sanity/ui'\nimport {useToast} from '@sanity/ui/toast'\nimport {isHotkey} from 'is-hotkey-esm'\nimport {type ChangeEvent, useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {\n getReleaseIdFromReleaseDocumentId,\n isCardinalityOneRelease,\n type PerspectiveStack,\n sortReleases,\n useActiveReleases,\n useClient,\n usePerspective,\n useScheduledDraftsEnabled,\n useTranslation,\n useWorkspace,\n VARIANTS_STUDIO_CLIENT_OPTIONS,\n} from 'sanity'\nimport {Box} from 'ui5'\nimport {useEffectEvent} from 'use-effect-event'\n\nimport {API_VERSIONS, DEFAULT_API_VERSION} from '../apiVersions'\nimport {groqExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActivePerspective,\n getActiveVariant,\n isSupportedPerspective,\n isVirtualPerspective,\n type SupportedPerspective,\n} from '../perspectives'\nimport {type VisionProps} from '../types'\nimport {encodeQueryString} from '../util/encodeQueryString'\nimport {isVisionPasteTarget} from '../util/isVisionPasteTarget'\nimport {getLocalStorage} from '../util/localStorage'\nimport {parseApiQueryString, type ParsedApiQueryString} from '../util/parseApiQueryString'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {validateApiVersion} from '../util/validateApiVersion'\nimport {ParamsEditor, parseParams} from './ParamsEditor'\nimport {QueryRecall} from './QueryRecall'\nimport {usePaneSize} from './usePaneSize'\nimport {\n InputBackgroundContainerLeft,\n InputContainer,\n QueryRecallPaneContainer,\n QueryRecallPaneWrapper,\n Root,\n SplitpaneContainer,\n StyledLabel,\n} from './VisionGui.styled'\nimport {VisionGuiControls} from './VisionGuiControls'\nimport {VisionGuiHeader} from './VisionGuiHeader'\nimport {VisionGuiResult} from './VisionGuiResult'\n\nfunction nodeContains(node: Node, other: EventTarget | Node | null): boolean {\n if (!node || !other) {\n return false\n }\n\n return node === other || !!(node.compareDocumentPosition(other as Node) & 16)\n}\n\n// Match Sanity API URLs with any domain (supports custom CDN domains like foolcdn.com)\nconst sanityUrl = /\\/(vX|v1|v\\d{4}-\\d\\d-\\d\\d)\\/.*?(?:query|listen)\\/(.*?)\\?(.*)/\nconst VARIANTS_API_VERSION = prefixApiVersion(VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion)\n\nconst isRunHotkey = (event: KeyboardEvent) =>\n isHotkey('ctrl+enter', event) || isHotkey('mod+enter', event)\n\ninterface Subscription {\n unsubscribe: () => void\n}\nexport interface Params {\n raw: string\n parsed: Record<string, unknown> | undefined\n valid: boolean\n error: string | undefined\n}\n\ninterface QueryExecutionOptions {\n apiVersion?: string\n dataset?: string\n perspective?: SupportedPerspective | undefined\n query?: string\n params?: Record<string, unknown>\n}\n\ninterface VisionGuiProps extends VisionProps {\n datasets: string[]\n projectId: string | undefined\n defaultDataset: string\n}\n\nexport interface ParsedUrlState {\n query: string\n params: Record<string, unknown>\n rawParams: string\n dataset: string\n apiVersion: string\n customApiVersion: string | false | undefined\n perspective: SupportedPerspective | undefined\n url: string\n}\n\nexport function VisionGui(props: VisionGuiProps) {\n const {datasets, config, projectId, defaultDataset} = props\n const toast = useToast()\n const {t} = useTranslation(visionLocaleNamespace)\n const {perspectiveStack, selectedVariantName} = usePerspective()\n const isScheduledDraftsEnabled = useScheduledDraftsEnabled()\n const {data: releases = []} = useActiveReleases()\n const workspace = useWorkspace()\n const isDraftModelEnabled = workspace.document.drafts.enabled\n\n const editorQueryRef = useRef<VisionCodeMirrorHandle>(null)\n const editorParamsRef = useRef<VisionCodeMirrorHandle>(null)\n const visionRootRef = useRef<HTMLDivElement | null>(null)\n const customApiVersionElementRef = useRef<HTMLInputElement | null>(null)\n const querySubscriptionRef = useRef<Subscription | undefined>(undefined)\n const listenSubscriptionRef = useRef<Subscription | undefined>(undefined)\n\n const [localStorage] = useState(() => getLocalStorage(projectId || 'default'))\n\n const storedDataset = localStorage.get('dataset', defaultDataset)\n const storedApiVersion = localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )\n const storedQuery = localStorage.get('query', '')\n const storedParams = localStorage.get('params', '{\\n \\n}')\n const storedPerspective = localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )\n\n const [dataset, setDataset] = useState<string>(() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n })\n const [perspective, setPerspectiveState] = useState<SupportedPerspective | undefined>(\n storedPerspective || 'raw',\n )\n const activeVariant = getActiveVariant(perspective, selectedVariantName)\n\n const [apiVersion, setApiVersion] = useState<string>(() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION,\n )\n const [customApiVersion, setCustomApiVersion] = useState<string | false>(() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion,\n )\n const isValidApiVersion = customApiVersion ? validateApiVersion(customApiVersion) : true\n\n const [url, setUrl] = useState<string | undefined>(undefined)\n const [query, setQuery] = useState<string>(() =>\n typeof storedQuery === 'string' ? storedQuery : '',\n )\n const [rawParams, setRawParams] = useState<string>(storedParams)\n const params = useMemo(() => parseParams(rawParams, t), [rawParams, t])\n const [queryResult, setQueryResult] = useState<unknown | undefined>(undefined)\n const [listenMutations, setListenMutations] = useState<MutationEvent[]>([])\n const [error, setError] = useState<Error | undefined>(undefined)\n const [queryTime, setQueryTime] = useState<number | undefined>(undefined)\n const [e2eTime, setE2eTime] = useState<number | undefined>(undefined)\n const [queryInProgress, setQueryInProgress] = useState<boolean>(false)\n const [listenInProgress, setListenInProgress] = useState<boolean>(false)\n const [isQueryRecallCollapsed, setIsQueryRecallCollapsed] = useState(false)\n\n const {paneSizeOptions, isNarrowBreakpoint} = usePaneSize({visionRootRef})\n\n // Compute scheduled drafts perspective stack\n const scheduledDraftsStack = useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])\n\n const userApiVersion = activeVariant\n ? VARIANTS_API_VERSION\n : isValidApiVersion && customApiVersion\n ? customApiVersion\n : apiVersion\n\n // Client with memoized initial value\n const _client = useClient({\n apiVersion: userApiVersion,\n })\n const client = useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])\n\n const cancelQuerySubscription = useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])\n\n const cancelListenerSubscription = useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])\n\n const handleQueryExecution = useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )\n\n const setPerspective = useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution],\n )\n\n const handleChangeDataset = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution],\n )\n\n const changeApiVersion = useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )\n\n const handleChangeApiVersion = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )\n\n // Handle custom API version change\n const handleCustomApiVersionChange = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )\n\n // Handle perspective change\n const handleChangePerspective = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )\n\n const handleListenerEvent = useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])\n const handleListenExecution = useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])\n\n const handleParamsChange = useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )\n\n // Get object of state values from provided URL\n const getStateFromUrl = useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(sanityUrl)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )\n\n // Use state object from parsed URL to update state\n const setStateFromParsedUrl = useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution],\n )\n\n const handlePaste = useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )\n\n useEffect(() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }, [handleKeyDown, handlePaste])\n\n useEffect(() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }, [cancelQuerySubscription, cancelListenerSubscription])\n\n const handleStudioVariantChange = useEffectEvent(() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n })\n\n useEffect(() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [activeVariant])\n\n const handleStudioPerspectiveChange = useEffectEvent((stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n })\n // Handle pinned perspective changes\n useEffect(() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [perspectiveStack])\n\n const generateUrl = useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )\n\n return (\n <Root\n direction=\"column\"\n height=\"fill\"\n ref={visionRootRef}\n sizing=\"border\"\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>\n )\n}\n","import {type SanityClient} from '@sanity/client'\nimport {useMemo} from 'react'\nimport {type ObservablePromise, useObservablePromise} from 'react-rx'\nimport {catchError, map, type Observable, of} from 'rxjs'\n\nimport {type VisionConfig} from '../types'\n\nexport function useDatasets({\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}): ObservablePromise<string[] | Error> {\n const datasets$: Observable<string[] | Error> = useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])\n\n return useObservablePromise(datasets$)\n}\n","import {Flex} from '@sanity/ui'\nimport {Suspense, use} from 'react'\nimport {type ObservablePromise} from 'react-rx'\nimport {useClient} from 'sanity'\n\nimport {DelayedSpinner} from '../components/DelayedSpinner'\nimport {VisionGui} from '../components/VisionGui'\nimport {useDatasets} from '../hooks/useDatasets'\nimport {type VisionProps} from '../types'\n\nexport function VisionContainer(props: VisionProps) {\n const datasetsClient = useClient({apiVersion: 'v2025-06-27'})\n const datasetsPromise = useDatasets({client: datasetsClient, datasets: props.config.datasets})\n\n return (\n <Suspense\n fallback={\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>\n )\n}\n\nfunction LoadedVisionContainer({\n datasetsPromise,\n ...props\n}: VisionProps & {datasetsPromise: ObservablePromise<string[] | Error>}) {\n const loadedDatasets = use(datasetsPromise)\n\n const datasets =\n loadedDatasets instanceof Error\n ? // On error, use the clients configured dataset\n [props.client.config().dataset || 'production']\n : // Otherwise use the loaded list, obviously\n loadedDatasets\n\n const projectId = props.client.config().projectId\n const defaultDataset = props.config.defaultDataset || props.client.config().dataset || datasets[0]\n\n return (\n <VisionGui\n key={projectId}\n {...props}\n datasets={datasets}\n projectId={projectId}\n defaultDataset={defaultDataset}\n />\n )\n}\n","/* oxlint-disable @sanity/i18n/no-attribute-string-literals */\n/* oxlint-disable i18next/no-literal-string */\nimport {Button, Card, Container, Heading, Stack} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Component, type PropsWithChildren} from 'react'\n\nimport {clearLocalStorage} from '../util/localStorage'\n\n/**\n * @internal\n */\nexport type VisionErrorBoundaryProps = PropsWithChildren\n\n/**\n * @internal\n */\ninterface VisionErrorBoundaryState {\n error: string | null\n numRetries: number\n}\n\n/**\n * @internal\n */\nexport class VisionErrorBoundary extends Component<\n VisionErrorBoundaryProps,\n VisionErrorBoundaryState\n> {\n constructor(props: VisionErrorBoundaryProps) {\n super(props)\n this.state = {error: null, numRetries: 0}\n }\n\n static getDerivedStateFromError(error: unknown) {\n // oxlint-disable-next-line restrict-template-expressions - @TODO use new Error(msg, {cause: error}) instead of casting to string, and console.error() the full error\n return {error: error instanceof Error ? error.message : `${error}`}\n }\n\n handleRetryRender = () =>\n this.setState((prev) => ({error: null, numRetries: prev.numRetries + 1}))\n\n handleRetryWithCacheClear = () => {\n clearLocalStorage()\n this.handleRetryRender()\n }\n\n render() {\n if (!this.state.error) {\n return this.props.children\n }\n\n const message = this.state.error\n const withCacheClear = this.state.numRetries > 0\n\n return (\n <Card\n height=\"fill\"\n overflow=\"auto\"\n paddingY={[4, 5, 6, 7]}\n paddingX={4}\n sizing=\"border\"\n tone=\"critical\"\n >\n <Container width={3}>\n <Stack gap={4}>\n <div>\n <Button\n onClick={withCacheClear ? this.handleRetryWithCacheClear : this.handleRetryRender}\n text={withCacheClear ? 'Clear cache and retry' : 'Retry'}\n tone=\"default\"\n />\n </div>\n\n <Heading>An error occurred</Heading>\n\n <Card border radius={2} overflow=\"auto\" padding={4} tone=\"inherit\">\n <Stack gap={4}>\n {message && (\n <Code size={1}>\n <strong>Error: {message}</strong>\n </Code>\n )}\n </Stack>\n </Card>\n </Stack>\n </Container>\n </Card>\n )\n }\n}\n","import {type Tool, useClient} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from './apiVersions'\nimport {VisionContainer} from './containers/VisionContainer'\nimport {VisionErrorBoundary} from './containers/VisionErrorBoundary'\nimport {type VisionConfig} from './types'\n\ninterface SanityVisionProps {\n tool: Tool<VisionConfig>\n}\n\nfunction SanityVision(props: SanityVisionProps) {\n const client = useClient({apiVersion: '1'})\n const config: VisionConfig = {\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }\n\n return (\n <VisionErrorBoundary>\n <VisionContainer client={client} config={config} />\n </VisionErrorBoundary>\n )\n}\n\nexport default SanityVision\n"],"mappings":"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"}