@@ -6,15 +6,8 @@ import { useThemeNormalized } from "@/hooks/useThemeNormalized";
6
6
import { json , jsonLanguage , jsonParseLinter } from "@codemirror/lang-json" ;
7
7
import { linter } from "@codemirror/lint" ;
8
8
import { 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" ;
18
11
import { Button } from "@/components/ui/button" ;
19
12
import { Separator } from "@/components/ui/separator" ;
20
13
import { Schema } from "ajv" ;
@@ -94,7 +87,7 @@ export function onQuickAction<T>(
94
87
const cursorPos = next . lastIndexOf ( selectionText ) ;
95
88
if ( cursorPos >= 0 ) {
96
89
view . dispatch ( {
97
- selection : {
90
+ selection : {
98
91
anchor : cursorPos ,
99
92
head : cursorPos + selectionText . length
100
93
}
@@ -120,7 +113,6 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
120
113
const editorRef = useRef < ReactCodeMirrorRef > ( null ) ;
121
114
const [ isViewMoreActionsEnabled , setIsViewMoreActionsEnabled ] = useState ( false ) ;
122
115
const [ height , setHeight ] = useState ( 224 ) ;
123
-
124
116
useImperativeHandle (
125
117
forwardedRef ,
126
118
( ) => editorRef . current as ReactCodeMirrorRef
@@ -129,6 +121,51 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
129
121
const keymapExtension = useKeymapExtension ( editorRef . current ?. view ) ;
130
122
const { theme } = useThemeNormalized ( ) ;
131
123
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
+
132
169
return (
133
170
< div className = "border rounded-md" >
134
171
< div className = "flex flex-row items-center flex-wrap p-1" >
@@ -211,19 +248,8 @@ const ConfigEditor = <T,>(props: ConfigEditorProps<T>, forwardedRef: Ref<ReactCo
211
248
extensions = { [
212
249
keymapExtension ,
213
250
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 ) ,
226
251
customAutocompleteStyle ,
252
+ ...jsonSchemaExtensions ,
227
253
] }
228
254
theme = { theme === "dark" ? "dark" : "light" }
229
255
/>
0 commit comments