import { useCallback, useEffect, useState } from "react";
import GraphiQLExplorer from "graphiql-explorer";
import {
ChevronDown,
ChevronRight,
Square,
SquareCheckBig,
} from "lucide-react";
import { buildSchema } from "graphql";
import { PluginV3Context } from "altair-graphql-core/build/plugin/v3/context";
import { 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: PluginV3Context;
}
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.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.getCurrentWindowState().then((state) => {
if (!state) {
return;
}
initializeCurrentWindowState(state);
});
context.on("query.change", setQuery);
context.on("sdl.change", setSDL);
context.on("current-window.change", async ({ windowId }) => {
const newWindowState = await context.getWindowState(windowId);
if (!newWindowState) {
return;
}
initializeCurrentWindowState(newWindowState);
});
return () => {
context.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()
}
/>
);
};