import { useCallback, useEffect, useState } from "react"; import GraphiQLExplorer from "graphiql-explorer"; import { ChevronDown, ChevronRight, Square, SquareCheckBig, } from "lucide-react"; import { buildSchema } from "graphql"; import { PluginContext, PluginWindowState, } from "altair-graphql-core/build/plugin/context/context.interface"; const colors = { keyword: "var(--editor-keyword-color)", // OperationName, FragmentName def: "var(--editor-def-color)", // FieldName property: "var(--editor-property-color)", // FieldAlias qualifier: "var(--editor-attribute-color)", // ArgumentName and ObjectFieldName attribute: "var(--editor-attribute-color)", number: "var(--editor-number-color)", string: "var(--editor-string-color)", // Boolean builtin: "var(--editor-builtin-color)", // Enum string2: "var(--editor-string-color)", variable: "var(--editor-variable-color)", // Type atom: "var(--editor-atom-color)", }; const defaultArrowOpen = () => ( ); const defaultArrowClosed = () => ( ); const defaultCheckboxChecked = () => ( ); const defaultCheckboxUnchecked = () => ( ); const maybeBuildSchema = (sdl: string) => { let schema; if (sdl) { try { schema = buildSchema(sdl); } catch (error) { // noop } } return schema; }; interface AppState { [key: string]: PluginWindowState & { schema: ReturnType; }; } interface WrapperProps { context: PluginContext; } export const Wrapper = ({ context }: WrapperProps) => { const [appState, setAppState] = useState({}); const [currentWindowId, setCurrentWindowId] = useState(""); const noop = (...args: unknown[]) => console.log(...args); const onEdit = (query: string) => context.app.setQuery(currentWindowId, query); const setQuery = useCallback( ({ windowId, data }: { windowId: string; data: string }) => { setAppState((appState) => ({ ...appState, [windowId]: { ...appState[windowId], query: data, }, })); }, [] ); const setSDL = useCallback( ({ windowId, data }: { windowId: string; data: string }) => { setAppState((appState) => ({ ...appState, [windowId]: { ...appState[windowId], sdl: data, schema: maybeBuildSchema(data), }, })); }, [] ); const initializeCurrentWindowState = (state: PluginWindowState) => { setCurrentWindowId(state.windowId); setAppState((appState) => ({ ...appState, [state.windowId]: { ...state, schema: maybeBuildSchema(state.sdl), }, })); }; useEffect(() => { context.app.getCurrentWindowState().then((state) => { if (!state) { return; } initializeCurrentWindowState(state); }); context.events.on("query.change", setQuery); context.events.on("sdl.change", setSDL); context.events.on("current-window.change", async ({ windowId }) => { const newWindowState = await context.app.getWindowState(windowId); if (!newWindowState) { return; } initializeCurrentWindowState(newWindowState); }); return () => { context.events.off(); }; }, [context, setQuery, setSDL]); if (!appState[currentWindowId]) { return null; } return ( onEdit(query)} explorerIsOpen={true} onToggleExplorer={noop} colors={colors} arrowClosed={ ?? defaultArrowClosed() } arrowOpen={ ?? defaultArrowOpen() } checkboxChecked={ ?? defaultCheckboxChecked() } checkboxUnchecked={ ?? defaultCheckboxUnchecked() } /> ); };