@finos/legend-application-studio 13.1.2 → 15.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/lib/components/EditorComponentTestUtils.d.ts +3 -13
  2. package/lib/components/EditorComponentTestUtils.d.ts.map +1 -1
  3. package/lib/components/EditorComponentTestUtils.js +3 -22
  4. package/lib/components/EditorComponentTestUtils.js.map +1 -1
  5. package/lib/components/editor/edit-panel/EditPanel.js +4 -4
  6. package/lib/components/editor/edit-panel/EditPanel.js.map +1 -1
  7. package/lib/components/editor/edit-panel/{ModelLoader.d.ts → ModelImporter.d.ts} +2 -2
  8. package/lib/components/editor/edit-panel/ModelImporter.d.ts.map +1 -0
  9. package/lib/components/editor/edit-panel/ModelImporter.js +127 -0
  10. package/lib/components/editor/edit-panel/ModelImporter.js.map +1 -0
  11. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.d.ts +7 -0
  12. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.d.ts.map +1 -1
  13. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.js +18 -42
  14. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.js.map +1 -1
  15. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.d.ts +24 -0
  16. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.d.ts.map +1 -0
  17. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.js +75 -0
  18. package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.js.map +1 -0
  19. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.d.ts.map +1 -1
  20. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.js +1 -2
  21. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.js.map +1 -1
  22. package/lib/components/editor/side-bar/Explorer.js +4 -4
  23. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  24. package/lib/index.css +1 -1
  25. package/lib/index.d.ts +1 -0
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/index.js +1 -0
  28. package/lib/index.js.map +1 -1
  29. package/lib/package.json +7 -7
  30. package/lib/stores/EditorGraphState.d.ts +1 -1
  31. package/lib/stores/EditorGraphState.d.ts.map +1 -1
  32. package/lib/stores/EditorGraphState.js +10 -10
  33. package/lib/stores/EditorGraphState.js.map +1 -1
  34. package/lib/stores/EditorStore.d.ts +3 -3
  35. package/lib/stores/EditorStore.d.ts.map +1 -1
  36. package/lib/stores/EditorStore.js +6 -8
  37. package/lib/stores/EditorStore.js.map +1 -1
  38. package/lib/stores/LegendStudioApplicationPlugin.d.ts +7 -5
  39. package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
  40. package/lib/stores/LegendStudioApplicationPlugin.js.map +1 -1
  41. package/lib/stores/editor-state/ExternalFormatState.d.ts +3 -2
  42. package/lib/stores/editor-state/ExternalFormatState.d.ts.map +1 -1
  43. package/lib/stores/editor-state/ExternalFormatState.js +11 -8
  44. package/lib/stores/editor-state/ExternalFormatState.js.map +1 -1
  45. package/lib/stores/editor-state/ModelImporterState.d.ts +100 -0
  46. package/lib/stores/editor-state/ModelImporterState.d.ts.map +1 -0
  47. package/lib/stores/editor-state/ModelImporterState.js +358 -0
  48. package/lib/stores/editor-state/ModelImporterState.js.map +1 -0
  49. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts +35 -12
  50. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts.map +1 -1
  51. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js +141 -34
  52. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js.map +1 -1
  53. package/lib/stores/editor-state/entity-diff-editor-state/EntityChangeConflictEditorState.js +1 -1
  54. package/lib/stores/editor-state/entity-diff-editor-state/EntityChangeConflictEditorState.js.map +1 -1
  55. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts +1 -0
  56. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts.map +1 -1
  57. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js +3 -0
  58. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js.map +1 -1
  59. package/package.json +15 -15
  60. package/src/components/EditorComponentTestUtils.tsx +2 -29
  61. package/src/components/editor/edit-panel/EditPanel.tsx +4 -4
  62. package/src/components/editor/edit-panel/ModelImporter.tsx +372 -0
  63. package/src/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.tsx +47 -163
  64. package/src/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.tsx +226 -0
  65. package/src/components/editor/edit-panel/mapping-editor/NewMappingElementModal.tsx +1 -2
  66. package/src/components/editor/side-bar/Explorer.tsx +8 -8
  67. package/src/index.ts +1 -0
  68. package/src/stores/EditorGraphState.ts +13 -12
  69. package/src/stores/EditorStore.ts +7 -9
  70. package/src/stores/LegendStudioApplicationPlugin.ts +16 -7
  71. package/src/stores/editor-state/ExternalFormatState.ts +15 -12
  72. package/src/stores/editor-state/ModelImporterState.ts +514 -0
  73. package/src/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.ts +203 -46
  74. package/src/stores/editor-state/entity-diff-editor-state/EntityChangeConflictEditorState.ts +1 -1
  75. package/src/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.ts +5 -0
  76. package/tsconfig.json +3 -2
  77. package/lib/components/editor/edit-panel/ModelLoader.d.ts.map +0 -1
  78. package/lib/components/editor/edit-panel/ModelLoader.js +0 -95
  79. package/lib/components/editor/edit-panel/ModelLoader.js.map +0 -1
  80. package/lib/stores/editor-state/ModelLoaderState.d.ts +0 -52
  81. package/lib/stores/editor-state/ModelLoaderState.d.ts.map +0 -1
  82. package/lib/stores/editor-state/ModelLoaderState.js +0 -199
  83. package/lib/stores/editor-state/ModelLoaderState.js.map +0 -1
  84. package/src/components/editor/edit-panel/ModelLoader.tsx +0 -259
  85. package/src/stores/editor-state/ModelLoaderState.ts +0 -280
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { observer } from 'mobx-react-lite';
18
+ import {
19
+ type ModelImporterEditorState,
20
+ ModelImporterState,
21
+ ExtensionModelImporterEditorState,
22
+ MODEL_IMPORT_NATIVE_INPUT_TYPE,
23
+ NativeModelImporterEditorState,
24
+ ExternalFormatModelImporterState,
25
+ } from '../../../stores/editor-state/ModelImporterState.js';
26
+ import { prettyCONSTName } from '@finos/legend-shared';
27
+ import {
28
+ DropdownMenu,
29
+ MenuContent,
30
+ MenuContentItem,
31
+ CaretDownIcon,
32
+ CheckSquareIcon,
33
+ TruckLoadingIcon,
34
+ EmptySquareIcon,
35
+ BlankPanelContent,
36
+ PanelLoadingIndicator,
37
+ clsx,
38
+ } from '@finos/legend-art';
39
+ import { flowResult } from 'mobx';
40
+ import { useEditorStore } from '../EditorStoreProvider.js';
41
+ import {
42
+ ActionAlertType,
43
+ ActionAlertActionType,
44
+ useApplicationStore,
45
+ EDITOR_LANGUAGE,
46
+ useApplicationNavigationContext,
47
+ } from '@finos/legend-application';
48
+ import { StudioTextInputEditor } from '../../shared/StudioTextInputEditor.js';
49
+ import type { ModelImporterExtensionConfiguration } from '../../../stores/LegendStudioApplicationPlugin.js';
50
+ import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../stores/LegendStudioApplicationNavigationContext.js';
51
+ import { SCHEMA_SET_TAB_TYPE } from '../../../stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js';
52
+ import { SchemaSetModelGenerationEditor } from './external-format-editor/SchemaSetModelGenerationEditor.js';
53
+ import { SchemaSetGeneralEditor } from './external-format-editor/SchemaSetElementEditor.js';
54
+
55
+ const ExternalFormatModelImporterEditor = observer(
56
+ (props: { externalFormatState: ExternalFormatModelImporterState }) => {
57
+ const { externalFormatState } = props;
58
+ const schemaSetEditorState = externalFormatState.schemaSetEditorState;
59
+ const editorStore = schemaSetEditorState.editorStore;
60
+ const schemaSet = schemaSetEditorState.schemaSet;
61
+ const currentTab = schemaSetEditorState.selectedTab;
62
+ const isFetchingDescriptions =
63
+ editorStore.graphState.graphGenerationState.externalFormatState
64
+ .fetchingDescriptionsState.isInProgress;
65
+ const changeTab =
66
+ (tab: SCHEMA_SET_TAB_TYPE): (() => void) =>
67
+ (): void =>
68
+ schemaSetEditorState.setSelectedTab(tab);
69
+ const renderMainEditPanel = (): React.ReactNode => {
70
+ if (isFetchingDescriptions) {
71
+ return (
72
+ <BlankPanelContent>Fetching format descriptions</BlankPanelContent>
73
+ );
74
+ }
75
+ if (currentTab === SCHEMA_SET_TAB_TYPE.SCHEMAS) {
76
+ return (
77
+ <SchemaSetGeneralEditor
78
+ schemaSetEditorState={schemaSetEditorState}
79
+ isReadOnly={false}
80
+ />
81
+ );
82
+ }
83
+ const supportsModelGeneraiton =
84
+ schemaSetEditorState.schemaSetModelGenerationState.description
85
+ ?.supportsModelGeneration;
86
+ return supportsModelGeneraiton ? (
87
+ <SchemaSetModelGenerationEditor
88
+ modelGenerationState={
89
+ schemaSetEditorState.schemaSetModelGenerationState
90
+ }
91
+ isReadOnly={false}
92
+ />
93
+ ) : (
94
+ <BlankPanelContent>
95
+ Format {schemaSet.format} does not support Model Generation
96
+ </BlankPanelContent>
97
+ );
98
+ };
99
+ return (
100
+ <div className="panel schema-set-panel">
101
+ <div className="panel__content model-loader">
102
+ <PanelLoadingIndicator isLoading={isFetchingDescriptions} />
103
+ <div className="panel__header">
104
+ <div className="uml-element-editor__tabs">
105
+ {Object.values(SCHEMA_SET_TAB_TYPE).map((tab) => (
106
+ <div
107
+ key={tab}
108
+ onClick={changeTab(tab)}
109
+ className={clsx('relational-connection-editor__tab', {
110
+ 'relational-connection-editor__tab--active':
111
+ tab === currentTab,
112
+ })}
113
+ >
114
+ {prettyCONSTName(tab)}
115
+ </div>
116
+ ))}
117
+ </div>
118
+ </div>
119
+
120
+ <div className="panel__content file-generation-editor__content">
121
+ {currentTab === SCHEMA_SET_TAB_TYPE.SCHEMAS && (
122
+ <SchemaSetGeneralEditor
123
+ schemaSetEditorState={schemaSetEditorState}
124
+ isReadOnly={false}
125
+ />
126
+ )}
127
+
128
+ {currentTab === SCHEMA_SET_TAB_TYPE.GENERATE_MODEL &&
129
+ renderMainEditPanel()}
130
+ </div>
131
+ </div>
132
+ </div>
133
+ );
134
+ },
135
+ );
136
+
137
+ export const ModelImporter = observer(() => {
138
+ const editorStore = useEditorStore();
139
+ const applicationStore = useApplicationStore();
140
+ const modelImporterState =
141
+ editorStore.getCurrentEditorState(ModelImporterState);
142
+ const nativeInputTypes = Object.values(MODEL_IMPORT_NATIVE_INPUT_TYPE);
143
+ const extraModelImporterExtensionsConfigs =
144
+ modelImporterState.extensionConfigs;
145
+ const externalFormatDescriptions =
146
+ modelImporterState.editorStore.graphState.graphGenerationState
147
+ .externalFormatState.externalFormatDescriptionsWithModelGenerationSupport;
148
+ // replace flag
149
+ const replace = modelImporterState.replace;
150
+ const toggleReplace = (): void => modelImporterState.setReplaceFlag(!replace);
151
+ const label = modelImporterState.modelImportEditorState.label;
152
+ const modelImportEditorState = modelImporterState.modelImportEditorState;
153
+ const loadModel = (): void => {
154
+ if (editorStore.hasUnpushedChanges) {
155
+ editorStore.setActionAlertInfo({
156
+ message: 'You have unpushed changes',
157
+ prompt:
158
+ 'This action will discard these changes and refresh the application',
159
+ type: ActionAlertType.CAUTION,
160
+ onEnter: (): void => editorStore.setBlockGlobalHotkeys(true),
161
+ onClose: (): void => editorStore.setBlockGlobalHotkeys(false),
162
+ actions: [
163
+ {
164
+ label: 'Proceed to load model',
165
+ type: ActionAlertActionType.PROCEED_WITH_CAUTION,
166
+ handler: (): void => {
167
+ editorStore.setIgnoreNavigationBlocking(true);
168
+ flowResult(
169
+ modelImporterState.modelImportEditorState.loadModel(),
170
+ ).catch(applicationStore.alertUnhandledError);
171
+ },
172
+ },
173
+ {
174
+ label: 'Abort',
175
+ type: ActionAlertActionType.PROCEED,
176
+ default: true,
177
+ },
178
+ ],
179
+ });
180
+ } else {
181
+ flowResult(modelImporterState.modelImportEditorState.loadModel()).catch(
182
+ applicationStore.alertUnhandledError,
183
+ );
184
+ }
185
+ };
186
+ useApplicationNavigationContext(
187
+ LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MODEL_LOADER,
188
+ );
189
+ const renderExtraActions = (): React.ReactNode => {
190
+ if (modelImportEditorState instanceof NativeModelImporterEditorState) {
191
+ // actions
192
+ const loadCurrentProjectEntities = applicationStore.guardUnhandledError(
193
+ () => flowResult(modelImportEditorState.loadCurrentProjectEntities()),
194
+ );
195
+ return (
196
+ <button
197
+ className="model-loader__header__configs__load-project-entities-btn"
198
+ tabIndex={-1}
199
+ onClick={loadCurrentProjectEntities}
200
+ title="Load current project entities"
201
+ >
202
+ <TruckLoadingIcon />
203
+ </button>
204
+ );
205
+ }
206
+ return null;
207
+ };
208
+ const renderModelImporterEditor = (): React.ReactNode => {
209
+ if (modelImportEditorState instanceof ExtensionModelImporterEditorState) {
210
+ return modelImportEditorState.config.renderer(
211
+ modelImportEditorState.rendererState,
212
+ );
213
+ } else if (
214
+ modelImportEditorState instanceof NativeModelImporterEditorState
215
+ ) {
216
+ const updateModel = (val: string): void =>
217
+ modelImportEditorState.setModelText(val);
218
+ return (
219
+ <div className="panel__content model-loader__editor">
220
+ <StudioTextInputEditor
221
+ language={
222
+ modelImportEditorState.nativeType ===
223
+ MODEL_IMPORT_NATIVE_INPUT_TYPE.PURE_GRAMMAR
224
+ ? EDITOR_LANGUAGE.PURE
225
+ : EDITOR_LANGUAGE.JSON
226
+ }
227
+ inputValue={modelImportEditorState.modelText}
228
+ updateInput={updateModel}
229
+ showMiniMap={true}
230
+ />
231
+ </div>
232
+ );
233
+ } else if (
234
+ modelImportEditorState instanceof ExternalFormatModelImporterState
235
+ ) {
236
+ return (
237
+ <ExternalFormatModelImporterEditor
238
+ externalFormatState={modelImportEditorState}
239
+ />
240
+ );
241
+ }
242
+ return null;
243
+ };
244
+
245
+ return (
246
+ <div className="panel model-loader">
247
+ <div className="panel__header model-loader__header">
248
+ <div className="model-loader__header__configs">
249
+ <DropdownMenu
250
+ content={
251
+ <MenuContent className="model-loader__header__configs__type__menu">
252
+ <div className="model-loader__header__configs__type-option__group model-loader__header__configs__type-option__group--native">
253
+ <div className="model-loader__header__configs__type-option__group__name">
254
+ native
255
+ </div>
256
+ <div className="model-loader__header__configs__type-option__group__options">
257
+ {nativeInputTypes.map((inputType) => (
258
+ <MenuContentItem
259
+ key={inputType}
260
+ className="model-loader__header__configs__type-option__group__option"
261
+ onClick={(): ModelImporterEditorState =>
262
+ modelImporterState.setNativeImportType(inputType)
263
+ }
264
+ >
265
+ {prettyCONSTName(inputType)}
266
+ </MenuContentItem>
267
+ ))}
268
+ </div>
269
+ </div>
270
+ {Boolean(externalFormatDescriptions.length) && (
271
+ <>
272
+ <div className="model-loader__header__configs__type-option__group__separator" />
273
+ <div className="model-loader__header__configs__type-option__group model-loader__header__configs__type-option__group--external">
274
+ <div className="model-loader__header__configs__type-option__group__name">
275
+ external
276
+ </div>
277
+ <div className="model-loader__header__configs__type-option__group__options">
278
+ {externalFormatDescriptions.map((inputType) => (
279
+ <MenuContentItem
280
+ key={inputType.name}
281
+ className="model-loader__header__configs__type-option__group__option"
282
+ onClick={() =>
283
+ modelImporterState.setExternalFormatImportFormat(
284
+ inputType,
285
+ )
286
+ }
287
+ >
288
+ {inputType.name}
289
+ </MenuContentItem>
290
+ ))}
291
+ </div>
292
+ </div>
293
+ </>
294
+ )}
295
+ {Boolean(extraModelImporterExtensionsConfigs.length > 0) && (
296
+ <>
297
+ <div className="model-loader__header__configs__type-option__group__separator" />
298
+ <div className="model-loader__header__configs__type-option__group model-loader__header__configs__type-option__group--extension">
299
+ <div className="model-loader__header__configs__type-option__group__name">
300
+ extensions
301
+ </div>
302
+ <div className="model-loader__header__configs__type-option__group__options">
303
+ {extraModelImporterExtensionsConfigs.map(
304
+ (config: ModelImporterExtensionConfiguration) => (
305
+ <MenuContentItem
306
+ key={config.key}
307
+ className="model-loader__header__configs__type-option__group__option"
308
+ onClick={() =>
309
+ modelImporterState.setModelImporterExtension(
310
+ config,
311
+ )
312
+ }
313
+ >
314
+ {config.label ?? prettyCONSTName(config.key)}
315
+ </MenuContentItem>
316
+ ),
317
+ )}
318
+ </div>
319
+ </div>
320
+ </>
321
+ )}
322
+ </MenuContent>
323
+ }
324
+ menuProps={{
325
+ anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
326
+ transformOrigin: { vertical: 'top', horizontal: 'right' },
327
+ }}
328
+ >
329
+ <div className="model-loader__header__configs__type">
330
+ <div className="model-loader__header__configs__type__label">
331
+ {prettyCONSTName(label)}
332
+ </div>
333
+ <div className="model-loader__header__configs__type__icon">
334
+ <CaretDownIcon />
335
+ </div>
336
+ </div>
337
+ </DropdownMenu>
338
+ {modelImportEditorState.allowHardReplace && (
339
+ <div
340
+ className="model-loader__header__configs__edit-mode"
341
+ onClick={toggleReplace}
342
+ >
343
+ <div className="model-loader__header__configs__edit-mode__icon">
344
+ {replace ? <CheckSquareIcon /> : <EmptySquareIcon />}
345
+ </div>
346
+ <div className="model-loader__header__configs__edit-mode__label">
347
+ replace
348
+ </div>
349
+ </div>
350
+ )}
351
+ {renderExtraActions()}
352
+ </div>
353
+ <div className="model-loader__header__action">
354
+ <button
355
+ className="btn--dark model-loader__header__load-btn"
356
+ onClick={loadModel}
357
+ disabled={
358
+ modelImportEditorState.loadModelActionState.isInProgress ||
359
+ modelImportEditorState.isLoadingDisabled
360
+ }
361
+ tabIndex={-1}
362
+ title="Load model"
363
+ >
364
+ Load
365
+ </button>
366
+ </div>
367
+ </div>
368
+
369
+ {renderModelImporterEditor()}
370
+ </div>
371
+ );
372
+ });
@@ -24,7 +24,6 @@ import {
24
24
  ResizablePanelSplitterLine,
25
25
  LockIcon,
26
26
  PlusIcon,
27
- RefreshIcon,
28
27
  PanelLoadingIndicator,
29
28
  UploadIcon,
30
29
  Dialog,
@@ -33,25 +32,17 @@ import {
33
32
  MenuContent,
34
33
  MenuContentItem,
35
34
  } from '@finos/legend-art';
36
- import {
37
- type GenerationProperty,
38
- ExternalFormatSchema as Schema,
39
- } from '@finos/legend-graph';
35
+ import { ExternalFormatSchema as Schema } from '@finos/legend-graph';
40
36
  import { flowResult } from 'mobx';
41
- import { useMemo } from 'react';
42
37
  import {
43
38
  SchemaSetEditorState,
39
+ type InnerSchemaSetEditorState,
44
40
  SCHEMA_SET_TAB_TYPE,
45
41
  } from '../../../../stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js';
46
42
  import { EDITOR_LANGUAGE } from '@finos/legend-application';
47
43
  import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor.js';
48
44
  import { getEditorLanguageFromFormat } from '../../../../stores/editor-state/FileGenerationViewerState.js';
49
- import {
50
- debounce,
51
- guaranteeNonNullable,
52
- prettyCONSTName,
53
- } from '@finos/legend-shared';
54
- import { GenerationPropertyEditor } from '../element-generation-editor/FileGenerationEditor.js';
45
+ import { guaranteeNonNullable, prettyCONSTName } from '@finos/legend-shared';
55
46
  import { useEditorStore } from '../../EditorStoreProvider.js';
56
47
  import {
57
48
  externalFormat_schemaSet_addSchema,
@@ -60,9 +51,12 @@ import {
60
51
  externalFormat_schema_setId,
61
52
  externalFormat_schema_setLocation,
62
53
  } from '../../../../stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js';
54
+ import { SchemaSetModelGenerationEditor } from './SchemaSetModelGenerationEditor.js';
63
55
 
64
56
  const SchemaLoader = observer(
65
- (props: { schemaSetEditorState: SchemaSetEditorState }) => {
57
+ (props: {
58
+ schemaSetEditorState: InnerSchemaSetEditorState | SchemaSetEditorState;
59
+ }) => {
66
60
  const { schemaSetEditorState } = props;
67
61
  const importState = schemaSetEditorState.importSchemaContentState;
68
62
  const onClose = (): void => importState.closeModal();
@@ -199,19 +193,23 @@ const SchemaBasicEditor = observer(
199
193
  },
200
194
  );
201
195
 
202
- const SchemaSetGeneralEditor = observer(
203
- (props: { schemaSetEditorState: SchemaSetEditorState }) => {
204
- const { schemaSetEditorState } = props;
196
+ export const SchemaSetGeneralEditor = observer(
197
+ (props: {
198
+ schemaSetEditorState: InnerSchemaSetEditorState | SchemaSetEditorState;
199
+ isReadOnly: boolean;
200
+ }) => {
201
+ const { schemaSetEditorState, isReadOnly } = props;
205
202
  const schemaSet = schemaSetEditorState.schemaSet;
206
203
  const applicationStore = schemaSetEditorState.editorStore.applicationStore;
207
204
  const importSchemaContentState =
208
205
  schemaSetEditorState.importSchemaContentState;
209
206
  const currentSchema = schemaSetEditorState.currentSchema;
210
- const isReadOnly = schemaSetEditorState.isReadOnly;
211
207
  const description =
212
208
  schemaSetEditorState.schemaSetModelGenerationState.description;
213
209
  // TEMPROARY engine api should return `fileformat`.
214
- const language = getEditorLanguageFromFormat(description.name);
210
+ const language = description
211
+ ? getEditorLanguageFromFormat(description.name)
212
+ : EDITOR_LANGUAGE.TEXT;
215
213
  const changeState =
216
214
  (schema: Schema): (() => void) =>
217
215
  (): void => {
@@ -246,7 +244,10 @@ const SchemaSetGeneralEditor = observer(
246
244
  }
247
245
  };
248
246
  const validateSchema = (): void => {
249
- if (currentSchema) {
247
+ if (
248
+ currentSchema &&
249
+ schemaSetEditorState instanceof SchemaSetEditorState
250
+ ) {
250
251
  flowResult(schemaSetEditorState.validateSchema(currentSchema)).catch(
251
252
  applicationStore.alertUnhandledError,
252
253
  );
@@ -332,15 +333,17 @@ const SchemaSetGeneralEditor = observer(
332
333
  </div>
333
334
  </div>
334
335
  <div className="panel__header__actions">
335
- <button
336
- className="btn--dark model-loader__header__load-btn"
337
- onClick={validateSchema}
338
- disabled={!currentSchema}
339
- tabIndex={-1}
340
- title="Validate Schema"
341
- >
342
- Validate
343
- </button>
336
+ {schemaSetEditorState instanceof SchemaSetEditorState && (
337
+ <button
338
+ className="btn--dark model-loader__header__load-btn"
339
+ onClick={validateSchema}
340
+ disabled={!currentSchema}
341
+ tabIndex={-1}
342
+ title="Validate Schema"
343
+ >
344
+ Validate
345
+ </button>
346
+ )}
344
347
  </div>
345
348
  </div>
346
349
  <div className="schema-set-panel__content">
@@ -366,133 +369,6 @@ const SchemaSetGeneralEditor = observer(
366
369
  },
367
370
  );
368
371
 
369
- const SchemaSetModelGenerationEditor = observer(
370
- (props: { schemaSetEditorState: SchemaSetEditorState }) => {
371
- const { schemaSetEditorState } = props;
372
- const applicationStore = schemaSetEditorState.editorStore.applicationStore;
373
- const schemaSet = schemaSetEditorState.schemaSet;
374
- const modelGenerationState =
375
- schemaSetEditorState.schemaSetModelGenerationState;
376
- const description = modelGenerationState.description;
377
- const properties = description.modelGenerationProperties;
378
- const isReadOnly = schemaSetEditorState.isReadOnly;
379
- const debouncedRegenerate = useMemo(
380
- () =>
381
- debounce(() => flowResult(modelGenerationState.generateModel()), 500),
382
- [modelGenerationState],
383
- );
384
- const update = (
385
- generationProperty: GenerationProperty,
386
- newValue: object,
387
- ): void => {
388
- debouncedRegenerate.cancel();
389
- modelGenerationState.updateGenerationParameters(
390
- generationProperty,
391
- newValue,
392
- );
393
- debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
394
- };
395
- const regenerate = (): void => {
396
- modelGenerationState.generateModel();
397
- };
398
- const getConfigValue = (name: string): unknown | undefined =>
399
- modelGenerationState.getConfigValue(name);
400
-
401
- const importGeneratedElements = (): void => {
402
- modelGenerationState.importGrammar();
403
- };
404
- return (
405
- <div className="panel__content file-generation-editor__content">
406
- <ResizablePanelGroup orientation="vertical">
407
- <ResizablePanel size={250} minSize={50}>
408
- <div className="panel file-generation-editor__configuration">
409
- <div className="panel__header">
410
- <div className="panel__header__title">
411
- <div className="panel__header__title__label">{`${schemaSet.format} configuration`}</div>
412
- </div>
413
- <div className="panel__header__actions">
414
- <button
415
- className="panel__header__action file-generation-editor__configuration__reset-btn"
416
- tabIndex={-1}
417
- disabled={isReadOnly || !properties.length}
418
- onClick={regenerate}
419
- title={'Reset to default configuration'}
420
- >
421
- <RefreshIcon />
422
- </button>
423
- </div>
424
- </div>
425
- <div className="panel__content">
426
- <div className="file-generation-editor__configuration__content">
427
- {modelGenerationState.modelGenerationProperties.map(
428
- (abstractGenerationProperty) => (
429
- <GenerationPropertyEditor
430
- key={abstractGenerationProperty.name}
431
- update={update}
432
- isReadOnly={isReadOnly}
433
- getConfigValue={getConfigValue}
434
- property={abstractGenerationProperty}
435
- />
436
- ),
437
- )}
438
- </div>
439
- </div>
440
- </div>
441
- </ResizablePanel>
442
- <ResizablePanelSplitter>
443
- <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
444
- </ResizablePanelSplitter>
445
- <ResizablePanel>
446
- <div className="panel generation-result-viewer__file">
447
- <div className="panel__header">
448
- <div className="panel__header__title">
449
- <div className="panel__header__title__label">result</div>
450
- </div>
451
- <div className="panel__header__actions">
452
- <button
453
- className={clsx(
454
- 'panel__header__action generation-result-viewer__regenerate-btn',
455
- {
456
- ' generation-result-viewer__regenerate-btn--loading':
457
- modelGenerationState.isGenerating,
458
- },
459
- )}
460
- tabIndex={-1}
461
- disabled={modelGenerationState.isGenerating}
462
- onClick={regenerate}
463
- title={'Re-generate'}
464
- >
465
- <RefreshIcon />
466
- </button>
467
- <button
468
- className="btn--dark model-loader__header__load-btn"
469
- onClick={importGeneratedElements}
470
- disabled={modelGenerationState.generationValue === ''}
471
- tabIndex={-1}
472
- title="Import generated elements"
473
- >
474
- Import
475
- </button>
476
- </div>
477
- </div>
478
- <div className="panel__content">
479
- <PanelLoadingIndicator
480
- isLoading={modelGenerationState.isGenerating}
481
- />
482
- <StudioTextInputEditor
483
- inputValue={modelGenerationState.generationValue}
484
- isReadOnly={true}
485
- language={EDITOR_LANGUAGE.PURE}
486
- />
487
- </div>
488
- </div>
489
- </ResizablePanel>
490
- </ResizablePanelGroup>
491
- </div>
492
- );
493
- },
494
- );
495
-
496
372
  export const SchemaSetEditor = observer(() => {
497
373
  const editorStore = useEditorStore();
498
374
  const schemaSetEditorState =
@@ -513,17 +389,23 @@ export const SchemaSetEditor = observer(() => {
513
389
  <BlankPanelContent>Fetching format descriptions</BlankPanelContent>
514
390
  );
515
391
  }
516
- if (currentTab === SCHEMA_SET_TAB_TYPE.GENERAL) {
392
+ if (currentTab === SCHEMA_SET_TAB_TYPE.SCHEMAS) {
517
393
  return (
518
- <SchemaSetGeneralEditor schemaSetEditorState={schemaSetEditorState} />
394
+ <SchemaSetGeneralEditor
395
+ schemaSetEditorState={schemaSetEditorState}
396
+ isReadOnly={isReadOnly}
397
+ />
519
398
  );
520
399
  }
521
400
  const supportsModelGeneraiton =
522
401
  schemaSetEditorState.schemaSetModelGenerationState.description
523
- .supportsModelGeneration;
402
+ ?.supportsModelGeneration;
524
403
  return supportsModelGeneraiton ? (
525
404
  <SchemaSetModelGenerationEditor
526
- schemaSetEditorState={schemaSetEditorState}
405
+ modelGenerationState={
406
+ schemaSetEditorState.schemaSetModelGenerationState
407
+ }
408
+ isReadOnly={isReadOnly}
527
409
  />
528
410
  ) : (
529
411
  <BlankPanelContent>
@@ -531,11 +413,12 @@ export const SchemaSetEditor = observer(() => {
531
413
  </BlankPanelContent>
532
414
  );
533
415
  };
416
+
534
417
  return (
535
418
  <div className="panel schema-set-panel">
536
419
  <div className="schema-set-panel__header">
537
420
  <div className="schema-set-panel__header__title">
538
- {isReadOnly && (
421
+ {schemaSetEditorState.isReadOnly && (
539
422
  <div className="schema-set-panel__header__lock">
540
423
  <LockIcon />
541
424
  </div>
@@ -544,7 +427,7 @@ export const SchemaSetEditor = observer(() => {
544
427
  Schema Set
545
428
  </div>
546
429
  <div className="schema-set-panel__header__title__content">
547
- {schemaSet.name}
430
+ {schemaSetEditorState.schemaSet.name}
548
431
  </div>
549
432
  </div>
550
433
  </div>
@@ -568,13 +451,14 @@ export const SchemaSetEditor = observer(() => {
568
451
  </div>
569
452
 
570
453
  <div className="panel__content file-generation-editor__content">
571
- {currentTab === SCHEMA_SET_TAB_TYPE.GENERAL && (
454
+ {currentTab === SCHEMA_SET_TAB_TYPE.SCHEMAS && (
572
455
  <SchemaSetGeneralEditor
573
456
  schemaSetEditorState={schemaSetEditorState}
457
+ isReadOnly={isReadOnly}
574
458
  />
575
459
  )}
576
460
 
577
- {currentTab === SCHEMA_SET_TAB_TYPE.MODEL_GENERATION &&
461
+ {currentTab === SCHEMA_SET_TAB_TYPE.GENERATE_MODEL &&
578
462
  renderMainEditPanel()}
579
463
  </div>
580
464
  </div>