@@ -6,15 +6,8 @@ import { useThemeNormalized } from "@/hooks/useThemeNormalized";
66import { json , jsonLanguage , jsonParseLinter } from "@codemirror/lang-json" ;
77import { linter } from "@codemirror/lint" ;
88import { EditorView , hoverTooltip } from "@codemirror/view" ;
9- import CodeMirror , { ReactCodeMirrorRef } from "@uiw/react-codemirror" ;
10- import {
11- handleRefresh ,
12- jsonCompletion ,
13- jsonSchemaHover ,
14- jsonSchemaLinter ,
15- stateExtensions
16- } from "codemirror-json-schema" ;
17- import { useRef , forwardRef , useImperativeHandle , Ref , ReactNode , useState } from "react" ;
9+ import CodeMirror , { Extension , ReactCodeMirrorRef } from "@uiw/react-codemirror" ;
10+ import { useRef , forwardRef , useImperativeHandle , Ref , ReactNode , useState , useEffect } from "react" ;
1811import { Button } from "@/components/ui/button" ;
1912import { Separator } from "@/components/ui/separator" ;
2013import { Schema } from "ajv" ;
@@ -94,7 +87,7 @@ export function onQuickAction<T>(
9487 const cursorPos = next . lastIndexOf ( selectionText ) ;
9588 if ( cursorPos >= 0 ) {
9689 view . dispatch ( {
97- selection : {
90+ selection : {
9891 anchor : cursorPos ,
9992 head : cursorPos + selectionText . length
10093 }
@@ -120,7 +113,6 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
120113 const editorRef = useRef < ReactCodeMirrorRef > ( null ) ;
121114 const [ isViewMoreActionsEnabled , setIsViewMoreActionsEnabled ] = useState ( false ) ;
122115 const [ height , setHeight ] = useState ( 224 ) ;
123-
124116 useImperativeHandle (
125117 forwardedRef ,
126118 ( ) => editorRef . current as ReactCodeMirrorRef
@@ -129,6 +121,51 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
129121 const keymapExtension = useKeymapExtension ( editorRef . current ?. view ) ;
130122 const { theme } = useThemeNormalized ( ) ;
131123
124+ // ⚠️ DISGUSTING HACK AHEAD ⚠️
125+ // Background: When navigating to the /connections/:id?tab=settings page, we were hitting a 500 error with the following
126+ // message server side:
127+ //
128+ // > Internal error: Error: Element type is invalid: expected a string (for built-in components) or a class/function
129+ // > (for composite components) but got: undefined. You likely forgot to export your component from the file it's
130+ // > defined in, or you might have mixed up default and named imports.
131+ //
132+ // Why was this happening? We have no idea, but we isolated it to the extensions exported by the `codemirror-json-schema`
133+ // package. The solution that worked was to dynamically import the package inside of the useEffect and load the extensions
134+ // async.
135+ //
136+ // So, yeah. - Brendan
137+ const [ jsonSchemaExtensions , setJsonSchemaExtensions ] = useState < Extension [ ] > ( [ ] ) ;
138+ useEffect ( ( ) => {
139+ const loadExtensions = async ( ) => {
140+ const {
141+ handleRefresh,
142+ jsonCompletion,
143+ jsonSchemaHover,
144+ jsonSchemaLinter,
145+ stateExtensions
146+ } = await import ( 'codemirror-json-schema' ) ;
147+ return [
148+ linter ( jsonParseLinter ( ) , {
149+ delay : 300 ,
150+ } ) ,
151+ linter ( jsonSchemaLinter ( ) , {
152+ needsRefresh : handleRefresh ,
153+ } ) ,
154+ jsonLanguage . data . of ( {
155+ autocomplete : jsonCompletion ( ) ,
156+ } ) ,
157+ hoverTooltip ( jsonSchemaHover ( ) ) ,
158+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159+ stateExtensions ( schema as any ) ,
160+ ]
161+ }
162+
163+ loadExtensions ( ) . then ( ( extensions ) => {
164+ console . debug ( 'Loaded json schema extensions' ) ;
165+ setJsonSchemaExtensions ( extensions ) ;
166+ } ) ;
167+ } , [ schema ] ) ;
168+
132169 return (
133170 < div className = "border rounded-md" >
134171 < div className = "flex flex-row items-center flex-wrap p-1" >
@@ -211,19 +248,8 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
211248 extensions = { [
212249 keymapExtension ,
213250 json ( ) ,
214- linter ( jsonParseLinter ( ) , {
215- delay : 300 ,
216- } ) ,
217- linter ( jsonSchemaLinter ( ) , {
218- needsRefresh : handleRefresh ,
219- } ) ,
220- jsonLanguage . data . of ( {
221- autocomplete : jsonCompletion ( ) ,
222- } ) ,
223- hoverTooltip ( jsonSchemaHover ( ) ) ,
224- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225- stateExtensions ( schema as any ) ,
226251 customAutocompleteStyle ,
252+ ...jsonSchemaExtensions ,
227253 ] }
228254 theme = { theme === "dark" ? "dark" : "light" }
229255 />
0 commit comments