@finos/legend-application-studio 13.1.2 → 14.0.0

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 (72) 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 +132 -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/side-bar/Explorer.js +4 -4
  20. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  21. package/lib/index.css +1 -1
  22. package/lib/package.json +1 -1
  23. package/lib/stores/EditorGraphState.d.ts +1 -1
  24. package/lib/stores/EditorGraphState.d.ts.map +1 -1
  25. package/lib/stores/EditorGraphState.js +10 -10
  26. package/lib/stores/EditorGraphState.js.map +1 -1
  27. package/lib/stores/EditorStore.d.ts +3 -3
  28. package/lib/stores/EditorStore.d.ts.map +1 -1
  29. package/lib/stores/EditorStore.js +6 -8
  30. package/lib/stores/EditorStore.js.map +1 -1
  31. package/lib/stores/LegendStudioApplicationPlugin.d.ts +3 -3
  32. package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
  33. package/lib/stores/editor-state/ExternalFormatState.d.ts +3 -2
  34. package/lib/stores/editor-state/ExternalFormatState.d.ts.map +1 -1
  35. package/lib/stores/editor-state/ExternalFormatState.js +11 -8
  36. package/lib/stores/editor-state/ExternalFormatState.js.map +1 -1
  37. package/lib/stores/editor-state/ModelImporterState.d.ts +95 -0
  38. package/lib/stores/editor-state/ModelImporterState.d.ts.map +1 -0
  39. package/lib/stores/editor-state/ModelImporterState.js +358 -0
  40. package/lib/stores/editor-state/ModelImporterState.js.map +1 -0
  41. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts +35 -12
  42. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts.map +1 -1
  43. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js +141 -34
  44. package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js.map +1 -1
  45. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts +1 -0
  46. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts.map +1 -1
  47. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js +3 -0
  48. package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js.map +1 -1
  49. package/package.json +3 -3
  50. package/src/components/EditorComponentTestUtils.tsx +2 -29
  51. package/src/components/editor/edit-panel/EditPanel.tsx +4 -4
  52. package/src/components/editor/edit-panel/ModelImporter.tsx +376 -0
  53. package/src/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.tsx +47 -163
  54. package/src/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.tsx +226 -0
  55. package/src/components/editor/side-bar/Explorer.tsx +8 -8
  56. package/src/stores/EditorGraphState.ts +13 -12
  57. package/src/stores/EditorStore.ts +7 -9
  58. package/src/stores/LegendStudioApplicationPlugin.ts +4 -4
  59. package/src/stores/editor-state/ExternalFormatState.ts +15 -12
  60. package/src/stores/editor-state/ModelImporterState.ts +506 -0
  61. package/src/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.ts +203 -46
  62. package/src/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.ts +5 -0
  63. package/tsconfig.json +3 -2
  64. package/lib/components/editor/edit-panel/ModelLoader.d.ts.map +0 -1
  65. package/lib/components/editor/edit-panel/ModelLoader.js +0 -95
  66. package/lib/components/editor/edit-panel/ModelLoader.js.map +0 -1
  67. package/lib/stores/editor-state/ModelLoaderState.d.ts +0 -52
  68. package/lib/stores/editor-state/ModelLoaderState.d.ts.map +0 -1
  69. package/lib/stores/editor-state/ModelLoaderState.js +0 -199
  70. package/lib/stores/editor-state/ModelLoaderState.js.map +0 -1
  71. package/src/components/editor/edit-panel/ModelLoader.tsx +0 -259
  72. package/src/stores/editor-state/ModelLoaderState.ts +0 -280
