@finos/legend-application-studio 26.1.11 → 27.1.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/__lib__/LegendStudioApplicationNavigationContext.d.ts +9 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js +11 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.d.ts +6 -0
- package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.js +7 -0
- package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
- package/lib/components/ElementIconUtils.d.ts.map +1 -1
- package/lib/components/ElementIconUtils.js +3 -1
- package/lib/components/ElementIconUtils.js.map +1 -1
- package/lib/components/editor/editor-group/ModelImporter.d.ts.map +1 -1
- package/lib/components/editor/editor-group/ModelImporter.js +1 -0
- package/lib/components/editor/editor-group/ModelImporter.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js +8 -10
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js +5 -0
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationalCSVDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationalCSVDataEditor.js +3 -0
- package/lib/components/editor/editor-group/data-editor/RelationalCSVDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_BindingElementEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_BindingElementEditor.js +3 -0
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_BindingElementEditor.js.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.js +3 -0
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.js.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.js +3 -0
- package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.js.map +1 -1
- package/lib/components/editor/editor-group/mapping-editor/NewMappingElementModal.js +1 -2
- package/lib/components/editor/editor-group/mapping-editor/NewMappingElementModal.js.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +6 -6
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js +16 -5
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js.map +1 -1
- package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts.map +1 -1
- package/lib/components/editor/panel-group/SQLPlaygroundPanel.js +38 -6
- package/lib/components/editor/panel-group/SQLPlaygroundPanel.js.map +1 -1
- package/lib/components/editor/side-bar/CreateNewElementModal.d.ts +3 -0
- package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
- package/lib/components/editor/side-bar/CreateNewElementModal.js +43 -1
- package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.d.ts.map +1 -1
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.js +15 -14
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.js.map +1 -1
- package/lib/components/extensions/Core_LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/components/extensions/Core_LegendStudioApplicationPlugin.js +10 -0
- package/lib/components/extensions/Core_LegendStudioApplicationPlugin.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +4 -4
- package/lib/stores/LegendStudioApplicationPlugin.d.ts +7 -7
- package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/LegendStudioApplicationPlugin.js.map +1 -1
- package/lib/stores/editor/EditorGraphState.js +1 -1
- package/lib/stores/editor/EditorGraphState.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +10 -2
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.js +0 -1
- package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
- package/lib/stores/editor/NewElementState.d.ts +0 -1
- package/lib/stores/editor/NewElementState.d.ts.map +1 -1
- package/lib/stores/editor/NewElementState.js +47 -12
- package/lib/stores/editor/NewElementState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +0 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js +26 -30
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts +4 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js +5 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.js +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js +3 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js +2 -2
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js.map +1 -1
- package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts +9 -0
- package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts.map +1 -1
- package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js +149 -3
- package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/BulkServiceRegistrationState.js +1 -1
- package/lib/stores/editor/sidebar-state/BulkServiceRegistrationState.js.map +1 -1
- package/lib/stores/editor/utils/MockDataUtils.d.ts +1 -1
- package/lib/stores/editor/utils/MockDataUtils.d.ts.map +1 -1
- package/lib/stores/editor/utils/MockDataUtils.js.map +1 -1
- package/lib/stores/editor/utils/ModelClassifierUtils.d.ts +2 -5
- package/lib/stores/editor/utils/ModelClassifierUtils.d.ts.map +1 -1
- package/lib/stores/editor/utils/ModelClassifierUtils.js +2 -6
- package/lib/stores/editor/utils/ModelClassifierUtils.js.map +1 -1
- package/lib/stores/editor/utils/PackageTreeUtils.js +3 -3
- package/lib/stores/editor/utils/PackageTreeUtils.js.map +1 -1
- package/package.json +14 -14
- package/src/__lib__/LegendStudioApplicationNavigationContext.ts +12 -1
- package/src/application/LegendStudioApplicationConfig.ts +8 -0
- package/src/components/ElementIconUtils.tsx +3 -0
- package/src/components/editor/editor-group/ModelImporter.tsx +4 -0
- package/src/components/editor/editor-group/connection-editor/DatabaseBuilder.tsx +12 -13
- package/src/components/editor/editor-group/data-editor/EmbeddedDataEditor.tsx +11 -1
- package/src/components/editor/editor-group/data-editor/RelationalCSVDataEditor.tsx +6 -0
- package/src/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_BindingElementEditor.tsx +7 -0
- package/src/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.tsx +6 -0
- package/src/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.tsx +6 -0
- package/src/components/editor/editor-group/mapping-editor/NewMappingElementModal.tsx +1 -1
- package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +6 -10
- package/src/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.tsx +22 -9
- package/src/components/editor/panel-group/SQLPlaygroundPanel.tsx +104 -18
- package/src/components/editor/side-bar/CreateNewElementModal.tsx +111 -1
- package/src/components/editor/side-bar/testable/GlobalTestRunner.tsx +21 -23
- package/src/components/extensions/Core_LegendStudioApplicationPlugin.tsx +10 -0
- package/src/stores/LegendStudioApplicationPlugin.ts +7 -11
- package/src/stores/editor/EditorGraphState.ts +1 -1
- package/src/stores/editor/EditorStore.ts +29 -17
- package/src/stores/editor/GraphEditFormModeState.ts +0 -1
- package/src/stores/editor/NewElementState.ts +115 -23
- package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +33 -40
- package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +5 -1
- package/src/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.ts +1 -1
- package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.ts +12 -2
- package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.ts +2 -2
- package/src/stores/editor/panel-group/SQLPlaygroundPanelState.ts +224 -1
- package/src/stores/editor/sidebar-state/BulkServiceRegistrationState.ts +1 -1
- package/src/stores/editor/utils/MockDataUtils.ts +1 -1
- package/src/stores/editor/utils/ModelClassifierUtils.ts +2 -6
- package/src/stores/editor/utils/PackageTreeUtils.ts +3 -3
@@ -81,6 +81,8 @@ export const getElementTypeLabel = (
|
|
81
81
|
return 'generation specification';
|
82
82
|
case PACKAGEABLE_ELEMENT_TYPE.DATA:
|
83
83
|
return 'data';
|
84
|
+
case PACKAGEABLE_ELEMENT_TYPE.TEMPORARY__LOCAL_CONNECTION:
|
85
|
+
return 'local connection';
|
84
86
|
default: {
|
85
87
|
if (type) {
|
86
88
|
const extraElementTypeLabelGetters = editorStore.pluginManager
|
@@ -436,7 +438,115 @@ const renderNewElementDriver = (
|
|
436
438
|
}
|
437
439
|
};
|
438
440
|
|
439
|
-
|
441
|
+
export const CreateNewLocalConnectionModal = observer(() => {
|
442
|
+
const editorStore = useEditorStore();
|
443
|
+
const applicationStore = useApplicationStore();
|
444
|
+
const newElementState = editorStore.newElementState;
|
445
|
+
const selectedPackage = newElementState.selectedPackage;
|
446
|
+
// Name
|
447
|
+
const name = newElementState.name;
|
448
|
+
const handleNameChange: React.ChangeEventHandler<HTMLInputElement> = (
|
449
|
+
event,
|
450
|
+
) => newElementState.setName(event.target.value);
|
451
|
+
const elementNameInputRef = useRef<HTMLInputElement>(null);
|
452
|
+
// Type
|
453
|
+
const typeOptions = ([PACKAGEABLE_ELEMENT_TYPE.PACKAGE] as string[])
|
454
|
+
.concat(editorStore.getSupportedElementTypes())
|
455
|
+
.filter(
|
456
|
+
// NOTE: we can only create package in root
|
457
|
+
(type) =>
|
458
|
+
selectedPackage !== editorStore.graphManagerState.graph.root ||
|
459
|
+
type === PACKAGEABLE_ELEMENT_TYPE.PACKAGE,
|
460
|
+
)
|
461
|
+
.map(buildElementTypeOption);
|
462
|
+
|
463
|
+
const selectedTypeOption = buildElementTypeOption(newElementState.type);
|
464
|
+
const handleTypeChange = (val: ElementTypeSelectOption): void =>
|
465
|
+
newElementState.setElementType(val.value);
|
466
|
+
// Submit button
|
467
|
+
const closeModal = (): void => newElementState.closeModal();
|
468
|
+
const [packagePath, elementName] = resolvePackageAndElementName(
|
469
|
+
selectedPackage,
|
470
|
+
selectedPackage === editorStore.graphManagerState.graph.root,
|
471
|
+
name,
|
472
|
+
);
|
473
|
+
const resolvedPackage =
|
474
|
+
editorStore.graphManagerState.graph.getNullablePackage(packagePath);
|
475
|
+
const needsToOverride = Boolean(
|
476
|
+
resolvedPackage?.children.find((child) => child.name === elementName),
|
477
|
+
);
|
478
|
+
const isDisabled = !name || needsToOverride || !newElementState.isValid;
|
479
|
+
const save = applicationStore.guardUnhandledError(() =>
|
480
|
+
flowResult(newElementState.save()),
|
481
|
+
);
|
482
|
+
const handleEnter = (): void => {
|
483
|
+
newElementState.setName('');
|
484
|
+
elementNameInputRef.current?.focus();
|
485
|
+
};
|
486
|
+
|
487
|
+
if (!newElementState.showModal) {
|
488
|
+
return null;
|
489
|
+
}
|
490
|
+
return (
|
491
|
+
<Dialog
|
492
|
+
open={newElementState.showModal}
|
493
|
+
onClose={closeModal}
|
494
|
+
TransitionProps={{
|
495
|
+
onEnter: handleEnter,
|
496
|
+
}}
|
497
|
+
classes={{ container: 'search-modal__container' }}
|
498
|
+
PaperProps={{ classes: { root: 'search-modal__inner-container' } }}
|
499
|
+
>
|
500
|
+
<form
|
501
|
+
data-testid={LEGEND_STUDIO_TEST_ID.NEW_ELEMENT_MODAL}
|
502
|
+
onSubmit={(event) => {
|
503
|
+
event.preventDefault();
|
504
|
+
save();
|
505
|
+
}}
|
506
|
+
className="modal modal--dark search-modal"
|
507
|
+
>
|
508
|
+
<div className="modal__title">
|
509
|
+
{`Create a New ${
|
510
|
+
getElementTypeLabel(editorStore, newElementState.type) ?? 'element'
|
511
|
+
}`}
|
512
|
+
</div>
|
513
|
+
<div>
|
514
|
+
{newElementState.showType && (
|
515
|
+
<CustomSelectorInput
|
516
|
+
options={typeOptions}
|
517
|
+
disabled={typeOptions.length === 1}
|
518
|
+
onChange={handleTypeChange}
|
519
|
+
value={selectedTypeOption}
|
520
|
+
isClearable={false}
|
521
|
+
darkMode={true}
|
522
|
+
/>
|
523
|
+
)}
|
524
|
+
<input
|
525
|
+
className="input--dark explorer__new-element-modal__name-input"
|
526
|
+
ref={elementNameInputRef}
|
527
|
+
spellCheck={false}
|
528
|
+
value={name}
|
529
|
+
onChange={handleNameChange}
|
530
|
+
placeholder={`Enter a name, use ${ELEMENT_PATH_DELIMITER} to create new package(s) for the ${
|
531
|
+
getElementTypeLabel(editorStore, newElementState.type) ??
|
532
|
+
'element'
|
533
|
+
}`}
|
534
|
+
/>
|
535
|
+
{renderNewElementDriver(newElementState.type, editorStore)}
|
536
|
+
</div>
|
537
|
+
<div className="search-modal__actions">
|
538
|
+
<button type="button" className="btn btn--dark" onClick={closeModal}>
|
539
|
+
Cancel
|
540
|
+
</button>
|
541
|
+
<button className="btn btn--dark" disabled={isDisabled}>
|
542
|
+
Create
|
543
|
+
</button>
|
544
|
+
</div>
|
545
|
+
</form>
|
546
|
+
</Dialog>
|
547
|
+
);
|
548
|
+
});
|
549
|
+
|
440
550
|
export const CreateNewElementModal = observer(() => {
|
441
551
|
const editorStore = useEditorStore();
|
442
552
|
const applicationStore = useApplicationStore();
|
@@ -54,7 +54,6 @@ import {
|
|
54
54
|
type GeneratorFn,
|
55
55
|
isNonNullable,
|
56
56
|
prettyCONSTName,
|
57
|
-
toTitleCase,
|
58
57
|
} from '@finos/legend-shared';
|
59
58
|
import { observer } from 'mobx-react-lite';
|
60
59
|
import { forwardRef, useEffect, useState } from 'react';
|
@@ -429,23 +428,28 @@ export const GlobalTestRunner = observer(
|
|
429
428
|
const editorStore = useEditorStore();
|
430
429
|
const globalTestRunnerState = props.globalTestRunnerState;
|
431
430
|
const isDispatchingAction = globalTestRunnerState.isDispatchingAction;
|
432
|
-
const testRunnerTabs = (Object.values(TEST_RUNNER_TABS) as string[])
|
433
|
-
.concat(
|
434
|
-
editorStore.pluginManager
|
435
|
-
.getApplicationPlugins()
|
436
|
-
.flatMap(
|
437
|
-
(plugin) => plugin.getExtraTestRunnerTabClassifiers?.() ?? [],
|
438
|
-
),
|
439
|
-
)
|
440
|
-
.map((e) => ({
|
441
|
-
value: e,
|
442
|
-
label: prettyCONSTName(e),
|
443
|
-
}));
|
444
431
|
|
445
432
|
const [selectedTab, setSelectedTab] = useState(
|
446
433
|
TEST_RUNNER_TABS.TEST_RUNNER.valueOf(),
|
447
434
|
);
|
448
435
|
|
436
|
+
const extractTestRunnerTabConfigurations = editorStore.pluginManager
|
437
|
+
.getApplicationPlugins()
|
438
|
+
.flatMap((plugin) => plugin.getExtraTestRunnerTabConfigurations?.() ?? [])
|
439
|
+
.filter((configuration) => configuration.renderer(editorStore));
|
440
|
+
|
441
|
+
const testRunnerTabs = (Object.values(TEST_RUNNER_TABS) as string[])
|
442
|
+
.map((e) => ({
|
443
|
+
value: e,
|
444
|
+
label: prettyCONSTName(e),
|
445
|
+
}))
|
446
|
+
.concat(
|
447
|
+
extractTestRunnerTabConfigurations.map((config) => ({
|
448
|
+
value: config.key,
|
449
|
+
label: config.title,
|
450
|
+
})),
|
451
|
+
);
|
452
|
+
|
449
453
|
const changeTab = (tab: string): void => {
|
450
454
|
setSelectedTab(tab);
|
451
455
|
};
|
@@ -544,7 +548,7 @@ export const GlobalTestRunner = observer(
|
|
544
548
|
['panel__header__tab--active']: tab.value === selectedTab,
|
545
549
|
})}
|
546
550
|
>
|
547
|
-
{
|
551
|
+
{tab.label}
|
548
552
|
</div>
|
549
553
|
))}
|
550
554
|
</div>
|
@@ -578,15 +582,9 @@ export const GlobalTestRunner = observer(
|
|
578
582
|
</div>
|
579
583
|
);
|
580
584
|
} else {
|
581
|
-
const
|
582
|
-
.
|
583
|
-
|
584
|
-
(plugin) => plugin.getExtraTestRunnerTabEditorRenderers?.() ?? [],
|
585
|
-
);
|
586
|
-
for (const editorRenderer of extraTestRunnerTabEditorRenderers) {
|
587
|
-
const editor = editorRenderer(selectedTab, editorStore);
|
588
|
-
if (editor) {
|
589
|
-
return editor;
|
585
|
+
for (const testRunnerTabConfiguration of extractTestRunnerTabConfigurations) {
|
586
|
+
if (testRunnerTabConfiguration.key === selectedTab) {
|
587
|
+
return testRunnerTabConfiguration.renderer(editorStore);
|
590
588
|
}
|
591
589
|
}
|
592
590
|
return (
|
@@ -133,6 +133,16 @@ export class Core_LegendStudioApplicationPlugin extends LegendStudioApplicationP
|
|
133
133
|
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CONNECTION_EDITOR,
|
134
134
|
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_BUILDER,
|
135
135
|
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SERVICE_EDITOR,
|
136
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATA_ELEMENT_EDITOR,
|
137
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MAPPING_EDITOR,
|
138
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.RUNTIME_EDITOR,
|
139
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.BINDING_EDITOR,
|
140
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SCHEMA_SET_EDITOR,
|
141
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SCHEMA_SET_MODEL_GENERATION,
|
142
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.EMBEDDED_DATA_RELATIONAL_EDITOR,
|
143
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.EMBEDDED_DATA_EXTERNAL_FORMAT_EDITOR,
|
144
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.EMBEDDED_DATA_DATA_ELEMENT_REFERENCE_EDITOR,
|
145
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.EMBEDDED_DATA_MODEL_STORE_EDITOR,
|
136
146
|
];
|
137
147
|
}
|
138
148
|
|
@@ -77,10 +77,11 @@ export type TestableMetadataGetter = (
|
|
77
77
|
editorStore: EditorStore,
|
78
78
|
) => TestableMetadata | undefined;
|
79
79
|
|
80
|
-
export type
|
81
|
-
|
82
|
-
|
83
|
-
) => React.ReactNode | undefined;
|
80
|
+
export type TestRunnerTabConfiguration = {
|
81
|
+
key: string;
|
82
|
+
title: string;
|
83
|
+
renderer: (editorStore: EditorStore) => React.ReactNode | undefined;
|
84
|
+
};
|
84
85
|
|
85
86
|
export abstract class LegendStudioApplicationPlugin extends LegendApplicationPlugin {
|
86
87
|
/**
|
@@ -126,14 +127,9 @@ export abstract class LegendStudioApplicationPlugin extends LegendApplicationPlu
|
|
126
127
|
getExtraTestableMetadata?(): TestableMetadataGetter[];
|
127
128
|
|
128
129
|
/**
|
129
|
-
* Get the list of the
|
130
|
-
*/
|
131
|
-
getExtraTestRunnerTabClassifiers?(): string[];
|
132
|
-
|
133
|
-
/**
|
134
|
-
* Get the list of renderers for the editor for a test runner tab.
|
130
|
+
* Get the list of configurations for the editor for a test runner tab.
|
135
131
|
*/
|
136
|
-
|
132
|
+
getExtraTestRunnerTabConfigurations?(): TestRunnerTabConfiguration[];
|
137
133
|
}
|
138
134
|
|
139
135
|
export type PureGrammarElementLabeler = (
|
@@ -929,25 +929,37 @@ export class EditorStore implements CommandRegistrar {
|
|
929
929
|
PACKAGEABLE_ELEMENT_TYPE.ASSOCIATION,
|
930
930
|
PACKAGEABLE_ELEMENT_TYPE.FUNCTION,
|
931
931
|
PACKAGEABLE_ELEMENT_TYPE.MEASURE,
|
932
|
-
PACKAGEABLE_ELEMENT_TYPE.MAPPING,
|
933
|
-
PACKAGEABLE_ELEMENT_TYPE.RUNTIME,
|
934
|
-
PACKAGEABLE_ELEMENT_TYPE.CONNECTION,
|
935
|
-
PACKAGEABLE_ELEMENT_TYPE.SERVICE,
|
936
|
-
PACKAGEABLE_ELEMENT_TYPE.GENERATION_SPECIFICATION,
|
937
|
-
PACKAGEABLE_ELEMENT_TYPE.FILE_GENERATION,
|
938
|
-
PACKAGEABLE_ELEMENT_TYPE.FLAT_DATA_STORE,
|
939
|
-
PACKAGEABLE_ELEMENT_TYPE.DATABASE,
|
940
|
-
PACKAGEABLE_ELEMENT_TYPE.DATA,
|
941
932
|
] as string[]
|
942
933
|
).concat(
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
934
|
+
(
|
935
|
+
[
|
936
|
+
PACKAGEABLE_ELEMENT_TYPE.MAPPING,
|
937
|
+
PACKAGEABLE_ELEMENT_TYPE.RUNTIME,
|
938
|
+
PACKAGEABLE_ELEMENT_TYPE.CONNECTION,
|
939
|
+
PACKAGEABLE_ELEMENT_TYPE.SERVICE,
|
940
|
+
PACKAGEABLE_ELEMENT_TYPE.GENERATION_SPECIFICATION,
|
941
|
+
PACKAGEABLE_ELEMENT_TYPE.FILE_GENERATION,
|
942
|
+
PACKAGEABLE_ELEMENT_TYPE.FLAT_DATA_STORE,
|
943
|
+
PACKAGEABLE_ELEMENT_TYPE.DATABASE,
|
944
|
+
PACKAGEABLE_ELEMENT_TYPE.DATA,
|
945
|
+
this.applicationStore.config.options
|
946
|
+
.TEMPORARY__enableLocalConnectionBuilder
|
947
|
+
? PACKAGEABLE_ELEMENT_TYPE.TEMPORARY__LOCAL_CONNECTION
|
948
|
+
: undefined,
|
949
|
+
] as (string | undefined)[]
|
950
|
+
)
|
951
|
+
.filter(isNonNullable)
|
952
|
+
.concat(
|
953
|
+
this.pluginManager
|
954
|
+
.getApplicationPlugins()
|
955
|
+
.flatMap(
|
956
|
+
(plugin) =>
|
957
|
+
(
|
958
|
+
plugin as DSL_LegendStudioApplicationPlugin_Extension
|
959
|
+
).getExtraSupportedElementTypes?.() ?? [],
|
960
|
+
),
|
961
|
+
)
|
962
|
+
.sort((a, b) => a.localeCompare(b)),
|
951
963
|
);
|
952
964
|
}
|
953
965
|
|
@@ -66,7 +66,6 @@ import {
|
|
66
66
|
PackageableElementExplicitReference,
|
67
67
|
RelationalDatabaseConnection,
|
68
68
|
DatabaseType,
|
69
|
-
StaticDatasourceSpecification,
|
70
69
|
DefaultH2AuthenticationStrategy,
|
71
70
|
ModelGenerationSpecification,
|
72
71
|
DataElement,
|
@@ -74,6 +73,13 @@ import {
|
|
74
73
|
Measure,
|
75
74
|
Multiplicity,
|
76
75
|
PrimitiveType,
|
76
|
+
LocalH2DatasourceSpecification,
|
77
|
+
SnowflakeDatasourceSpecification,
|
78
|
+
SnowflakePublicAuthenticationStrategy,
|
79
|
+
StoreConnections,
|
80
|
+
ConnectionPointer,
|
81
|
+
IdentifiedConnection,
|
82
|
+
generateIdentifiedConnectionId,
|
77
83
|
} from '@finos/legend-graph';
|
78
84
|
import type { DSL_Mapping_LegendStudioApplicationPlugin_Extension } from '../extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.js';
|
79
85
|
import {
|
@@ -302,6 +308,8 @@ export class NewFlatDataConnectionDriver extends NewConnectionValueDriver<FlatDa
|
|
302
308
|
}
|
303
309
|
}
|
304
310
|
|
311
|
+
const DEFAULT_H2_SQL =
|
312
|
+
'-- loads sample data for getting started. See https://github.com/pthom/northwind_psql for more info\n call loadNorthwindData()';
|
305
313
|
export class NewRelationalDatabaseConnectionDriver extends NewConnectionValueDriver<RelationalDatabaseConnection> {
|
306
314
|
constructor(editorStore: EditorStore) {
|
307
315
|
super(editorStore);
|
@@ -327,10 +335,12 @@ export class NewRelationalDatabaseConnectionDriver extends NewConnectionValueDri
|
|
327
335
|
const dbs = this.editorStore.graphManagerState.usableDatabases;
|
328
336
|
selectedStore = dbs.length ? (dbs[0] as Database) : stub_Database();
|
329
337
|
}
|
338
|
+
const spec = new LocalH2DatasourceSpecification();
|
339
|
+
spec.testDataSetupSqls = [DEFAULT_H2_SQL];
|
330
340
|
return new RelationalDatabaseConnection(
|
331
341
|
PackageableElementExplicitReference.create(selectedStore),
|
332
342
|
DatabaseType.H2,
|
333
|
-
|
343
|
+
spec,
|
334
344
|
new DefaultH2AuthenticationStrategy(),
|
335
345
|
);
|
336
346
|
}
|
@@ -440,7 +450,6 @@ export class NewPackageableConnectionDriver extends NewElementDriver<Packageable
|
|
440
450
|
this.store = store;
|
441
451
|
this.newConnectionValueDriver = newDriver;
|
442
452
|
}
|
443
|
-
return;
|
444
453
|
}
|
445
454
|
|
446
455
|
get isValid(): boolean {
|
@@ -643,7 +652,6 @@ export class NewElementState {
|
|
643
652
|
_package: observable,
|
644
653
|
name: observable,
|
645
654
|
newElementDriver: observable,
|
646
|
-
elementAndPackageName: computed,
|
647
655
|
selectedPackage: computed,
|
648
656
|
isValid: computed,
|
649
657
|
setShowModal: action,
|
@@ -662,14 +670,6 @@ export class NewElementState {
|
|
662
670
|
this.type = PACKAGEABLE_ELEMENT_TYPE.PACKAGE;
|
663
671
|
}
|
664
672
|
|
665
|
-
get elementAndPackageName(): [string, string] {
|
666
|
-
return resolvePackageAndElementName(
|
667
|
-
this.selectedPackage,
|
668
|
-
this._package === this.editorStore.graphManagerState.graph.root,
|
669
|
-
this.name,
|
670
|
-
);
|
671
|
-
}
|
672
|
-
|
673
673
|
get selectedPackage(): Package {
|
674
674
|
return this._package
|
675
675
|
? this._package
|
@@ -775,7 +775,11 @@ export class NewElementState {
|
|
775
775
|
|
776
776
|
*save(): GeneratorFn<void> {
|
777
777
|
if (this.name && this.isValid) {
|
778
|
-
const [packagePath, elementName] =
|
778
|
+
const [packagePath, elementName] = resolvePackageAndElementName(
|
779
|
+
this.selectedPackage,
|
780
|
+
this._package === this.editorStore.graphManagerState.graph.root,
|
781
|
+
this.name,
|
782
|
+
);
|
779
783
|
if (
|
780
784
|
this.editorStore.graphManagerState.graph.getNullablePackage(
|
781
785
|
packagePath,
|
@@ -786,17 +790,105 @@ export class NewElementState {
|
|
786
790
|
`Can't create elements for type other than 'package' in root package`,
|
787
791
|
);
|
788
792
|
} else {
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
793
|
+
if (
|
794
|
+
this.editorStore.applicationStore.config.options
|
795
|
+
.TEMPORARY__enableLocalConnectionBuilder &&
|
796
|
+
this.type === PACKAGEABLE_ELEMENT_TYPE.TEMPORARY__LOCAL_CONNECTION
|
797
|
+
) {
|
798
|
+
// NOTE: this is temporary until we have proper support for local connection
|
799
|
+
// For now, we aim to fulfill the PoC for SnowflakeApp use case and will generate
|
800
|
+
// everything: mapping, store, connection, runtime, etc.
|
801
|
+
const store = new Database(`${this.name}_Database`);
|
802
|
+
const mapping = new Mapping(`${this.name}_Mapping`);
|
803
|
+
// connection
|
804
|
+
const connection = new PackageableConnection(
|
805
|
+
`${this.name}_LocalConnection`,
|
806
|
+
);
|
807
|
+
const _suffix = `${packagePath.replaceAll(
|
808
|
+
ELEMENT_PATH_DELIMITER,
|
809
|
+
'-',
|
810
|
+
)}-${connection.name}`;
|
811
|
+
const datasourceSpecification = new SnowflakeDatasourceSpecification(
|
812
|
+
`legend-local-snowflake-accountName-${_suffix}`,
|
813
|
+
`legend-local-snowflake-region-${_suffix}`,
|
814
|
+
`legend-local-snowflake-warehouseName-${_suffix}`,
|
815
|
+
`legend-local-snowflake-databaseName-${_suffix}`,
|
816
|
+
);
|
817
|
+
datasourceSpecification.cloudType = `legend-local-snowflake-cloudType-${_suffix}`;
|
818
|
+
datasourceSpecification.role = `legend-local-snowflake-role-${_suffix}`;
|
819
|
+
const connectionValue = new RelationalDatabaseConnection(
|
820
|
+
PackageableElementExplicitReference.create(store),
|
821
|
+
DatabaseType.Snowflake,
|
822
|
+
datasourceSpecification,
|
823
|
+
new SnowflakePublicAuthenticationStrategy(
|
824
|
+
`legend-local-snowflake-privateKeyVaultReference-${_suffix}`,
|
825
|
+
`legend-local-snowflake-passphraseVaultReference-${_suffix}`,
|
826
|
+
`legend-local-snowflake-publicuserName-${_suffix}`,
|
827
|
+
),
|
828
|
+
);
|
829
|
+
connectionValue.localMode = true;
|
830
|
+
connection.connectionValue = connectionValue;
|
831
|
+
// runtime
|
832
|
+
const runtime = new PackageableRuntime(`${this.name}_Runtime`);
|
833
|
+
const engineRuntime = new EngineRuntime();
|
834
|
+
engineRuntime.mappings = [
|
835
|
+
PackageableElementExplicitReference.create(mapping),
|
836
|
+
];
|
837
|
+
const storeConnections = new StoreConnections(
|
838
|
+
PackageableElementExplicitReference.create(store),
|
839
|
+
);
|
840
|
+
storeConnections.storeConnections = [
|
841
|
+
new IdentifiedConnection(
|
842
|
+
generateIdentifiedConnectionId(engineRuntime),
|
843
|
+
new ConnectionPointer(
|
844
|
+
PackageableElementExplicitReference.create(connection),
|
845
|
+
),
|
846
|
+
),
|
847
|
+
];
|
848
|
+
engineRuntime.connections = [storeConnections];
|
849
|
+
runtime.runtimeValue = engineRuntime;
|
850
|
+
// add the elements
|
851
|
+
yield flowResult(
|
852
|
+
this.editorStore.graphEditorMode.addElement(
|
853
|
+
store,
|
854
|
+
packagePath,
|
855
|
+
false,
|
856
|
+
),
|
857
|
+
);
|
858
|
+
yield flowResult(
|
859
|
+
this.editorStore.graphEditorMode.addElement(
|
860
|
+
connection,
|
861
|
+
packagePath,
|
862
|
+
false,
|
863
|
+
),
|
864
|
+
);
|
865
|
+
yield flowResult(
|
866
|
+
this.editorStore.graphEditorMode.addElement(
|
867
|
+
mapping,
|
868
|
+
packagePath,
|
869
|
+
false,
|
870
|
+
),
|
871
|
+
);
|
872
|
+
yield flowResult(
|
873
|
+
this.editorStore.graphEditorMode.addElement(
|
874
|
+
runtime,
|
875
|
+
packagePath,
|
876
|
+
false,
|
877
|
+
),
|
878
|
+
);
|
879
|
+
} else {
|
880
|
+
const element = this.createElement(elementName);
|
881
|
+
yield flowResult(
|
882
|
+
this.editorStore.graphEditorMode.addElement(
|
883
|
+
element,
|
884
|
+
packagePath,
|
885
|
+
true,
|
886
|
+
),
|
887
|
+
);
|
797
888
|
|
798
|
-
|
799
|
-
|
889
|
+
// post creation handling
|
890
|
+
yield handlePostCreateAction(element, this.editorStore);
|
891
|
+
}
|
800
892
|
}
|
801
893
|
}
|
802
894
|
this.closeModal();
|
package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts
CHANGED
@@ -146,8 +146,8 @@ export class DatabaseBuilderState {
|
|
146
146
|
makeObservable<DatabaseBuilderState>(this, {
|
147
147
|
showModal: observable,
|
148
148
|
targetDatabasePath: observable,
|
149
|
-
isBuildingDatabase: observable,
|
150
149
|
databaseGrammarCode: observable,
|
150
|
+
isBuildingDatabase: observable,
|
151
151
|
isSavingDatabase: observable,
|
152
152
|
currentDatabase: computed,
|
153
153
|
setTargetDatabasePath: action,
|
@@ -219,7 +219,7 @@ export class DatabaseBuilderState {
|
|
219
219
|
treeData: DatabaseBuilderTreeData,
|
220
220
|
): DatabaseBuilderTreeNodeData[] | undefined {
|
221
221
|
return node.childrenIds
|
222
|
-
?.map((
|
222
|
+
?.map((childNode) => treeData.nodes.get(childNode))
|
223
223
|
.filter(isNonNullable);
|
224
224
|
}
|
225
225
|
|
@@ -245,7 +245,8 @@ export class DatabaseBuilderState {
|
|
245
245
|
}
|
246
246
|
}
|
247
247
|
}
|
248
|
-
|
248
|
+
|
249
|
+
// TODO: support toggling check for columns
|
249
250
|
this.setTreeData({ ...treeData });
|
250
251
|
}
|
251
252
|
|
@@ -279,6 +280,7 @@ export class DatabaseBuilderState {
|
|
279
280
|
schemaId,
|
280
281
|
schema,
|
281
282
|
);
|
283
|
+
nodes.set(schemaId, schemaNode);
|
282
284
|
|
283
285
|
schemaNode.setChecked(
|
284
286
|
Boolean(
|
@@ -287,7 +289,6 @@ export class DatabaseBuilderState {
|
|
287
289
|
),
|
288
290
|
),
|
289
291
|
);
|
290
|
-
nodes.set(schemaId, schemaNode);
|
291
292
|
});
|
292
293
|
const treeData = { rootIds, nodes, database };
|
293
294
|
this.setTreeData(treeData);
|
@@ -341,6 +342,8 @@ export class DatabaseBuilderState {
|
|
341
342
|
schema,
|
342
343
|
table,
|
343
344
|
);
|
345
|
+
treeData.nodes.set(tableId, tableNode);
|
346
|
+
addUniqueEntry(childrenIds, tableId);
|
344
347
|
|
345
348
|
if (this.currentDatabase) {
|
346
349
|
const matchingSchema = getNullableSchema(
|
@@ -357,9 +360,6 @@ export class DatabaseBuilderState {
|
|
357
360
|
} else {
|
358
361
|
tableNode.setChecked(false);
|
359
362
|
}
|
360
|
-
|
361
|
-
treeData.nodes.set(tableId, tableNode);
|
362
|
-
addUniqueEntry(childrenIds, tableId);
|
363
363
|
});
|
364
364
|
schemaNode.childrenIds = childrenIds;
|
365
365
|
this.setTreeData({ ...treeData });
|
@@ -605,6 +605,8 @@ export class DatabaseBuilderState {
|
|
605
605
|
} else {
|
606
606
|
currentDatabase = this.currentDatabase;
|
607
607
|
}
|
608
|
+
|
609
|
+
// remove undefined schemas
|
608
610
|
const schemas = Array.from(this.treeData.nodes.values())
|
609
611
|
.map((schemaNode) => {
|
610
612
|
if (schemaNode instanceof SchemaDatabaseBuilderTreeNodeData) {
|
@@ -613,11 +615,32 @@ export class DatabaseBuilderState {
|
|
613
615
|
return undefined;
|
614
616
|
})
|
615
617
|
.filter(isNonNullable);
|
616
|
-
|
618
|
+
currentDatabase.schemas = currentDatabase.schemas.filter((schema) => {
|
619
|
+
if (
|
620
|
+
schemas.find((item) => item.name === schema.name) &&
|
621
|
+
!database.schemas.find((s) => s.name === schema.name)
|
622
|
+
) {
|
623
|
+
return false;
|
624
|
+
}
|
625
|
+
return true;
|
626
|
+
});
|
627
|
+
|
628
|
+
// update existing schemas
|
629
|
+
database.schemas.forEach((schema) => {
|
630
|
+
(schema as Writable<Schema>)._OWNER = currentDatabase;
|
631
|
+
const currentSchemaIndex = currentDatabase.schemas.findIndex(
|
632
|
+
(item) => item.name === schema.name,
|
633
|
+
);
|
634
|
+
if (currentSchemaIndex !== -1) {
|
635
|
+
currentDatabase.schemas[currentSchemaIndex] = schema;
|
636
|
+
} else {
|
637
|
+
currentDatabase.schemas.push(schema);
|
638
|
+
}
|
639
|
+
});
|
640
|
+
|
617
641
|
this.editorStore.applicationStore.notificationService.notifySuccess(
|
618
|
-
`Database successfully '${isUpdating ? 'updated' : 'created'}
|
642
|
+
`Database successfully '${isUpdating ? 'updated' : 'created'}`,
|
619
643
|
);
|
620
|
-
this.fetchDatabaseMetadata();
|
621
644
|
if (isUpdating) {
|
622
645
|
yield flowResult(
|
623
646
|
this.editorStore
|
@@ -639,34 +662,4 @@ export class DatabaseBuilderState {
|
|
639
662
|
this.isSavingDatabase = false;
|
640
663
|
}
|
641
664
|
}
|
642
|
-
|
643
|
-
updateDatabase(
|
644
|
-
current: Database,
|
645
|
-
generatedDatabase: Database,
|
646
|
-
allSchemas: Schema[],
|
647
|
-
): void {
|
648
|
-
// remove undefined schemas
|
649
|
-
current.schemas = current.schemas.filter((schema) => {
|
650
|
-
if (
|
651
|
-
allSchemas.find((item) => item.name === schema.name) &&
|
652
|
-
!generatedDatabase.schemas.find((c) => c.name === schema.name)
|
653
|
-
) {
|
654
|
-
return false;
|
655
|
-
}
|
656
|
-
return true;
|
657
|
-
});
|
658
|
-
|
659
|
-
// update existing schemas
|
660
|
-
generatedDatabase.schemas.forEach((schema) => {
|
661
|
-
(schema as Writable<Schema>)._OWNER = current;
|
662
|
-
const currentSchemaIndex = current.schemas.findIndex(
|
663
|
-
(item) => item.name === schema.name,
|
664
|
-
);
|
665
|
-
if (currentSchemaIndex !== -1) {
|
666
|
-
current.schemas[currentSchemaIndex] = schema;
|
667
|
-
} else {
|
668
|
-
current.schemas.push(schema);
|
669
|
-
}
|
670
|
-
});
|
671
|
-
}
|
672
665
|
}
|
@@ -121,7 +121,6 @@ import {
|
|
121
121
|
setImpl_updateRootOnCreate,
|
122
122
|
setImpl_updateRootOnDelete,
|
123
123
|
} from '../../../../graph-modifier/DSL_Mapping_GraphModifierHelper.js';
|
124
|
-
import { BASIC_SET_IMPLEMENTATION_TYPE } from '../../../utils/ModelClassifierUtils.js';
|
125
124
|
import { rootRelationalSetImp_setMainTableAlias } from '../../../../graph-modifier/STO_Relational_GraphModifierHelper.js';
|
126
125
|
import { LambdaEditorState } from '@finos/legend-query-builder';
|
127
126
|
import type { MappingEditorTabState } from './MappingTabManagerState.js';
|
@@ -163,6 +162,11 @@ export enum MAPPING_ELEMENT_TYPE {
|
|
163
162
|
ASSOCIATION = 'ASSOCIATION',
|
164
163
|
}
|
165
164
|
|
165
|
+
export enum BASIC_SET_IMPLEMENTATION_TYPE {
|
166
|
+
OPERATION = 'operation',
|
167
|
+
INSTANCE = 'instance',
|
168
|
+
}
|
169
|
+
|
166
170
|
export type MappingElement =
|
167
171
|
| EnumerationMapping
|
168
172
|
| SetImplementation
|