'use client'; import { ScrollArea } from "@/components/ui/scroll-area"; import { useKeymapExtension } from "@/hooks/useKeymapExtension"; import { useThemeNormalized } from "@/hooks/useThemeNormalized"; import { json, jsonLanguage, jsonParseLinter } from "@codemirror/lang-json"; import { linter } from "@codemirror/lint"; import { EditorView, hoverTooltip } from "@codemirror/view"; import CodeMirror, { ReactCodeMirrorRef } from "@uiw/react-codemirror"; import { handleRefresh, jsonCompletion, jsonSchemaHover, jsonSchemaLinter, stateExtensions } from "codemirror-json-schema"; import { useMemo, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { Schema } from "ajv"; export type QuickActionFn = (previous: T) => T; export type QuickAction = { name: string; fn: QuickActionFn; }; interface ConfigEditorProps { value: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any onChange: (...event: any[]) => void; actions: QuickAction[], schema: Schema; } const customAutocompleteStyle = EditorView.baseTheme({ ".cm-tooltip.cm-completionInfo": { padding: "8px", fontSize: "12px", fontFamily: "monospace", }, ".cm-tooltip-hover.cm-tooltip": { padding: "8px", fontSize: "12px", fontFamily: "monospace", } }); export function ConfigEditor({ value, onChange, actions, schema, }: ConfigEditorProps) { const editorRef = useRef(null); const keymapExtension = useKeymapExtension(editorRef.current?.view); const { theme } = useThemeNormalized(); const isQuickActionsDisabled = useMemo(() => { try { JSON.parse(value); return false; } catch { return true; } }, [value]); const onQuickAction = (action: QuickActionFn) => { let previousConfig: T; try { previousConfig = JSON.parse(value) as T; } catch { return; } const nextConfig = action(previousConfig); const next = JSON.stringify(nextConfig, null, 2); const cursorPos = next.lastIndexOf(`""`) + 1; editorRef.current?.view?.focus(); editorRef.current?.view?.dispatch({ changes: { from: 0, to: value.length, insert: next, } }); editorRef.current?.view?.dispatch({ selection: { anchor: cursorPos, head: cursorPos } }); } return ( <>
{actions.map(({ name, fn }, index) => (
{index !== actions.length - 1 && ( )}
))}
) }