UNPKG

@sanity/vision

Version:

Sanity plugin for running/debugging GROQ-queries against Sanity datasets

1,115 lines (1,078 loc) 73.7 kB
"use strict"; var jsxRuntime = require("react/jsx-runtime"), reactCompilerRuntime = require("react-compiler-runtime"), sanity = require("sanity"), react = require("react"), ui = require("@sanity/ui"), reactSplitPane = require("@rexxars/react-split-pane"), isHotkeyEsm = require("is-hotkey-esm"), useEffectEvent = require("use-effect-event"), CodeMirror = require("@uiw/react-codemirror"), autocomplete = require("@codemirror/autocomplete"), commands = require("@codemirror/commands"), langJavascript = require("@codemirror/lang-javascript"), language = require("@codemirror/language"), search = require("@codemirror/search"), view = require("@codemirror/view"), highlight = require("@lezer/highlight"), color = require("@sanity/color"), styledComponents = require("styled-components"), index = require("./index.js"), icons = require("@sanity/icons"), debounce = require("lodash/debounce.js"), JSON5 = require("json5"), json2Csv = require("json-2-csv"), reactJsonInspector = require("@rexxars/react-json-inspector"), LRU = require("quick-lru"), router = require("sanity/router"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var CodeMirror__default = /* @__PURE__ */ _interopDefaultCompat(CodeMirror), debounce__default = /* @__PURE__ */ _interopDefaultCompat(debounce), JSON5__default = /* @__PURE__ */ _interopDefaultCompat(JSON5), LRU__default = /* @__PURE__ */ _interopDefaultCompat(LRU); const API_VERSIONS = ["v1", "vX", "v2021-03-25", "v2021-10-21", "v2022-03-07", "v2025-02-19", `v${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`], [DEFAULT_API_VERSION] = API_VERSIONS.slice(-1); function DelayedSpinner(props) { const $ = reactCompilerRuntime.c(5), [show, setShow] = react.useState(!1); let t0, t1; $[0] !== props.delay ? (t0 = () => { const timer = setTimeout(() => setShow(!0), props.delay || 500); return () => clearTimeout(timer); }, t1 = [props.delay], $[0] = props.delay, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), react.useEffect(t0, t1); let t2; return $[3] !== show ? (t2 = show ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, { muted: !0, size: 4 }) : null, $[3] = show, $[4] = t2) : t2 = $[4], t2; } const codemirrorExtensions = [[langJavascript.javascriptLanguage], view.lineNumbers(), view.highlightActiveLine(), view.highlightActiveLineGutter(), search.highlightSelectionMatches(), view.highlightSpecialChars(), language.indentOnInput(), language.bracketMatching(), autocomplete.closeBrackets(), commands.history(), view.drawSelection(), language.syntaxHighlighting(language.defaultHighlightStyle, { fallback: !0 }), view.keymap.of([ // Override the default keymap for Mod-Enter to not insert a new line, we have a custom event handler for executing queries { key: "Mod-Enter", run: () => !0 }, // Add the default keymap and history keymap commands.defaultKeymap, commands.historyKeymap ].flat().filter(Boolean))]; function useCodemirrorTheme(theme) { const $ = reactCompilerRuntime.c(7); let t0, t1; $[0] !== theme ? (t1 = createTheme(theme), $[0] = theme, $[1] = t1) : t1 = $[1], t0 = t1; const cmTheme = t0; let t2, t3; $[2] !== theme ? (t3 = language.syntaxHighlighting(createHighlight(theme)), $[2] = theme, $[3] = t3) : t3 = $[3], t2 = t3; const cmHighlight = t2; let t4; return $[4] !== cmHighlight || $[5] !== cmTheme ? (t4 = [cmTheme, cmHighlight], $[4] = cmHighlight, $[5] = cmTheme, $[6] = t4) : t4 = $[6], t4; } function createTheme(theme) { const { color: color$1, fonts } = theme.sanity, card = color$1.card.enabled, cursor = color.hues.blue[color$1.dark ? 400 : 500].hex, selection = color.hues.gray[theme.sanity.color.dark ? 900 : 100].hex; return view.EditorView.theme({ "&": { color: card.fg, backgroundColor: card.bg }, ".cm-content": { caretColor: cursor }, ".cm-editor": { fontFamily: fonts.code.family, fontSize: ui.rem(fonts.code.sizes[1].fontSize), lineHeight: "inherit" }, ".cm-cursor, .cm-dropCursor": { borderLeftColor: cursor }, "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: selection }, ".cm-panels": { backgroundColor: card.bg, color: card.fg }, ".cm-panels.cm-panels-top": { borderBottom: `2px solid ${card.border}` }, ".cm-panels.cm-panels-bottom": { borderTop: `2px solid ${card.border}` } }, { dark: color$1.dark }); } function createHighlight(theme) { const c = theme.sanity.color.base, s = theme.sanity.color.syntax; return language.HighlightStyle.define([{ tag: highlight.tags.keyword, color: s.keyword }, { tag: [highlight.tags.propertyName, highlight.tags.name, highlight.tags.deleted, highlight.tags.character, highlight.tags.macroName], color: s.property }, { tag: [highlight.tags.function(highlight.tags.variableName), highlight.tags.labelName], color: s.function }, { tag: [highlight.tags.color, highlight.tags.constant(highlight.tags.name), highlight.tags.standard(highlight.tags.name)], color: s.variable }, { tag: [highlight.tags.definition(highlight.tags.name), highlight.tags.separator], color: s.constant }, { tag: [highlight.tags.typeName, highlight.tags.className, highlight.tags.number, highlight.tags.changed, highlight.tags.annotation, highlight.tags.modifier, highlight.tags.self, highlight.tags.namespace], color: s.number }, { tag: [highlight.tags.operator, highlight.tags.operatorKeyword, highlight.tags.url, highlight.tags.escape, highlight.tags.regexp, highlight.tags.link, highlight.tags.special(highlight.tags.string)], color: s.operator }, { tag: [highlight.tags.meta, highlight.tags.comment], color: s.comment }, { tag: highlight.tags.strong, fontWeight: "bold" }, { tag: highlight.tags.emphasis, fontStyle: "italic" }, { tag: highlight.tags.strikethrough, textDecoration: "line-through" }, { tag: highlight.tags.heading, fontWeight: "bold", color: s.property }, { tag: [highlight.tags.atom, highlight.tags.bool, highlight.tags.special(highlight.tags.variableName)], color: s.boolean }, { tag: [highlight.tags.processingInstruction, highlight.tags.string, highlight.tags.inserted], color: s.string }, { tag: highlight.tags.invalid, color: c.fg }]); } const EditorRoot = styledComponents.styled.div` width: 100%; box-sizing: border-box; height: 100%; overflow: hidden; overflow: clip; position: relative; display: flex; & .cm-theme { width: 100%; } & .cm-editor { height: 100%; font-size: 16px; line-height: 21px; } & .cm-line { padding-left: ${({ theme }) => ui.rem(theme.sanity.space[3])}; } & .cm-content { border-right-width: ${({ theme }) => ui.rem(theme.sanity.space[4])} !important; padding-top: ${({ theme }) => ui.rem(theme.sanity.space[5])}; } `, VisionCodeMirror = react.forwardRef((props, ref) => { const $ = reactCompilerRuntime.c(7), [initialValue] = react.useState(props.initialValue), sanityTheme = ui.useTheme(), theme = useCodemirrorTheme(sanityTheme), codeMirrorRef = react.useRef(null); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = (newContent) => { const editorView = codeMirrorRef.current?.view; if (!editorView) return; const currentDoc = editorView.state.doc.toString(); newContent !== currentDoc && editorView.dispatch({ changes: { from: 0, to: currentDoc.length, insert: newContent }, selection: CodeMirror.EditorSelection.cursor(newContent.length) }); }, $[0] = t0) : t0 = $[0]; const resetEditorContent = t0; let t1, t2; $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => ({ resetEditorContent }), t2 = [resetEditorContent], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), react.useImperativeHandle(ref, t1, t2); let t3; return $[3] !== initialValue || $[4] !== props.onChange || $[5] !== theme ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(EditorRoot, { children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror__default.default, { ref: codeMirrorRef, basicSetup: !1, theme, extensions: codemirrorExtensions, value: initialValue, onChange: props.onChange }) }), $[3] = initialValue, $[4] = props.onChange, $[5] = theme, $[6] = t3) : t3 = $[6], t3; }); VisionCodeMirror.displayName = "VisionCodeMirror"; const SUPPORTED_PERSPECTIVES = ["pinnedRelease", "raw", "published", "drafts"], VIRTUAL_PERSPECTIVES = ["pinnedRelease"]; function isSupportedPerspective(p) { return SUPPORTED_PERSPECTIVES.includes(p); } function isVirtualPerspective(maybeVirtualPerspective) { return typeof maybeVirtualPerspective == "string" && VIRTUAL_PERSPECTIVES.includes(maybeVirtualPerspective); } function hasPinnedPerspective({ selectedPerspectiveName }) { return typeof selectedPerspectiveName < "u"; } function getActivePerspective({ visionPerspective, perspectiveStack }) { return visionPerspective !== "pinnedRelease" ? visionPerspective : perspectiveStack; } function encodeQueryString(query, params = {}, options = {}) { const searchParams = new URLSearchParams(); searchParams.set("query", query); for (const [key, value] of Object.entries(params)) searchParams.set(`$${key}`, JSON.stringify(value)); for (const [key, value] of Object.entries(options)) value && searchParams.set(key, `${value}`); return `?${searchParams}`; } function isPlainObject(obj) { return !!obj && typeof obj == "object" && Object.prototype.toString.call(obj) === "[object Object]"; } const hasLocalStorage = supportsLocalStorage(), keyPrefix = "sanityVision:"; function clearLocalStorage() { if (hasLocalStorage) for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); key?.startsWith(keyPrefix) && localStorage.removeItem(key); } } function getLocalStorage(namespace) { const storageKey = `${keyPrefix}${namespace}`; let loadedState = null; return { get, set, merge }; function get(key, defaultVal) { const state = ensureState(); return typeof state[key] > "u" ? defaultVal : state[key]; } function set(key, value) { const state = ensureState(); return state[key] = value, localStorage.setItem(storageKey, JSON.stringify(loadedState)), value; } function merge(props) { const state = { ...ensureState(), ...props }; return localStorage.setItem(storageKey, JSON.stringify(state)), state; } function ensureState() { return loadedState === null && (loadedState = loadState()), loadedState; } function loadState() { if (!hasLocalStorage) return {}; try { const stored = JSON.parse(localStorage.getItem(storageKey) || "{}"); return isPlainObject(stored) ? stored : {}; } catch { return {}; } } } function supportsLocalStorage() { const mod = "lsCheck"; try { return localStorage.setItem(mod, mod), localStorage.removeItem(mod), !0; } catch { return !1; } } function parseApiQueryString(qs) { const params = {}, options = {}; for (const [key, value] of qs.entries()) { if (key[0] === "$") { params[key.slice(1)] = JSON.parse(value); continue; } if (key === "perspective") { options[key] = value; continue; } } return { query: qs.get("query") || "", params, options }; } function prefixApiVersion(version) { return version[0] !== "v" && version !== "other" ? `v${version}` : version; } function validateApiVersion(apiVersion) { const parseableApiVersion = apiVersion.replace(/^v/, "").trim().toUpperCase(); return parseableApiVersion.length > 0 && (parseableApiVersion === "X" || parseableApiVersion === "1" || /^\d{4}-\d{2}-\d{2}$/.test(parseableApiVersion) && !isNaN(Date.parse(parseableApiVersion))); } function tryParseParams(val, t) { try { const parsed = val ? JSON5__default.default.parse(val) : {}; return typeof parsed == "object" && parsed && !Array.isArray(parsed) ? parsed : {}; } catch (err) { return err.message = `${t("params.error.params-invalid-json")}: ${err.message.replace("JSON5:", "")}`, err; } } const Root = styledComponents.styled(ui.Flex)` .sidebarPanes .Pane { overflow-y: auto; overflow-x: hidden; } & .Resizer { background: var(--card-border-color); opacity: 1; z-index: 1; box-sizing: border-box; background-clip: padding-box; border: solid transparent; } & .Resizer:hover { border-color: var(--card-shadow-ambient-color); } & .Resizer.horizontal { height: 11px; margin: -5px 0; border-width: 5px 0; cursor: row-resize; width: 100%; z-index: 4; } & .Resizer.vertical { width: 11px; margin: 0 -5px; border-width: 0 5px; cursor: col-resize; z-index: 2; /* To prevent the resizer from being hidden behind CodeMirror scroll area */ } .Resizer.disabled { cursor: not-allowed; } .Resizer.disabled:hover { border-color: transparent; } `; Root.displayName = "Root"; const Header = styledComponents.styled(ui.Card)` border-bottom: 1px solid var(--card-border-color); `, StyledLabel = styledComponents.styled(ui.Label)` flex: 1; `, SplitpaneContainer = styledComponents.styled(ui.Box)` position: relative; `, QueryCopyLink = styledComponents.styled.a` cursor: pointer; margin-right: auto; `, InputBackgroundContainer = styledComponents.styled(ui.Box)` position: absolute; top: 1rem; left: 0; padding: 0; margin: 0; z-index: 10; right: 0; ${StyledLabel} { user-select: none; } `, InputBackgroundContainerLeft = styledComponents.styled(InputBackgroundContainer)` // This is so its aligned with the gutters of CodeMirror left: 33px; `, InputContainer = styledComponents.styled(ui.Card)` width: 100%; height: 100%; position: relative; flex-direction: column; `, ResultOuterContainer = styledComponents.styled(ui.Flex)` height: 100%; `, ResultInnerContainer = styledComponents.styled(ui.Box)` position: relative; `, ResultContainer = styledComponents.styled(ui.Card)` height: 100%; width: 100%; position: absolute; max-width: 100%; ${({ $isInvalid }) => $isInvalid && styledComponents.css` &:after { background-color: var(--card-bg-color); content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 100%; } `} `, Result = styledComponents.styled(ui.Box)` position: relative; width: 100%; height: 100%; z-index: 20; `, ResultFooter = styledComponents.styled(ui.Flex)` border-top: 1px solid var(--card-border-color); `, TimingsCard = styledComponents.styled(ui.Card)` position: relative; `; styledComponents.styled(ui.Box)` width: 100%; height: 100%; `; const TimingsTextContainer = styledComponents.styled(ui.Flex)` height: 100%; min-height: ${({ theme }) => ui.rem(theme.sanity.space[3] * 2 + theme.sanity.fonts.text.sizes[2].lineHeight - theme.sanity.fonts.text.sizes[2].ascenderHeight - theme.sanity.fonts.text.sizes[2].descenderHeight)}; `, DownloadsCard = styledComponents.styled(ui.Card)` position: relative; `, SaveResultLabel = styledComponents.styled(ui.Text)` transform: initial; &:before, &:after { content: none; } > span { display: flex !important; gap: ${({ theme }) => ui.rem(theme.sanity.space[3])}; align-items: center; } `, ControlsContainer = styledComponents.styled(ui.Box)` border-top: 1px solid var(--card-border-color); `, defaultValue = `{ }`; function ParamsEditor(props) { const $ = reactCompilerRuntime.c(33), { onChange, paramsError, hasValidParams, editorRef } = props, { t } = sanity.useTranslation(index.visionLocaleNamespace); let t0; $[0] !== props.value || $[1] !== t ? (t0 = parseParams(props.value, t), $[0] = props.value, $[1] = t, $[2] = t0) : t0 = $[2]; const { raw: value, error, parsed, valid } = t0, [isValid, setValid] = react.useState(valid), [init, setInit] = react.useState(!1); let t1, t2; $[3] !== error || $[4] !== init || $[5] !== isValid || $[6] !== onChange || $[7] !== parsed || $[8] !== value ? (t1 = () => { init || (onChange({ parsed, raw: value, valid: isValid, error }), setInit(!0)); }, t2 = [error, init, isValid, onChange, parsed, value], $[3] = error, $[4] = init, $[5] = isValid, $[6] = onChange, $[7] = parsed, $[8] = value, $[9] = t1, $[10] = t2) : (t1 = $[9], t2 = $[10]), react.useEffect(t1, t2); let t3; $[11] !== onChange || $[12] !== t ? (t3 = (newValue) => { const event = parseParams(newValue, t); setValid(event.valid), onChange(event); }, $[11] = onChange, $[12] = t, $[13] = t3) : t3 = $[13]; const handleChangeRaw = t3; let t4, t5; $[14] !== handleChangeRaw ? (t5 = debounce__default.default(handleChangeRaw, 333), $[14] = handleChangeRaw, $[15] = t5) : t5 = $[15], t4 = t5; const handleChange = t4, t6 = hasValidParams ? "default" : "critical"; let t7; $[16] !== t ? (t7 = t("params.label"), $[16] = t, $[17] = t7) : t7 = $[17]; let t8; $[18] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { muted: !0, children: t7 }), $[18] = t7, $[19] = t8) : t8 = $[19]; let t9; $[20] !== paramsError ? (t9 = paramsError && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { animate: !0, placement: "top", portal: !0, content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: paramsError }), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, marginX: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.ErrorOutlineIcon, {}) }) }) }), $[20] = paramsError, $[21] = t9) : t9 = $[21]; let t10; $[22] !== t8 || $[23] !== t9 ? (t10 = /* @__PURE__ */ jsxRuntime.jsx(InputBackgroundContainerLeft, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [ t8, t9 ] }) }), $[22] = t8, $[23] = t9, $[24] = t10) : t10 = $[24]; const t11 = props.value || defaultValue; let t12; $[25] !== editorRef || $[26] !== handleChange || $[27] !== t11 ? (t12 = /* @__PURE__ */ jsxRuntime.jsx(VisionCodeMirror, { ref: editorRef, initialValue: t11, onChange: handleChange }), $[25] = editorRef, $[26] = handleChange, $[27] = t11, $[28] = t12) : t12 = $[28]; let t13; return $[29] !== t10 || $[30] !== t12 || $[31] !== t6 ? (t13 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { flex: 1, tone: t6, "data-testid": "params-editor", children: [ t10, t12 ] }), $[29] = t10, $[30] = t12, $[31] = t6, $[32] = t13) : t13 = $[32], t13; } function parseParams(value, t) { const parsedParams = tryParseParams(value, t), params = parsedParams instanceof Error ? {} : parsedParams, validationError = parsedParams instanceof Error ? parsedParams.message : void 0; return { parsed: params, raw: value, valid: !validationError, error: validationError }; } function narrowBreakpoint() { return typeof window < "u" && window.innerWidth > 600; } function calculatePaneSizeOptions(height) { let rootHeight = height; return rootHeight || (rootHeight = typeof window < "u" && typeof document < "u" ? document.body.getBoundingClientRect().height - 60 : 0), { defaultSize: rootHeight / (narrowBreakpoint() ? 2 : 1), size: rootHeight > 550 ? void 0 : rootHeight * 0.4, allowResize: rootHeight > 550, minSize: Math.min(170, Math.max(170, rootHeight / 2)), maxSize: rootHeight > 650 ? rootHeight * 0.7 : rootHeight * 0.6 }; } function usePaneSize(t0) { const $ = reactCompilerRuntime.c(7), { visionRootRef } = t0, [isNarrowBreakpoint, setIsNarrowBreakpoint] = react.useState(_temp$3), [paneSizeOptions, setPaneSizeOptions] = react.useState(_temp2$1); let t1; $[0] !== visionRootRef.current ? (t1 = () => { if (!visionRootRef.current) return; const handleResize = (entries) => { setIsNarrowBreakpoint(narrowBreakpoint()); const entry = entries?.[0]; entry && setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height)); }, resizeObserver = new ResizeObserver(handleResize); return resizeObserver.observe(visionRootRef.current), () => { resizeObserver.disconnect(); }; }, $[0] = visionRootRef.current, $[1] = t1) : t1 = $[1]; let t2; $[2] !== visionRootRef ? (t2 = [visionRootRef], $[2] = visionRootRef, $[3] = t2) : t2 = $[3], react.useEffect(t1, t2); let t3; return $[4] !== isNarrowBreakpoint || $[5] !== paneSizeOptions ? (t3 = { paneSizeOptions, isNarrowBreakpoint }, $[4] = isNarrowBreakpoint, $[5] = paneSizeOptions, $[6] = t3) : t3 = $[6], t3; } function _temp2$1() { return calculatePaneSizeOptions(void 0); } function _temp$3() { return narrowBreakpoint(); } function VisionGuiControls(t0) { const $ = reactCompilerRuntime.c(30), { hasValidParams, listenInProgress, queryInProgress, onQueryExecution, onListenExecution } = t0, { t } = sanity.useTranslation(index.visionLocaleNamespace); let t1; $[0] !== t ? (t1 = t("params.error.params-invalid-json"), $[0] = t, $[1] = t1) : t1 = $[1]; let t2; $[2] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { radius: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: t1 }) }), $[2] = t1, $[3] = t2) : t2 = $[3]; let t3; $[4] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { radius: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Hotkeys, { keys: ["Ctrl", "Enter"] }) }), $[4] = t3) : t3 = $[4]; const t4 = queryInProgress ? icons.StopIcon : icons.PlayIcon, t5 = listenInProgress || !hasValidParams, t6 = queryInProgress ? "positive" : "primary"; let t7; $[5] !== queryInProgress || $[6] !== t ? (t7 = t(queryInProgress ? "action.query-cancel" : "action.query-execute"), $[5] = queryInProgress, $[6] = t, $[7] = t7) : t7 = $[7]; let t8; $[8] !== onQueryExecution || $[9] !== t4 || $[10] !== t5 || $[11] !== t6 || $[12] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t3, placement: "top", portal: !0, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { width: "fill", onClick: onQueryExecution, type: "button", icon: t4, disabled: t5, tone: t6, text: t7 }) }) }), $[8] = onQueryExecution, $[9] = t4, $[10] = t5, $[11] = t6, $[12] = t7, $[13] = t8) : t8 = $[13]; const t9 = listenInProgress ? icons.StopIcon : icons.PlayIcon; let t10; $[14] !== listenInProgress || $[15] !== t ? (t10 = t(listenInProgress ? "action.listen-cancel" : "action.listen-execute"), $[14] = listenInProgress, $[15] = t, $[16] = t10) : t10 = $[16]; const t11 = !hasValidParams, t12 = listenInProgress ? "positive" : "default"; let t13; $[17] !== onListenExecution || $[18] !== t10 || $[19] !== t11 || $[20] !== t12 || $[21] !== t9 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, marginLeft: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { width: "fill", onClick: onListenExecution, type: "button", icon: t9, text: t10, mode: "ghost", disabled: t11, tone: t12 }) }), $[17] = onListenExecution, $[18] = t10, $[19] = t11, $[20] = t12, $[21] = t9, $[22] = t13) : t13 = $[22]; let t14; $[23] !== t13 || $[24] !== t8 ? (t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "space-evenly", children: [ t8, t13 ] }), $[23] = t13, $[24] = t8, $[25] = t14) : t14 = $[25]; let t15; return $[26] !== hasValidParams || $[27] !== t14 || $[28] !== t2 ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(ControlsContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, paddingX: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t2, placement: "top", disabled: hasValidParams, portal: !0, children: t14 }) }) }), $[26] = hasValidParams, $[27] = t14, $[28] = t2, $[29] = t15) : t15 = $[29], t15; } const PerspectivePopoverContent = styledComponents.styled(ui.Box)` /* This limits the width of the popover content */ max-width: 240px; `, PerspectivePopoverLink = styledComponents.styled.a` cursor: pointer; margin-right: auto; `, Dot = styledComponents.styled.div` width: 4px; height: 4px; border-radius: 3px; box-shadow: 0 0 0 1px var(--card-bg-color); background-color: ${({ tone }) => `var(--card-badge-${tone}-dot-color)`}; `; function PerspectivePopover() { const $ = reactCompilerRuntime.c(39), [open, setOpen] = react.useState(!1), buttonRef = react.useRef(null), popoverRef = react.useRef(null); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => setOpen(_temp$2), $[0] = t0) : t0 = $[0]; const handleClick = t0, { t } = sanity.useTranslation(index.visionLocaleNamespace); let t1, t2; $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => setOpen(!1), t2 = () => [buttonRef.current, popoverRef.current], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), ui.useClickOutsideEvent(t1, t2); let t3; $[3] !== t ? (t3 = t("settings.perspectives.title"), $[3] = t, $[4] = t3) : t3 = $[4]; let t4; $[5] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { space: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "medium", children: t3 }) }), $[5] = t3, $[6] = t4) : t4 = $[6]; let t5; $[7] !== t ? (t5 = t("settings.perspectives.description"), $[7] = t, $[8] = t5) : t5 = $[8]; let t6; $[9] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { muted: !0, children: t5 }) }), $[9] = t5, $[10] = t6) : t6 = $[10]; let t7; $[11] !== t ? (t7 = t("label.new"), $[11] = t, $[12] = t7) : t7 = $[12]; let t8; $[13] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { tone: "primary", children: t7 }) }), $[13] = t7, $[14] = t8) : t8 = $[14]; let t9; $[15] !== t ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { muted: !0, children: /* @__PURE__ */ jsxRuntime.jsx(sanity.Translate, { t, i18nKey: "settings.perspective.preview-drafts-renamed-to-drafts.description" }) }), $[15] = t, $[16] = t9) : t9 = $[16]; let t10; $[17] !== t8 || $[18] !== t9 ? (t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [ t8, t9 ] }) }), $[17] = t8, $[18] = t9, $[19] = t10) : t10 = $[19]; let t11; $[20] !== t ? (t11 = null, $[20] = t, $[21] = t11) : t11 = $[21]; let t12; $[22] !== t ? (t12 = t("settings.perspectives.action.docs-link"), $[22] = t, $[23] = t12) : t12 = $[23]; let t13; $[24] !== t12 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: /* @__PURE__ */ jsxRuntime.jsxs(PerspectivePopoverLink, { href: "https://sanity.io/docs/perspectives", target: "_blank", children: [ t12, " \u2192" ] }) }) }), $[24] = t12, $[25] = t13) : t13 = $[25]; let t14; $[26] !== t10 || $[27] !== t11 || $[28] !== t13 || $[29] !== t4 || $[30] !== t6 ? (t14 = /* @__PURE__ */ jsxRuntime.jsx(PerspectivePopoverContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [ t4, t6, t10, t11, t13 ] }) }), $[26] = t10, $[27] = t11, $[28] = t13, $[29] = t4, $[30] = t6, $[31] = t14) : t14 = $[31]; let t15; $[32] === Symbol.for("react.memo_cache_sentinel") ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(Dot, { tone: "primary" }), $[32] = t15) : t15 = $[32]; let t16; $[33] !== open ? (t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { icon: icons.HelpCircleIcon, mode: "bleed", padding: 2, paddingRight: 1, tone: "primary", fontSize: 1, ref: buttonRef, onClick: handleClick, selected: open, children: t15 }), $[33] = open, $[34] = t16) : t16 = $[34]; let t17; return $[35] !== open || $[36] !== t14 || $[37] !== t16 ? (t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { content: t14, placement: "bottom-start", portal: !0, padding: 3, ref: popoverRef, open, children: t16 }), $[35] = open, $[36] = t14, $[37] = t16, $[38] = t17) : t17 = $[38], t17; } function _temp$2(o) { return !o; } const PinnedReleasePerspectiveOption = (t0) => { const $ = reactCompilerRuntime.c(9), { pinnedPerspective, t } = t0, name = typeof pinnedPerspective.selectedPerspective == "object" ? pinnedPerspective.selectedPerspective.metadata.title : pinnedPerspective.selectedPerspectiveName; let t1; $[0] !== pinnedPerspective || $[1] !== t ? (t1 = hasPinnedPerspective(pinnedPerspective) ? `(${t("settings.perspectives.pinned-release-label")})` : t("settings.perspectives.pinned-release-label"), $[0] = pinnedPerspective, $[1] = t, $[2] = t1) : t1 = $[2]; const label = t1; let t2, t3; $[3] !== label || $[4] !== name ? (t3 = [name, label].filter(_temp$1), $[3] = label, $[4] = name, $[5] = t3) : t3 = $[5], t2 = t3.join(" "); const text = t2, t4 = !hasPinnedPerspective(pinnedPerspective); let t5; return $[6] !== t4 || $[7] !== text ? (t5 = /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pinnedRelease", disabled: t4, children: text }), $[6] = t4, $[7] = text, $[8] = t5) : t5 = $[8], t5; }; function VisionGuiHeader(t0) { const $ = reactCompilerRuntime.c(64), { onChangeDataset, dataset, customApiVersion, apiVersion, onChangeApiVersion, datasets, customApiVersionElementRef, onCustomApiVersionChange, isValidApiVersion, onChangePerspective, url, perspective } = t0, pinnedPerspective = sanity.usePerspective(), { t } = sanity.useTranslation(index.visionLocaleNamespace), operationUrlElement = react.useRef(null); let t1; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => { const el = operationUrlElement.current; if (el) try { el.select(), document.execCommand("copy"); } catch { console.error("Unable to copy to clipboard :("); } }, $[0] = t1) : t1 = $[0]; const handleCopyUrl = t1; let t2; $[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = [1, 4, 8, 12], $[1] = t2) : t2 = $[1]; let t3; $[2] !== t ? (t3 = t("settings.dataset-label"), $[2] = t, $[3] = t3) : t3 = $[3]; let t4; $[4] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t3 }) }), $[4] = t3, $[5] = t4) : t4 = $[5]; let t5; $[6] !== datasets ? (t5 = datasets.map(_temp2), $[6] = datasets, $[7] = t5) : t5 = $[7]; let t6; $[8] !== dataset || $[9] !== onChangeDataset || $[10] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: dataset, onChange: onChangeDataset, children: t5 }), $[8] = dataset, $[9] = onChangeDataset, $[10] = t5, $[11] = t6) : t6 = $[11]; let t7; $[12] !== t4 || $[13] !== t6 ? (t7 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [ t4, t6 ] }) }), $[12] = t4, $[13] = t6, $[14] = t7) : t7 = $[14]; let t8; $[15] !== t ? (t8 = t("settings.api-version-label"), $[15] = t, $[16] = t8) : t8 = $[16]; let t9; $[17] !== t8 ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t8 }) }), $[17] = t8, $[18] = t9) : t9 = $[18]; const t10 = customApiVersion === !1 ? apiVersion : "other"; let t11; $[19] === Symbol.for("react.memo_cache_sentinel") ? (t11 = API_VERSIONS.map(_temp3), $[19] = t11) : t11 = $[19]; let t12; $[20] !== t ? (t12 = t("settings.other-api-version-label"), $[20] = t, $[21] = t12) : t12 = $[21]; let t13; $[22] !== t12 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx("option", { value: "other", children: t12 }, "other"), $[22] = t12, $[23] = t13) : t13 = $[23]; let t14; $[24] !== onChangeApiVersion || $[25] !== t10 || $[26] !== t13 ? (t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { "data-testid": "api-version-selector", value: t10, onChange: onChangeApiVersion, children: [ t11, t13 ] }), $[24] = onChangeApiVersion, $[25] = t10, $[26] = t13, $[27] = t14) : t14 = $[27]; let t15; $[28] !== t14 || $[29] !== t9 ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [ t9, t14 ] }) }), $[28] = t14, $[29] = t9, $[30] = t15) : t15 = $[30]; let t16; $[31] !== customApiVersion || $[32] !== customApiVersionElementRef || $[33] !== isValidApiVersion || $[34] !== onCustomApiVersionChange || $[35] !== t ? (t16 = customApiVersion !== !1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [ /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { textOverflow: "ellipsis", children: t("settings.custom-api-version-label") }) }), /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { ref: customApiVersionElementRef, value: customApiVersion, onChange: onCustomApiVersionChange, customValidity: isValidApiVersion ? void 0 : t("settings.error.invalid-api-version"), maxLength: 11 }) ] }) }), $[31] = customApiVersion, $[32] = customApiVersionElementRef, $[33] = isValidApiVersion, $[34] = onCustomApiVersionChange, $[35] = t, $[36] = t16) : t16 = $[36]; let t17; $[37] !== t ? (t17 = t("settings.perspective-label"), $[37] = t, $[38] = t17) : t17 = $[38]; let t18; $[39] !== t17 ? (t18 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t17 }) }), $[39] = t17, $[40] = t18) : t18 = $[40]; let t19; $[41] === Symbol.for("react.memo_cache_sentinel") ? (t19 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(PerspectivePopover, {}) }), $[41] = t19) : t19 = $[41]; let t20; $[42] !== t18 ? (t20 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingBottom: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Inline, { space: 1, children: [ t18, t19 ] }) }), $[42] = t18, $[43] = t20) : t20 = $[43]; const t21 = perspective || "default"; let t22; $[44] !== pinnedPerspective || $[45] !== t ? (t22 = SUPPORTED_PERSPECTIVES.map((perspectiveName) => perspectiveName === "pinnedRelease" ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(PinnedReleasePerspectiveOption, { pinnedPerspective, t }), /* @__PURE__ */ jsxRuntime.jsx("option", { value: "default", children: t("settings.perspectives.default") }, "default"), /* @__PURE__ */ jsxRuntime.jsx("hr", {}) ] }, "pinnedRelease") : /* @__PURE__ */ jsxRuntime.jsx("option", { children: perspectiveName }, perspectiveName)), $[44] = pinnedPerspective, $[45] = t, $[46] = t22) : t22 = $[46]; let t23; $[47] !== onChangePerspective || $[48] !== t21 || $[49] !== t22 ? (t23 = /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: t21, onChange: onChangePerspective, children: t22 }), $[47] = onChangePerspective, $[48] = t21, $[49] = t22, $[50] = t23) : t23 = $[50]; let t24; $[51] !== t20 || $[52] !== t23 ? (t24 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [ t20, t23 ] }) }), $[51] = t20, $[52] = t23, $[53] = t24) : t24 = $[53]; let t25; $[54] !== customApiVersion || $[55] !== t || $[56] !== url ? (t25 = typeof url == "string" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, flex: 1, column: customApiVersion === !1 ? 6 : 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [ /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(StyledLabel, { children: [ t("query.url"), "\xA0", /* @__PURE__ */ jsxRuntime.jsxs(QueryCopyLink, { onClick: handleCopyUrl, children: [ "[", t("action.copy-url-to-clipboard"), "]" ] }) ] }) }), /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { flex: 1, gap: 1, children: [ /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { readOnly: !0, type: "url", ref: operationUrlElement, value: url }) }), /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("action.copy-url-to-clipboard"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { "aria-label": t("action.copy-url-to-clipboard"), type: "button", mode: "ghost", icon: icons.CopyIcon, onClick: handleCopyUrl }) }) ] }) ] }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1 }), $[54] = customApiVersion, $[55] = t, $[56] = url, $[57] = t25) : t25 = $[57]; let t26; return $[58] !== t15 || $[59] !== t16 || $[60] !== t24 || $[61] !== t25 || $[62] !== t7 ? (t26 = /* @__PURE__ */ jsxRuntime.jsx(Header, { paddingX: 3, paddingY: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: t2, children: [ t7, t15, t16, t24, t25 ] }) }), $[58] = t15, $[59] = t16, $[60] = t24, $[61] = t25, $[62] = t7, $[63] = t26) : t26 = $[63], t26; } function _temp3(version) { return /* @__PURE__ */ jsxRuntime.jsx("option", { children: version }, version); } function _temp2(ds) { return /* @__PURE__ */ jsxRuntime.jsx("option", { children: ds }, ds); } function _temp$1(value) { return typeof value < "u"; } function getBlobUrl(content, mimeType) { return URL.createObjectURL(new Blob([content], { type: mimeType })); } function getMemoizedBlobUrlResolver(mimeType, stringEncoder) { return /* @__PURE__ */ (() => { let prevResult = "", prevContent = ""; return (input) => { const content = stringEncoder(input); if (!(typeof content != "string" || content === "")) return content === prevContent || (prevContent = content, prevResult && URL.revokeObjectURL(prevResult), prevResult = getBlobUrl(content, mimeType)), prevResult; }; })(); } const getJsonBlobUrl = getMemoizedBlobUrlResolver("application/json", (input) => JSON.stringify(input, null, 2)), getCsvBlobUrl = getMemoizedBlobUrlResolver("text/csv", (input) => json2Csv.json2csv(Array.isArray(input) ? input : [input]).trim()), ErrorCode = styledComponents.styled(ui.Code)` color: ${({ theme }) => theme.sanity.color.muted.critical.enabled.fg}; `; function QueryErrorDetails(t0) { const $ = reactCompilerRuntime.c(7), { error } = t0, { t } = sanity.useTranslation(index.visionLocaleNamespace); if (!("details" in error)) return null; const details = { ...error.details, ...mapToLegacyDetails(error.details) }; if (!details.line) return null; const t1 = `${details.line} ${dashLine(details.column, details.columnEnd)}`; let t2; $[0] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: t1 }), $[0] = t1, $[1] = t2) : t2 = $[1]; const t3 = `${t("query.error.line")}: ${details.lineNumber} ${t("query.error.column")}: ${details.column}`; let t4; $[2] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: t3 }) }), $[2] = t3, $[3] = t4) : t4 = $[3]; let t5; return $[4] !== t2 || $[5] !== t4 ? (t5 = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [ t2, t4 ] }), $[4] = t2, $[5] = t4, $[6] = t5) : t5 = $[6], t5; } function mapToLegacyDetails(details) { if (!details || typeof details.query != "string" || typeof details.start != "number") return {}; const { query, start, end } = details, lineStart = query.slice(0, start).lastIndexOf(` `) + 1, lineNumber = (query.slice(0, lineStart).match(/\n/g) || []).length, line = query.slice(lineStart, query.indexOf(` `, lineStart)), column = start - lineStart, columnEnd = typeof end == "number" ? end - lineStart : void 0; return { line, lineNumber, column, columnEnd }; } function dashLine(column, columnEnd) { const line = "-".repeat(column), hats = "^".repeat(columnEnd ? columnEnd - column : 1); return `${line}${hats}`; } function QueryErrorDialog(props) { const $ = reactCompilerRuntime.c(7); let t0; $[0] !== props.error.message ? (t0 = /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: props.error.message }), $[0] = props.error.message, $[1] = t0) : t0 = $[1]; let t1; $[2] !== props.error ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(QueryErrorDetails, { error: props.error }), $[2] = props.error, $[3] = t1) : t1 = $[3]; let t2; return $[4] !== t0 || $[5] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 5, marginTop: 2, children: [ t0, t1 ] }), $[4] = t0, $[5] = t1, $[6] = t2) : t2 = $[6], t2; } const ResultViewWrapper = styledComponents.styled.div(({ theme }) => { const { color: color2, fonts, space } = theme.sanity; return styledComponents.css` & .json-inspector, & .json-inspector .json-inspector__selection { font-family: ${fonts.code.family}; font-size: ${fonts.code.sizes[2].fontSize}px; line-height: ${fonts.code.sizes[2].lineHeight}px; color: var(--card-code-fg-color); } & .json-inspector .json-inspector__leaf { padding-left: ${ui.rem(space[4])}; } & .json-inspector .json-inspector__leaf.json-inspector__leaf_root { padding-top: ${ui.rem(space[0])}; padding-left: 0; } & .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key { display: none; } & .json-inspector .json-inspector__line { display: block; position: relative; cursor: default; } & .json-inspector .json-inspector__line::after { content: ''; position: absolute; top: 0; left: -200px; right: -50px; bottom: 0; z-index: -1; pointer-events: none; } & .json-inspector .json-inspector__line:hover::after { background: var(--card-code-bg-color); } & .json-inspector .json-inspector__leaf_composite > .json-inspector__line { cursor: pointer; } & .json-inspector .json-inspector__leaf_composite > .json-inspector__line::before { content: '▸ '; margin-left: calc(0px - ${ui.rem(space[4])}); font-size: ${fonts.code.sizes[2].fontSize}px; line-height: ${fonts.code.sizes[2].lineHeight}px; } & .json-inspector .json-inspector__leaf_expanded.json-inspector__leaf_composite > .json-inspector__line::before { content: '▾ '; font-size: ${fonts.code.sizes[2].fontSize}px; line-height: ${fonts.code.sizes[2].lineHeight}px; } & .json-inspector .json-inspector__radio, & .json-inspector .json-inspector__flatpath { display: none; } & .json-inspector .json-inspector__value { margin-left: ${ui.rem(space[4] / 2)}; } & .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key + .json-inspector__value { margin: 0; } & .json-inspector .json-inspector__key { color: ${color2.syntax.property}; } & .json-inspector .json-inspector__value_helper, & .json-inspector .json-inspector__value_null { color: ${color2.syntax.constant}; } & .json-inspector .json-inspector__not-found { padding-top: ${ui.rem(space[2])}; } & .json-inspector .json-inspector__value_string { color: ${color2.syntax.string}; word-break: break-word; } & .json-inspector .json-inspector__value_boolean { color: ${color2.syntax.boolean}; } & .json-inspector .json-inspector__value_number { color: ${color2.syntax.number}; } & .json-inspector .json-inspector__show-original { display: inline-block; padding: 0 6px; cursor: pointer; } & .json-inspector .json-inspector__show-original:hover { color: inherit; } & .json-inspector .json-inspector__show-original::before { content: '↔'; } & .json-inspector .json-inspector__show-original:hover::after { content: ' expand'; } `; }), lru = new LRU__default.default({ maxSize: 5e4 }); function ResultView(props) { const $ = reactCompilerRuntime.c(7), { data, datasetName } = props, workspaceDataset = sanity.useDataset(); if (isRecord(data) || Array.isArray(data)) { const t02 = workspaceDataset === datasetName ? DocumentEditLabel : void 0; let t12; return $[0] !== data || $[1] !== t02 ? (t12 = /* @__PURE__ */ jsxRuntime.jsx(ResultViewWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(reactJsonInspector.JsonInspector, { data, search: !1, isExpanded, onClick: toggleExpanded, interactiveLabel: t02 }) }), $[0] = data, $[1] = t02, $[2] = t12) : t12 = $[2], t12; } let t0; $[3] !== data ? (t0 = JSON.stringify(data), $[3] = data, $[4] = t0) : t0 = $[4]; let t1; return $[5] !== t0 ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { language: "json", children: t0 }), $[5] = t0, $[6] = t1) : t1 = $[6], t1; } function DocumentEditLabel(props) { const $ = reactCompilerRuntime.c(5); if (props.isKey || !props.keypath.endsWith("_id") && !props.keypath.endsWith("_ref")) return null; let t0; $[0] !== props.value ? (t0 = { id: props.value }, $[0] = props.value, $[1] = t0) : t0 = $[1]; let t1; $[2] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(icons.LinkIcon, {}), $[2] = t1) : t1 = $[2]; let t2; return $[3] !== t0 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(router.IntentLink, { intent: "edit", params: t0, children: t1 }), $[3] = t0, $[4] = t2) : t2 = $[4], t2; } function isExpanded(keyPath, value) { const cached = lru.get(keyPath); if (typeof cached == "boolean") return cached; const segments = keyPath.split(".", 4); return segments.length === 4 ? !1 : Array.isArray(value) ? !0 : isRecord(value) && !segments.some((key) => isArrayKeyOverLimit(key)); } function toggleExpanded(event) { const { path } = event, current = lru.get(path); current !== void 0 && lru.set(path, !current); } function isRecord(value) { return value !== null && typeof value == "object" && !Array.isArray(value); } const numeric = /^\d+$/; function isArrayKeyOverLimit(segment, limit = 10) { return numeric.test(segment) && parseInt(segment, 10) > limit; } function preventSave(evt) { return evt.preventDefault(); } function SaveCsvButton(t0) { const $ = reactCompilerRuntime.c(9), { blobUrl } = t0, { t } = sanity.useTranslation(index.visionLocaleNamespace), isDisabled = !blobUrl, t1 = isDisabled ? void 0 : "query-result.csv", t2 = isDisabled ? preventSave : void 0; let t3; $[0] !== blobUrl || $[1] !== isDisabled || $[2] !== t1 || $[3] !== t2 ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { as: "a", disabled: isDisabled, download: t1, href: blobUrl, icon: icons.DocumentSheetIcon, mode: "ghost", onClick: t2, text: "CSV", tone: "default" }), $[0] = blobUrl, $[1] = isDisabled, $[2] = t1, $[3] = t2, $[4] = t3) : t3 = $[4]; const button = t3; let t4; return $[5] !== button || $[6] !== isDisabled || $[7] !== t ? (t4 = isDisabled ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("result.save-result-as-csv.not-csv-encodable"), placement: "top", children: button }) : button, $[5] = button, $[6] = isDisabled, $[7] = t, $[8] = t4) : t4 = $[8], t4; } function SaveJsonButton(t0) { const $ = reactCompilerRuntime.c(2), { blobUrl } = t0; let t1; return $[0] !== blobUrl ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { as: "a", download: "query-result.json", href: blobUrl, icon: icons.DocumentSheetIcon, mode: "ghost", text: "JSON", tone: "default" }), $[0] = blobUrl, $[1] = t1) : t1 = $[1], t1; } function VisionGuiResult(t0) { const $ = reactCompilerRuntime.c(67), { error, queryInProgress, queryResult, listenInProgress, listenMutations, dataset, queryTime, e2eTime } = t0, { t } = sanity.useTranslation(index.visionLocaleNamespace), hasResult = !error && !queryInProgress && typeof queryResult < "u"; let t1; $[0] !== hasResult || $[1] !== queryResult ? (t1 = hasResult ? getJsonBlobUrl(queryResult) : "", $[0] = hasResult, $[1] = queryResult, $[2] = t1) : t1 = $[2]; const jsonUrl = t1; let t2; $[3] !== hasResult || $[4] !== queryResult ? (t2 = hasResult ? getCsvBlobUrl(queryResult) : "", $[3] = hasResult, $[4] = queryResult, $[5] = t2) : t2 = $[5]; const csvUrl = t2, t3 = error ? "critical" : "default", t4 = !!error; let t5; $[6] !== t ? (t5 = t("result.label"), $[6] = t, $[7] = t5) : t5 = $[7]; let t6; $[8] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(InputBackgroundContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginLeft: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { muted: !0, children: t5 }) }) }), $[8] = t5, $[9] = t6) : t6 = $[9]; let t7; $[10] !== listenInProgress || $[11] !== listenMutations || $[12] !== queryInProgress ? (t7 = (queryInProgress || listenInProgress && listenMutations.length === 0) && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 3, children: /* @__PURE__ */ jsxRuntime.jsx(DelayedSpinner, {}) }), $[10] = listenInProgress, $[11] = listenMutations, $[12] = queryInProgress, $[13] = t7) : t7 = $[13]; let t8; $[14] !== error ? (t8 = error && /* @__PURE__ */ jsxRuntime.jsx(QueryErrorDialog, { error }), $[14] = error, $[15] = t8) : t8 = $[15]; let t9; $[16] !== dataset || $[17] !== hasResult || $[18] !== queryResult ? (t9 = hasResult && /* @__PURE__ */ jsxRuntime.jsx(ResultView, { data: queryResult, datasetName: dataset }), $[16] = dataset, $[17] = hasResult, $[18] = queryResult, $[19] = t9) : t9 = $[19]; let t10; $[20] !== dataset || $[21] !== listenInProgress || $[22] !== listenMutations ? (t10 = listenInProgress && listenMutations.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ResultView, { data: listenMutations, datasetNam