@@ -0,0 +1,226 @@
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 { type GenerationProperty, isValidFullPath } from '@finos/legend-graph';
18
+ import { flowResult } from 'mobx';
19
+ import { observer } from 'mobx-react-lite';
20
+ import { useMemo } from 'react';
21
+ import type { SchemaSetModelGenerationState } from '../../../../stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js';
22
+ import { debounce } from '@finos/legend-shared';
23
+ import {
24
+ clsx,
25
+ InputWithInlineValidation,
26
+ PanelLoadingIndicator,
27
+ RefreshIcon,
28
+ ResizablePanel,
29
+ ResizablePanelGroup,
30
+ ResizablePanelSplitter,
31
+ ResizablePanelSplitterLine,
32
+ } from '@finos/legend-art';
33
+ import { GenerationPropertyEditor } from '../element-generation-editor/FileGenerationEditor.js';
34
+ import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor.js';
35
+ import { EDITOR_LANGUAGE } from '@finos/legend-application';
36
+
37
+ enum HIDDEN_CONFIGURATION_PROPERTIES {
38
+ FORMAT = 'format',
39
+ }
40
+
41
+ export const SchemaSetModelGenerationEditor = observer(
42
+ (props: {
43
+ modelGenerationState: SchemaSetModelGenerationState;
44
+ isReadOnly: boolean;
45
+ }) => {
46
+ const { modelGenerationState, isReadOnly } = props;
47
+ const applicationStore = modelGenerationState.editorStore.applicationStore;
48
+ const format = modelGenerationState.schemaSet.format;
49
+ const description = modelGenerationState.description;
50
+ const properties = description?.modelGenerationProperties ?? [];
51
+ const debouncedRegenerate = useMemo(
52
+ () =>
53
+ debounce(() => flowResult(modelGenerationState.generateModel()), 500),
54
+ [modelGenerationState],
55
+ );
56
+ const update = (
57
+ generationProperty: GenerationProperty,
58
+ newValue: object,
59
+ ): void => {
60
+ debouncedRegenerate.cancel();
61
+ modelGenerationState.updateGenerationParameters(
62
+ generationProperty,
63
+ newValue,
64
+ );
65
+ debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
66
+ };
67
+ const regenerate = (): void => {
68
+ modelGenerationState.generateModel();
69
+ };
70
+ const getConfigValue = (name: string): unknown | undefined =>
71
+ modelGenerationState.getConfigValue(name);
72
+ const targetBindingPathValidationMessage =
73
+ Boolean(modelGenerationState.targetBinding) &&
74
+ !isValidFullPath(modelGenerationState.targetBinding)
75
+ ? 'Invalid target binding path'
76
+ : undefined;
77
+
78
+ const changeTargetBindingPath: React.ChangeEventHandler<
79
+ HTMLInputElement
80
+ > = (event) => {
81
+ modelGenerationState.setTargetBindingPath(event.target.value);
82
+ if (
83
+ !modelGenerationState.targetBinding ||
84
+ (modelGenerationState.targetBinding &&
85
+ isValidFullPath(modelGenerationState.targetBinding))
86
+ ) {
87
+ modelGenerationState.handleTargetBindingPathChange();
88
+ debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
89
+ }
90
+ };
91
+ const importGeneratedElements = (): void => {
92
+ modelGenerationState.importGeneratedModelsIntoGraph();
93
+ };
94
+
95
+ return (
96
+ <div className="panel__content file-generation-editor__content">
97
+ <ResizablePanelGroup orientation="vertical">
98
+ <ResizablePanel size={250} minSize={50}>
99
+ <div className="panel file-generation-editor__configuration">
100
+ <div className="panel__header">
101
+ <div className="panel__header__title">
102
+ <div className="panel__header__title__label">{`${format} configuration`}</div>
103
+ </div>
104
+ <div className="panel__header__actions">
105
+ <button
106
+ className="panel__header__action file-generation-editor__configuration__reset-btn"
107
+ tabIndex={-1}
108
+ disabled={isReadOnly || !properties.length}
109
+ onClick={regenerate}
110
+ title={'Reset to default configuration'}
111
+ >
112
+ <RefreshIcon />
113
+ </button>
114
+ </div>
115
+ </div>
116
+ <div className="panel__content">
117
+ <div className="file-generation-editor__configuration__content">
118
+ <div className="panel__content__form__section">
119
+ <div className="panel__content__form__section__header__label">
120
+ {'Target Binding Path'}
121
+ </div>
122
+ <div className="panel__content__form__section__header__prompt">
123
+ {
124
+ 'If path is provided, a binding will be generated alongside the models. The binding will ensure the schema and models are compatible through compile time validations.'
125
+ }
126
+ </div>
127
+ <InputWithInlineValidation
128
+ className="query-builder__parameters__parameter__name__input input-group__input"
129
+ spellCheck={false}
130
+ value={modelGenerationState.targetBinding}
131
+ onChange={changeTargetBindingPath}
132
+ placeholder={`Target binding path`}
133
+ validationErrorMessage={
134
+ targetBindingPathValidationMessage
135
+ }
136
+ />
137
+ </div>
138
+
139
+ {modelGenerationState.modelGenerationProperties
140
+ .filter(
141
+ (property) =>
142
+ !Object.values(
143
+ HIDDEN_CONFIGURATION_PROPERTIES,
144
+ ).includes(
145
+ property.name as HIDDEN_CONFIGURATION_PROPERTIES,
146
+ ),
147
+ )
148
+ .map((abstractGenerationProperty) => (
149
+ <GenerationPropertyEditor
150
+ key={abstractGenerationProperty.name}
151
+ update={update}
152
+ isReadOnly={isReadOnly}
153
+ getConfigValue={getConfigValue}
154
+ property={abstractGenerationProperty}
155
+ />
156
+ ))}
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </ResizablePanel>
161
+ <ResizablePanelSplitter>
162
+ <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
163
+ </ResizablePanelSplitter>
164
+ <ResizablePanel>
165
+ <div className="panel generation-result-viewer__file">
166
+ <div className="panel__header">
167
+ <div className="panel__header__title">
168
+ <div className="panel__header__title__label">result</div>
169
+ </div>
170
+ <div className="panel__header__actions">
171
+ <button
172
+ className={clsx(
173
+ 'panel__header__action generation-result-viewer__regenerate-btn',
174
+ {
175
+ ' generation-result-viewer__regenerate-btn--loading':
176
+ modelGenerationState.generatingModelsState
177
+ .isInProgress ||
178
+ modelGenerationState.importGeneratedElementsState
179
+ .isInProgress,
180
+ },
181
+ )}
182
+ tabIndex={-1}
183
+ disabled={
184
+ modelGenerationState.generatingModelsState.isInProgress ||
185
+ modelGenerationState.importGeneratedElementsState
186
+ .isInProgress
187
+ }
188
+ onClick={regenerate}
189
+ title={'Re-generate'}
190
+ >
191
+ <RefreshIcon />
192
+ </button>
193
+ {!modelGenerationState.isolatedGraph && (
194
+ <button
195
+ className="btn--dark model-loader__header__load-btn"
196
+ onClick={importGeneratedElements}
197
+ disabled={modelGenerationState.generationValue === ''}
198
+ tabIndex={-1}
199
+ title="Import generated elements"
200
+ >
201
+ Import
202
+ </button>
203
+ )}
204
+ </div>
205
+ </div>
206
+ <div className="panel__content">
207
+ <PanelLoadingIndicator
208
+ isLoading={
209
+ modelGenerationState.generatingModelsState.isInProgress ||
210
+ modelGenerationState.importGeneratedElementsState
211
+ .isInProgress
212
+ }
213
+ />
214
+ <StudioTextInputEditor
215
+ inputValue={modelGenerationState.generationValue}
216
+ isReadOnly={true}
217
+ language={EDITOR_LANGUAGE.PURE}
218
+ />
219
+ </div>
220
+ </div>
221
+ </ResizablePanel>
222
+ </ResizablePanelGroup>
223
+ </div>
224
+ );
225
+ },
226
+ );
@@ -483,8 +483,8 @@ const ExplorerDropdownMenu = observer(() => {
483
483
  const ExplorerTrees = observer(() => {
484
484
  const editorStore = useEditorStore();
485
485
  const { isInGrammarTextMode, isInViewerMode } = editorStore;
486
- const openModelLoader = (): void =>
487
- editorStore.openSingletonEditorState(editorStore.modelLoaderState);
486
+ const openModelImport = (): void =>
487
+ editorStore.openSingletonEditorState(editorStore.modelImporterState);
488
488
  const graph = editorStore.graphManagerState.graph;
489
489
  // Explorer tree
490
490
  const treeData = editorStore.explorerTreeState.getTreeData();
@@ -661,9 +661,9 @@ const ExplorerTrees = observer(() => {
661
661
  </div>
662
662
  <button
663
663
  className="btn--dark explorer__content--empty__btn"
664
- onClick={openModelLoader}
664
+ onClick={openModelImport}
665
665
  >
666
- Open Model Loader
666
+ Open Model Importer
667
667
  </button>
668
668
  </div>
669
669
  )}
@@ -688,8 +688,8 @@ const ProjectExplorerActionPanel = observer((props: { disabled: boolean }) => {
688
688
  });
689
689
  editorStore.explorerTreeState.setTreeData({ ...treeData });
690
690
  };
691
- const showModelLoader = (): void =>
692
- editorStore.openState(editorStore.modelLoaderState);
691
+ const showModelImporter = (): void =>
692
+ editorStore.openState(editorStore.modelImporterState);
693
693
 
694
694
  return (
695
695
  <div className="panel__header__actions">
@@ -697,8 +697,8 @@ const ProjectExplorerActionPanel = observer((props: { disabled: boolean }) => {
697
697
  <button
698
698
  className="panel__header__action"
699
699
  disabled={disabled}
700
- title="Open Model Loader (F2)"
701
- onClick={showModelLoader}
700
+ title="Open Model Importer (F2)"
701
+ onClick={showModelImporter}
702
702
  >
703
703
  <FileImportIcon />
704
704
  </button>
@@ -35,7 +35,7 @@ import {
35
35
  import type { EditorStore } from './EditorStore.js';
36
36
  import { ElementEditorState } from './editor-state/element-editor-state/ElementEditorState.js';
37
37
  import { GraphGenerationState } from './editor-state/GraphGenerationState.js';
38
- import { MODEL_UPDATER_INPUT_TYPE } from './editor-state/ModelLoaderState.js';
38
+ import { MODEL_IMPORT_NATIVE_INPUT_TYPE } from './editor-state/ModelImporterState.js';
39
39
  import type { DSL_LegendStudioApplicationPlugin_Extension } from './LegendStudioApplicationPlugin.js';
40
40
  import type { Entity } from '@finos/legend-storage';
41
41
  import {
@@ -303,8 +303,8 @@ export class EditorGraphState {
303
303
  );
304
304
  this.editorStore.setCurrentEditorState(projectConfigurationEditorState);
305
305
  } else if (error instanceof GraphDataDeserializationError) {
306
- // if something goes wrong with de-serialization, redirect to model loader to fix
307
- this.redirectToModelLoaderForDebugging(error);
306
+ // if something goes wrong with de-serialization, redirect to model importer to fix
307
+ this.redirectToModelImporterForDebugging(error);
308
308
  } else if (error instanceof NetworkClientError) {
309
309
  this.editorStore.graphManagerState.graphBuildState.fail();
310
310
  this.editorStore.applicationStore.notifyWarning(
@@ -332,8 +332,8 @@ export class EditorGraphState {
332
332
  error2,
333
333
  );
334
334
  if (error2 instanceof NetworkClientError) {
335
- // in case the server cannot even transform the JSON due to corrupted protocol, we can redirect to model loader
336
- this.redirectToModelLoaderForDebugging(error2);
335
+ // in case the server cannot even transform the JSON due to corrupted protocol, we can redirect to model importer
336
+ this.redirectToModelImporterForDebugging(error2);
337
337
  return {
338
338
  status: GraphBuilderStatus.FAILED,
339
339
  error: error2,
@@ -361,7 +361,7 @@ export class EditorGraphState {
361
361
  }
362
362
  }
363
363
 
364
- private redirectToModelLoaderForDebugging(error: Error): void {
364
+ private redirectToModelImporterForDebugging(error: Error): void {
365
365
  if (this.editorStore.isInConflictResolutionMode) {
366
366
  this.editorStore.setBlockingAlert({
367
367
  message: `Can't de-serialize graph model from entities`,
@@ -370,14 +370,15 @@ export class EditorGraphState {
370
370
  return;
371
371
  }
372
372
  this.editorStore.applicationStore.notifyWarning(
373
- `Can't de-serialize graph model from entities. Redirected to model loader for debugging. Error: ${error.message}`,
374
- );
375
- this.editorStore.modelLoaderState.setCurrentModelLoadType(
376
- MODEL_UPDATER_INPUT_TYPE.ENTITIES,
373
+ `Can't de-serialize graph model from entities. Redirected to model importer for debugging. Error: ${error.message}`,
377
374
  );
375
+ const nativeImporterState =
376
+ this.editorStore.modelImporterState.setNativeImportType(
377
+ MODEL_IMPORT_NATIVE_INPUT_TYPE.ENTITIES,
378
+ );
378
379
  // Making an async call
379
- this.editorStore.modelLoaderState.loadCurrentProjectEntities();
380
- this.editorStore.openState(this.editorStore.modelLoaderState);
380
+ nativeImporterState.loadCurrentProjectEntities();
381
+ this.editorStore.openState(this.editorStore.modelImporterState);
381
382
  }
382
383
 
383
384
  /**
@@ -59,7 +59,7 @@ import {
59
59
  import { UMLEditorState } from './editor-state/element-editor-state/UMLEditorState.js';
60
60
  import { ServiceEditorState } from './editor-state/element-editor-state/service/ServiceEditorState.js';
61
61
  import { EditorSDLCState } from './EditorSDLCState.js';
62
- import { ModelLoaderState } from './editor-state/ModelLoaderState.js';
62
+ import { ModelImporterState } from './editor-state/ModelImporterState.js';
63
63
  import type { EditorState } from './editor-state/EditorState.js';
64
64
  import { EntityDiffViewState } from './editor-state/entity-diff-editor-state/EntityDiffViewState.js';
65
65
  import { FunctionEditorState } from './editor-state/element-editor-state/FunctionEditorState.js';
@@ -186,7 +186,7 @@ export class EditorStore {
186
186
  graphManagerState: GraphManagerState;
187
187
  changeDetectionState: ChangeDetectionState;
188
188
  grammarTextEditorState: GrammarTextEditorState;
189
- modelLoaderState: ModelLoaderState;
189
+ modelImporterState: ModelImporterState;
190
190
  projectConfigurationEditorState: ProjectConfigurationEditorState;
191
191
  projectOverviewState: ProjectOverviewState;
192
192
  workspaceWorkflowManagerState: WorkspaceWorkflowManagerState;
@@ -315,7 +315,7 @@ export class EditorStore {
315
315
  this.newElementState = new NewElementState(this);
316
316
  // special (singleton) editors
317
317
  this.grammarTextEditorState = new GrammarTextEditorState(this);
318
- this.modelLoaderState = new ModelLoaderState(this);
318
+ this.modelImporterState = new ModelImporterState(this);
319
319
  this.projectConfigurationEditorState = new ProjectConfigurationEditorState(
320
320
  this,
321
321
  this.sdlcState,
@@ -375,7 +375,7 @@ export class EditorStore {
375
375
  LEGEND_STUDIO_HOTKEY.TOGGLE_MODEL_LOADER,
376
376
  [LEGEND_STUDIO_HOTKEY_MAP.TOGGLE_MODEL_LOADER],
377
377
  this.createGlobalHotKeyAction(() =>
378
- this.openState(this.modelLoaderState),
378
+ this.openState(this.modelImporterState),
379
379
  ),
380
380
  ),
381
381
  new HotkeyConfiguration(
@@ -736,7 +736,6 @@ export class EditorStore {
736
736
  this.projectConfigurationEditorState.fetchLatestProjectStructureVersion(),
737
737
  this.graphState.graphGenerationState.fetchAvailableFileGenerationDescriptions(),
738
738
  this.graphState.graphGenerationState.externalFormatState.fetchExternalFormatsDescriptions(),
739
- this.modelLoaderState.fetchAvailableModelImportDescriptions(),
740
739
  this.sdlcState.fetchProjectVersions(),
741
740
  ]);
742
741
  }
@@ -775,7 +774,6 @@ export class EditorStore {
775
774
  this.projectConfigurationEditorState.fetchLatestProjectStructureVersion(),
776
775
  this.graphState.graphGenerationState.fetchAvailableFileGenerationDescriptions(),
777
776
  this.graphState.graphGenerationState.externalFormatState.fetchExternalFormatsDescriptions(),
778
- this.modelLoaderState.fetchAvailableModelImportDescriptions(),
779
777
  this.sdlcState.fetchProjectVersions(),
780
778
  ]);
781
779
  }
@@ -959,8 +957,8 @@ export class EditorStore {
959
957
  this.openEntityChangeConflict(editorState);
960
958
  } else if (editorState instanceof FileGenerationViewerState) {
961
959
  this.openGeneratedFile(editorState.generatedFile);
962
- } else if (editorState === this.modelLoaderState) {
963
- this.openSingletonEditorState(this.modelLoaderState);
960
+ } else if (editorState === this.modelImporterState) {
961
+ this.openSingletonEditorState(this.modelImporterState);
964
962
  } else if (editorState === this.projectConfigurationEditorState) {
965
963
  this.openSingletonEditorState(this.projectConfigurationEditorState);
966
964
  } else {
@@ -1008,7 +1006,7 @@ export class EditorStore {
1008
1006
  * This method helps open editor that only exists one instance at at time such as model-loader, project config, settings ...
1009
1007
  */
1010
1008
  openSingletonEditorState(
1011
- singularEditorState: ModelLoaderState | ProjectConfigurationEditorState,
1009
+ singularEditorState: ModelImporterState | ProjectConfigurationEditorState,
1012
1010
  ): void {
1013
1011
  const existingEditorState = this.openedEditorStates.find(
1014
1012
  (e) => e === singularEditorState,
@@ -49,12 +49,12 @@ export type ClassPreviewRenderer = (
49
49
  _class: Class,
50
50
  ) => React.ReactNode | undefined;
51
51
 
52
- export type ModelLoaderExtensionConfiguration = {
52
+ export type ModelImporterExtensionConfiguration = {
53
53
  key: string;
54
54
  label?: string | undefined;
55
55
  allowHardReplace?: boolean;
56
56
  // TODO: document about this behavior better, right now the behavior is not well
57
- // structured yet, also, model loader seems rather fragmented at the moment
57
+ // structured yet, also, model importer seems rather fragmented at the moment
58
58
  load: (editorStore: EditorStore) => Promise<void>;
59
59
  renderer: (editorStore: EditorStore) => React.ReactNode | undefined;
60
60
  };
@@ -98,9 +98,9 @@ export abstract class LegendStudioApplicationPlugin extends LegendApplicationPlu
98
98
  getExtraEditorExtensionComponentRendererConfigurations?(): EditorExtensionComponentRendererConfiguration[];
99
99
 
100
100
  /**
101
- * Get the list of extension configurations for model loader.
101
+ * Get the list of extension configurations for model importer.
102
102
  */
103
- getExtraModelLoaderExtensionConfigurations?(): ModelLoaderExtensionConfiguration[];
103
+ getExtraModelImporterExtensionConfigurations?(): ModelImporterExtensionConfiguration[];
104
104
 
105
105
  /**
106
106
  * Get the list of extension for testables
@@ -18,7 +18,6 @@ import type { ExternalFormatDescription } from '@finos/legend-graph';
18
18
  import {
19
19
  type GeneratorFn,
20
20
  assertErrorThrown,
21
- guaranteeNonNullable,
22
21
  LogEvent,
23
22
  ActionState,
24
23
  } from '@finos/legend-shared';
@@ -58,12 +57,22 @@ export class ExternalFormatState {
58
57
  }
59
58
 
60
59
  get formatTypeOptions(): ExternalFormatTypeOption[] {
61
- return this.externalFormatsDescriptions.map((e) => ({
62
- value: e.name,
63
- label: e.name,
60
+ return this.externalFormatsDescriptions.map((types) => ({
61
+ value: types.name,
62
+ label: types.name,
64
63
  }));
65
64
  }
66
65
 
66
+ get formatContentTypes(): string[] {
67
+ return this.externalFormatsDescriptions.map((e) => e.contentTypes).flat();
68
+ }
69
+
70
+ get externalFormatDescriptionsWithModelGenerationSupport(): ExternalFormatDescription[] {
71
+ return this.externalFormatsDescriptions.filter(
72
+ (d) => d.supportsModelGeneration,
73
+ );
74
+ }
75
+
67
76
  getFormatTypeForContentType(contentType: string): string | undefined {
68
77
  return this.externalFormatsDescriptions.find(
69
78
  (externalFormatDescription) =>
@@ -71,10 +80,6 @@ export class ExternalFormatState {
71
80
  )?.name;
72
81
  }
73
82
 
74
- get formatContentTypes(): string[] {
75
- return this.externalFormatsDescriptions.map((e) => e.contentTypes).flat();
76
- }
77
-
78
83
  setExternalFormatsDescriptions(
79
84
  externalFormatsDescriptions: ExternalFormatDescription[],
80
85
  ): void {
@@ -99,9 +104,7 @@ export class ExternalFormatState {
99
104
  }
100
105
  }
101
106
 
102
- getTypeDescription(type: string): ExternalFormatDescription {
103
- return guaranteeNonNullable(
104
- this.externalFormatsDescriptions.find((e) => e.name === type),
105
- );
107
+ getTypeDescription(type: string): ExternalFormatDescription | undefined {
108
+ return this.externalFormatsDescriptions.find((e) => e.name === type);
106
109
  }
107
110
  }