From 4519ff73ce7120dd4bb6e035d883648235f28454 Mon Sep 17 00:00:00 2001 From: ZuperZee Date: Fri, 6 Jun 2025 14:26:40 +0200 Subject: [PATCH] feat: don't wait for declarations to load editor Start loading the editor immediately instead of waiting for the type declarations to be fetched. The editor can still be used when the declarations are not yet loaded, but the type declarations are loaded pretty quick, so it shouldn't be noticeable. This has kinda the same problems as #202 since this uses dynamic updating of type declarations. Straight copied from the commit message: This only works for Grafana v8.2.0-v8.3.X and v9.2.0 and later. Grafana v8.4.0 updated monaco editor to v0.31.1 which had a bug which prevents dynamically updating type declarations. This was fixed in Grafana v9.2.0. --- src/components/CodeEditor/index.tsx | 57 +++++++++++++---------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/src/components/CodeEditor/index.tsx b/src/components/CodeEditor/index.tsx index 5ce8e21..ee16e80 100644 --- a/src/components/CodeEditor/index.tsx +++ b/src/components/CodeEditor/index.tsx @@ -11,36 +11,35 @@ interface Props { } export const CodeEditor: FC = ({ settings, value, context, onChange }) => { - const [declarations, setDeclarations] = useState>(); const [monaco, setMonaco] = useState(); const editorDidMount = async (_: MonacoEditor, m: Monaco) => { setMonaco(m); - if (declarations) { - // Add autocompletion for panel definitions (htmlNode, htmlGraphics, data, options, ETC) - m.languages.typescript.javascriptDefaults.setExtraLibs(declarations); - } }; useEffect(() => { - if (settings?.useHtmlGraphicsDeclarations) { + if (monaco && settings?.useHtmlGraphicsDeclarations) { const reqDecl = require.context('./declarations', true, /\..*\.d\.ts$/); Promise.all(reqDecl.keys().map((key) => fetch(reqDecl(key)))) .then((r) => Promise.all(r.map((a) => a.text()))) - .then((d) => - setDeclarations( - reqDecl.keys().map((filePath, i) => ({ - filePath: filePath.substring(2), // Remove ./ - content: d[i], - })) - ) - ); + .then((d) => { + const extraLibs = monaco.languages.typescript.javascriptDefaults.getExtraLibs(); + reqDecl.keys().forEach((filePath, i) => { + const truncatedPath = filePath.substring(2); // Remove ./ + if (truncatedPath in extraLibs) { + // Don't add a declaration if it already exists + // Makes it so customProperties isn't overwritten :D + return; + } + monaco.languages.typescript.javascriptDefaults.addExtraLib(d[i], truncatedPath); + }); + }); } - }, [settings?.useHtmlGraphicsDeclarations]); + }, [monaco, settings?.useHtmlGraphicsDeclarations]); useEffect(() => { - if (!monaco || context.options?.codeData === undefined || !settings?.useHtmlGraphicsDeclarations === true) { + if (!monaco || context.options?.codeData === undefined || !settings?.useHtmlGraphicsDeclarations) { return; } @@ -58,24 +57,20 @@ export const CodeEditor: FC = ({ settings, value, context, onChange }) => const content = createCustomPropertiesType(context.options.codeData); monaco.languages.typescript.javascriptDefaults.addExtraLib(content, 'customProperties.d.ts'); - }, [context, monaco, settings]); + }, [monaco, settings?.useHtmlGraphicsDeclarations, context.options?.codeData]); return (
- {!settings?.useHtmlGraphicsDeclarations || declarations ? ( - - ) : ( -
Loading declarations...
- )} +
); };