@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.
- package/lib/components/EditorComponentTestUtils.d.ts +3 -13
- package/lib/components/EditorComponentTestUtils.d.ts.map +1 -1
- package/lib/components/EditorComponentTestUtils.js +3 -22
- package/lib/components/EditorComponentTestUtils.js.map +1 -1
- package/lib/components/editor/edit-panel/EditPanel.js +4 -4
- package/lib/components/editor/edit-panel/EditPanel.js.map +1 -1
- package/lib/components/editor/edit-panel/{ModelLoader.d.ts → ModelImporter.d.ts} +2 -2
- package/lib/components/editor/edit-panel/ModelImporter.d.ts.map +1 -0
- package/lib/components/editor/edit-panel/ModelImporter.js +132 -0
- package/lib/components/editor/edit-panel/ModelImporter.js.map +1 -0
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.d.ts +7 -0
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.js +18 -42
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.js.map +1 -1
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.d.ts +24 -0
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.d.ts.map +1 -0
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.js +75 -0
- package/lib/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.js.map +1 -0
- package/lib/components/editor/side-bar/Explorer.js +4 -4
- package/lib/components/editor/side-bar/Explorer.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/EditorGraphState.d.ts +1 -1
- package/lib/stores/EditorGraphState.d.ts.map +1 -1
- package/lib/stores/EditorGraphState.js +10 -10
- package/lib/stores/EditorGraphState.js.map +1 -1
- package/lib/stores/EditorStore.d.ts +3 -3
- package/lib/stores/EditorStore.d.ts.map +1 -1
- package/lib/stores/EditorStore.js +6 -8
- package/lib/stores/EditorStore.js.map +1 -1
- package/lib/stores/LegendStudioApplicationPlugin.d.ts +3 -3
- package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/editor-state/ExternalFormatState.d.ts +3 -2
- package/lib/stores/editor-state/ExternalFormatState.d.ts.map +1 -1
- package/lib/stores/editor-state/ExternalFormatState.js +11 -8
- package/lib/stores/editor-state/ExternalFormatState.js.map +1 -1
- package/lib/stores/editor-state/ModelImporterState.d.ts +95 -0
- package/lib/stores/editor-state/ModelImporterState.d.ts.map +1 -0
- package/lib/stores/editor-state/ModelImporterState.js +358 -0
- package/lib/stores/editor-state/ModelImporterState.js.map +1 -0
- package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts +35 -12
- package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js +141 -34
- package/lib/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js.map +1 -1
- package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts +1 -0
- package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js +3 -0
- package/lib/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js.map +1 -1
- package/package.json +3 -3
- package/src/components/EditorComponentTestUtils.tsx +2 -29
- package/src/components/editor/edit-panel/EditPanel.tsx +4 -4
- package/src/components/editor/edit-panel/ModelImporter.tsx +376 -0
- package/src/components/editor/edit-panel/external-format-editor/SchemaSetElementEditor.tsx +47 -163
- package/src/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.tsx +226 -0
- package/src/components/editor/side-bar/Explorer.tsx +8 -8
- package/src/stores/EditorGraphState.ts +13 -12
- package/src/stores/EditorStore.ts +7 -9
- package/src/stores/LegendStudioApplicationPlugin.ts +4 -4
- package/src/stores/editor-state/ExternalFormatState.ts +15 -12
- package/src/stores/editor-state/ModelImporterState.ts +506 -0
- package/src/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.ts +203 -46
- package/src/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.ts +5 -0
- package/tsconfig.json +3 -2
- package/lib/components/editor/edit-panel/ModelLoader.d.ts.map +0 -1
- package/lib/components/editor/edit-panel/ModelLoader.js +0 -95
- package/lib/components/editor/edit-panel/ModelLoader.js.map +0 -1
- package/lib/stores/editor-state/ModelLoaderState.d.ts +0 -52
- package/lib/stores/editor-state/ModelLoaderState.d.ts.map +0 -1
- package/lib/stores/editor-state/ModelLoaderState.js +0 -199
- package/lib/stores/editor-state/ModelLoaderState.js.map +0 -1
- package/src/components/editor/edit-panel/ModelLoader.tsx +0 -259
- package/src/stores/editor-state/ModelLoaderState.ts +0 -280
package/src/components/editor/edit-panel/external-format-editor/SchemaSetModelGenerationEditor.tsx
ADDED
|
@@ -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
|
|
487
|
-
editorStore.openSingletonEditorState(editorStore.
|
|
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={
|
|
664
|
+
onClick={openModelImport}
|
|
665
665
|
>
|
|
666
|
-
Open Model
|
|
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
|
|
692
|
-
editorStore.openState(editorStore.
|
|
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
|
|
701
|
-
onClick={
|
|
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 {
|
|
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
|
|
307
|
-
this.
|
|
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
|
|
336
|
-
this.
|
|
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
|
|
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
|
|
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
|
-
|
|
380
|
-
this.editorStore.openState(this.editorStore.
|
|
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 {
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
963
|
-
this.openSingletonEditorState(this.
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
101
|
+
* Get the list of extension configurations for model importer.
|
|
102
102
|
*/
|
|
103
|
-
|
|
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((
|
|
62
|
-
value:
|
|
63
|
-
label:
|
|
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
|
|
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
|
}
|