@finos/legend-application-studio 13.1.0 → 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/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.js +10 -2
- package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
- 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/edit-panel/service-editor/testable/ServiceTestDataEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.js +6 -4
- package/lib/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.js.map +1 -1
- package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.js +2 -4
- package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.js.map +1 -1
- 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 +2 -2
- package/lib/index.css.map +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/NewElementState.d.ts.map +1 -1
- package/lib/stores/editor/NewElementState.js +4 -3
- package/lib/stores/editor/NewElementState.js.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/connection/ConnectionEditorState.d.ts +2 -1
- package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.js +9 -1
- package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.js.map +1 -1
- 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/editor-state/element-editor-state/service/ServiceExecutionState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/service/ServiceExecutionState.js +1 -1
- package/lib/stores/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.js +2 -2
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.js.map +1 -1
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestEditorState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js +3 -3
- package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestEditorState.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/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.d.ts +2 -1
- package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.js +3 -0
- package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.js.map +1 -1
- package/lib/stores/shared/testable/TestableUtils.d.ts.map +1 -1
- package/lib/stores/shared/testable/TestableUtils.js +2 -3
- package/lib/stores/shared/testable/TestableUtils.js.map +1 -1
- package/package.json +9 -9
- 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/connection-editor/RelationalDatabaseConnectionEditor.tsx +36 -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/edit-panel/service-editor/testable/ServiceTestDataEditor.tsx +63 -36
- package/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx +1 -7
- 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/NewElementState.ts +4 -3
- 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/connection/ConnectionEditorState.ts +10 -0
- package/src/stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.ts +203 -46
- package/src/stores/editor-state/element-editor-state/service/ServiceExecutionState.ts +1 -0
- package/src/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts +2 -1
- package/src/stores/editor-state/element-editor-state/service/testable/ServiceTestEditorState.ts +12 -3
- package/src/stores/graphModifier/DSLExternalFormat_GraphModifierHelper.ts +5 -0
- package/src/stores/graphModifier/StoreRelational_GraphModifierHelper.ts +10 -0
- package/src/stores/shared/testable/TestableUtils.ts +4 -3
- 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
|
@@ -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: {
|
|
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: {
|
|
204
|
-
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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.
|
|
392
|
+
if (currentTab === SCHEMA_SET_TAB_TYPE.SCHEMAS) {
|
|
517
393
|
return (
|
|
518
|
-
<SchemaSetGeneralEditor
|
|
394
|
+
<SchemaSetGeneralEditor
|
|
395
|
+
schemaSetEditorState={schemaSetEditorState}
|
|
396
|
+
isReadOnly={isReadOnly}
|
|
397
|
+
/>
|
|
519
398
|
);
|
|
520
399
|
}
|
|
521
400
|
const supportsModelGeneraiton =
|
|
522
401
|
schemaSetEditorState.schemaSetModelGenerationState.description
|
|
523
|
-
|
|
402
|
+
?.supportsModelGeneration;
|
|
524
403
|
return supportsModelGeneraiton ? (
|
|
525
404
|
<SchemaSetModelGenerationEditor
|
|
526
|
-
|
|
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.
|
|
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.
|
|
461
|
+
{currentTab === SCHEMA_SET_TAB_TYPE.GENERATE_MODEL &&
|
|
578
462
|
renderMainEditPanel()}
|
|
579
463
|
</div>
|
|
580
464
|
</div>
|
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
|
+
);
|
|
@@ -212,12 +212,14 @@ export const NewConnectionDataModal = observer(
|
|
|
212
212
|
const dataElementOptions = testDataState.editorStore.dataOptions;
|
|
213
213
|
const newConnectionState = testDataState.newConnectionDataState;
|
|
214
214
|
const dataElement = newConnectionState.dataElement;
|
|
215
|
-
const
|
|
215
|
+
const selectedDataElement = dataElement
|
|
216
|
+
? buildElementOption(dataElement)
|
|
217
|
+
: null;
|
|
216
218
|
const onDataElementChange = (val: {
|
|
217
219
|
label: string;
|
|
218
220
|
value?: DataElement;
|
|
219
221
|
}): void => {
|
|
220
|
-
if (val.value !==
|
|
222
|
+
if (val.value !== selectedDataElement?.value && val.value) {
|
|
221
223
|
newConnectionState.setDataElement(val.value);
|
|
222
224
|
}
|
|
223
225
|
};
|
|
@@ -265,7 +267,7 @@ export const NewConnectionDataModal = observer(
|
|
|
265
267
|
// external format
|
|
266
268
|
const selectedEmbeddedType = newConnectionState.embeddedDataType
|
|
267
269
|
? {
|
|
268
|
-
label: prettyCONSTName(newConnectionState.embeddedDataType.
|
|
270
|
+
label: prettyCONSTName(newConnectionState.embeddedDataType.value),
|
|
269
271
|
value: newConnectionState.embeddedDataType.value,
|
|
270
272
|
}
|
|
271
273
|
: undefined;
|
|
@@ -301,42 +303,67 @@ export const NewConnectionDataModal = observer(
|
|
|
301
303
|
>
|
|
302
304
|
<form
|
|
303
305
|
onSubmit={handleSubmit}
|
|
304
|
-
className="modal modal--dark
|
|
306
|
+
className="modal service-test-data-modal modal--dark"
|
|
305
307
|
>
|
|
306
|
-
<div className="
|
|
307
|
-
|
|
308
|
-
<CustomSelectorInput
|
|
309
|
-
className="explorer__new-element-modal__driver__dropdown"
|
|
310
|
-
options={connectionOptions}
|
|
311
|
-
onChange={onConnectionSelectionChange}
|
|
312
|
-
value={selectedConnection}
|
|
313
|
-
isClearable={false}
|
|
314
|
-
darkMode={true}
|
|
315
|
-
/>
|
|
308
|
+
<div className="modal__header">
|
|
309
|
+
<div className="modal__title">Create a connection test data</div>
|
|
316
310
|
</div>
|
|
317
|
-
<div className="
|
|
318
|
-
<
|
|
319
|
-
className="
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
darkMode={true}
|
|
336
|
-
/>
|
|
311
|
+
<div className="modal__body">
|
|
312
|
+
<div className="panel__content__form__section">
|
|
313
|
+
<div className="panel__content__form__section__header__label">
|
|
314
|
+
Connection ID
|
|
315
|
+
</div>
|
|
316
|
+
<div className="panel__content__form__section__header__prompt">
|
|
317
|
+
Connection in runtime to povide test data for
|
|
318
|
+
</div>
|
|
319
|
+
<div className="explorer__new-element-modal__driver">
|
|
320
|
+
<CustomSelectorInput
|
|
321
|
+
className="explorer__new-element-modal__driver__dropdown"
|
|
322
|
+
options={connectionOptions}
|
|
323
|
+
onChange={onConnectionSelectionChange}
|
|
324
|
+
value={selectedConnection}
|
|
325
|
+
isClearable={false}
|
|
326
|
+
darkMode={true}
|
|
327
|
+
/>
|
|
328
|
+
</div>
|
|
337
329
|
</div>
|
|
338
|
-
|
|
339
|
-
|
|
330
|
+
<div className="panel__content__form__section">
|
|
331
|
+
<div className="panel__content__form__section__header__label">
|
|
332
|
+
Data Type
|
|
333
|
+
</div>
|
|
334
|
+
<div className="panel__content__form__section__header__prompt">
|
|
335
|
+
Test data type that will be loaded to your test connection
|
|
336
|
+
</div>
|
|
337
|
+
<div className="explorer__new-element-modal__driver">
|
|
338
|
+
<CustomSelectorInput
|
|
339
|
+
className="explorer__new-element-modal__driver__dropdown"
|
|
340
|
+
options={embeddedOptions}
|
|
341
|
+
onChange={onEmbeddedTypeChange}
|
|
342
|
+
value={selectedEmbeddedType}
|
|
343
|
+
isClearable={false}
|
|
344
|
+
darkMode={true}
|
|
345
|
+
/>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
{selectedEmbeddedType?.value === EmbeddedDataType.DATA_ELEMENT && (
|
|
349
|
+
<div className="panel__content__form__section">
|
|
350
|
+
<div className="panel__content__form__section__header__label">
|
|
351
|
+
Data Element
|
|
352
|
+
</div>
|
|
353
|
+
<div className="explorer__new-element-modal__driver">
|
|
354
|
+
<CustomSelectorInput
|
|
355
|
+
className="panel__content__form__section__dropdown data-element-reference-editor__value__dropdown"
|
|
356
|
+
disabled={isReadOnly}
|
|
357
|
+
options={dataElementOptions}
|
|
358
|
+
onChange={onDataElementChange}
|
|
359
|
+
value={selectedDataElement}
|
|
360
|
+
darkMode={true}
|
|
361
|
+
/>
|
|
362
|
+
</div>
|
|
363
|
+
</div>
|
|
364
|
+
)}
|
|
365
|
+
</div>
|
|
366
|
+
<div className="modal__footer">
|
|
340
367
|
<button
|
|
341
368
|
type="button"
|
|
342
369
|
className="btn btn--dark"
|