@finos/legend-application-studio 28.1.2 → 28.1.3
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 +1 -0
- package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js +1 -0
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
- package/lib/__lib__/LegendStudioEvent.d.ts +1 -0
- package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioEvent.js +1 -0
- package/lib/__lib__/LegendStudioEvent.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +16 -2
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts +23 -0
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts.map +1 -0
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js +45 -0
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js.map +1 -0
- package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
- package/lib/components/editor/side-bar/Explorer.js +10 -10
- 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/editor/ExplorerTreeState.d.ts +6 -3
- package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
- package/lib/stores/editor/ExplorerTreeState.js +13 -31
- package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +4 -0
- 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 +42 -7
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +0 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts +37 -0
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js +111 -0
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js.map +1 -0
- package/package.json +1 -1
- package/src/__lib__/LegendStudioApplicationNavigationContext.ts +1 -0
- package/src/__lib__/LegendStudioEvent.ts +1 -0
- package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +29 -5
- package/src/components/editor/editor-group/connection-editor/DatabaseModelBuilder.tsx +158 -0
- package/src/components/editor/side-bar/Explorer.tsx +24 -20
- package/src/stores/editor/ExplorerTreeState.ts +19 -50
- package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +80 -12
- package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts +1 -2
- package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.ts +156 -0
- package/tsconfig.json +2 -0
@@ -33,6 +33,7 @@ import {
|
|
33
33
|
BlankPanelContent,
|
34
34
|
PanelHeader,
|
35
35
|
Panel,
|
36
|
+
InputWithInlineValidation,
|
36
37
|
} from '@finos/legend-art';
|
37
38
|
import { useEffect } from 'react';
|
38
39
|
import { noop } from '@finos/legend-shared';
|
@@ -56,10 +57,24 @@ export const DatabaseBuilderWizard = observer(
|
|
56
57
|
}) => {
|
57
58
|
const { databaseBuilderState, isReadOnly } = props;
|
58
59
|
const schemaExplorerState = databaseBuilderState.schemaExplorerState;
|
60
|
+
const isCreatingNewDatabase = schemaExplorerState.isCreatingNewDatabase;
|
61
|
+
const elementAlreadyExistsMessage =
|
62
|
+
isCreatingNewDatabase &&
|
63
|
+
databaseBuilderState.editorStore.graphManagerState.graph.allElements
|
64
|
+
.map((s) => s.path)
|
65
|
+
.includes(schemaExplorerState.targetDatabasePath)
|
66
|
+
? 'Element with same path already exists'
|
67
|
+
: undefined;
|
68
|
+
|
59
69
|
const applicationStore = useApplicationStore();
|
60
70
|
const preview = applicationStore.guardUnhandledError(() =>
|
61
71
|
flowResult(databaseBuilderState.previewDatabaseModel()),
|
62
72
|
);
|
73
|
+
const onTargetPathChange: React.ChangeEventHandler<HTMLInputElement> = (
|
74
|
+
event,
|
75
|
+
) => {
|
76
|
+
schemaExplorerState.setTargetDatabasePath(event.target.value);
|
77
|
+
};
|
63
78
|
const updateDatabase = applicationStore.guardUnhandledError(() =>
|
64
79
|
flowResult(databaseBuilderState.updateDatabase()),
|
65
80
|
);
|
@@ -131,18 +146,23 @@ export const DatabaseBuilderWizard = observer(
|
|
131
146
|
<ResizablePanel>
|
132
147
|
<Panel className="database-builder__model">
|
133
148
|
<PanelHeader title="database model" />
|
134
|
-
|
135
149
|
<PanelContent>
|
136
150
|
<div className="database-builder__modeller">
|
137
151
|
<div className="panel__content__form__section database-builder__modeller__path">
|
138
152
|
<div className="panel__content__form__section__header__label">
|
139
153
|
Target Database Path
|
140
154
|
</div>
|
141
|
-
<
|
155
|
+
<InputWithInlineValidation
|
142
156
|
className="panel__content__form__section__input"
|
143
157
|
spellCheck={false}
|
144
|
-
|
145
|
-
|
158
|
+
onChange={onTargetPathChange}
|
159
|
+
disabled={!isCreatingNewDatabase}
|
160
|
+
value={
|
161
|
+
isCreatingNewDatabase
|
162
|
+
? schemaExplorerState.targetDatabasePath
|
163
|
+
: schemaExplorerState.database.path
|
164
|
+
}
|
165
|
+
error={elementAlreadyExistsMessage}
|
146
166
|
/>
|
147
167
|
</div>
|
148
168
|
<div className="database-builder__modeller__preview">
|
@@ -178,7 +198,11 @@ export const DatabaseBuilderWizard = observer(
|
|
178
198
|
</ModalFooterButton>
|
179
199
|
<ModalFooterButton
|
180
200
|
className="database-builder__action--btn"
|
181
|
-
disabled={
|
201
|
+
disabled={
|
202
|
+
isReadOnly ||
|
203
|
+
isExecutingAction ||
|
204
|
+
Boolean(elementAlreadyExistsMessage)
|
205
|
+
}
|
182
206
|
onClick={updateDatabase}
|
183
207
|
>
|
184
208
|
Update Database
|
@@ -0,0 +1,158 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
import { observer } from 'mobx-react-lite';
|
18
|
+
import type { DatabaseModelBuilderState } from '../../../../stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js';
|
19
|
+
import {
|
20
|
+
BlankPanelContent,
|
21
|
+
Dialog,
|
22
|
+
Modal,
|
23
|
+
ModalBody,
|
24
|
+
ModalFooter,
|
25
|
+
ModalFooterButton,
|
26
|
+
ModalHeader,
|
27
|
+
ModalHeaderActions,
|
28
|
+
ModalTitle,
|
29
|
+
Panel,
|
30
|
+
PanelContent,
|
31
|
+
PanelHeader,
|
32
|
+
PanelLoadingIndicator,
|
33
|
+
ResizablePanel,
|
34
|
+
ResizablePanelGroup,
|
35
|
+
TimesIcon,
|
36
|
+
} from '@finos/legend-art';
|
37
|
+
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
|
38
|
+
import {
|
39
|
+
useApplicationStore,
|
40
|
+
useConditionedApplicationNavigationContext,
|
41
|
+
} from '@finos/legend-application';
|
42
|
+
import { flowResult } from 'mobx';
|
43
|
+
import { useEffect } from 'react';
|
44
|
+
import {
|
45
|
+
CODE_EDITOR_LANGUAGE,
|
46
|
+
CodeEditor,
|
47
|
+
} from '@finos/legend-lego/code-editor';
|
48
|
+
import { noop } from '@finos/legend-shared';
|
49
|
+
|
50
|
+
export const DatabaseModelBuilder = observer(
|
51
|
+
(props: {
|
52
|
+
databaseModelBuilderState: DatabaseModelBuilderState;
|
53
|
+
isReadOnly: boolean;
|
54
|
+
}) => {
|
55
|
+
const { databaseModelBuilderState, isReadOnly } = props;
|
56
|
+
|
57
|
+
const applicationStore = useApplicationStore();
|
58
|
+
const preview = applicationStore.guardUnhandledError(() =>
|
59
|
+
flowResult(databaseModelBuilderState.previewDatabaseModels()),
|
60
|
+
);
|
61
|
+
const saveModels = applicationStore.guardUnhandledError(() =>
|
62
|
+
flowResult(databaseModelBuilderState.saveModels()),
|
63
|
+
);
|
64
|
+
const closeModal = (): void => {
|
65
|
+
databaseModelBuilderState.close();
|
66
|
+
};
|
67
|
+
|
68
|
+
const isExecutingAction =
|
69
|
+
databaseModelBuilderState.generatingModelState.isInProgress ||
|
70
|
+
databaseModelBuilderState.saveModelState.isInProgress;
|
71
|
+
|
72
|
+
useEffect(() => {
|
73
|
+
flowResult(databaseModelBuilderState.previewDatabaseModels()).catch(
|
74
|
+
applicationStore.alertUnhandledError,
|
75
|
+
);
|
76
|
+
}, [applicationStore, databaseModelBuilderState]);
|
77
|
+
|
78
|
+
useConditionedApplicationNavigationContext(
|
79
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_MODEL_BUILDER,
|
80
|
+
databaseModelBuilderState.showModal,
|
81
|
+
);
|
82
|
+
|
83
|
+
return (
|
84
|
+
<Dialog
|
85
|
+
open={databaseModelBuilderState.showModal}
|
86
|
+
classes={{ container: 'search-modal__container' }}
|
87
|
+
onClose={noop}
|
88
|
+
PaperProps={{
|
89
|
+
classes: {
|
90
|
+
root: 'search-modal__inner-container database-builder__container',
|
91
|
+
},
|
92
|
+
}}
|
93
|
+
>
|
94
|
+
<Modal darkMode={true} className="database-builder">
|
95
|
+
<ModalHeader>
|
96
|
+
<ModalTitle title="Database Model Builder" />
|
97
|
+
<ModalHeaderActions>
|
98
|
+
<button
|
99
|
+
className="modal__header__action"
|
100
|
+
tabIndex={-1}
|
101
|
+
onClick={closeModal}
|
102
|
+
>
|
103
|
+
<TimesIcon />
|
104
|
+
</button>
|
105
|
+
</ModalHeaderActions>
|
106
|
+
</ModalHeader>
|
107
|
+
<ModalBody className="database-builder__content">
|
108
|
+
<PanelLoadingIndicator isLoading={isExecutingAction} />
|
109
|
+
<ResizablePanelGroup orientation="vertical">
|
110
|
+
<ResizablePanel>
|
111
|
+
<Panel className="database-builder__model">
|
112
|
+
<PanelHeader title="database model" />
|
113
|
+
<PanelContent>
|
114
|
+
<div className="database-builder__modeller">
|
115
|
+
<div className="database-builder__modeller__preview">
|
116
|
+
{databaseModelBuilderState.generatedGrammarCode && (
|
117
|
+
<CodeEditor
|
118
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
119
|
+
inputValue={
|
120
|
+
databaseModelBuilderState.generatedGrammarCode
|
121
|
+
}
|
122
|
+
isReadOnly={true}
|
123
|
+
/>
|
124
|
+
)}
|
125
|
+
{!databaseModelBuilderState.generatedGrammarCode && (
|
126
|
+
<BlankPanelContent>
|
127
|
+
No model preview
|
128
|
+
</BlankPanelContent>
|
129
|
+
)}
|
130
|
+
</div>
|
131
|
+
</div>
|
132
|
+
</PanelContent>
|
133
|
+
</Panel>
|
134
|
+
</ResizablePanel>
|
135
|
+
</ResizablePanelGroup>
|
136
|
+
</ModalBody>
|
137
|
+
<ModalFooter>
|
138
|
+
<ModalFooterButton
|
139
|
+
className="database-builder__action--btn"
|
140
|
+
disabled={isReadOnly || isExecutingAction}
|
141
|
+
onClick={preview}
|
142
|
+
title="Preview models..."
|
143
|
+
>
|
144
|
+
Preview
|
145
|
+
</ModalFooterButton>
|
146
|
+
<ModalFooterButton
|
147
|
+
className="database-builder__action--btn"
|
148
|
+
disabled={isReadOnly || isExecutingAction}
|
149
|
+
onClick={saveModels}
|
150
|
+
>
|
151
|
+
Save Models
|
152
|
+
</ModalFooterButton>
|
153
|
+
</ModalFooter>
|
154
|
+
</Modal>
|
155
|
+
</Dialog>
|
156
|
+
);
|
157
|
+
},
|
158
|
+
);
|
@@ -140,6 +140,7 @@ import {
|
|
140
140
|
} from '@finos/legend-lego/code-editor';
|
141
141
|
import { DatabaseBuilderWizard } from '../editor-group/connection-editor/DatabaseBuilderWizard.js';
|
142
142
|
import { FunctionEditorState } from '../../../stores/editor/editor-state/element-editor-state/FunctionEditorState.js';
|
143
|
+
import { DatabaseModelBuilder } from '../editor-group/connection-editor/DatabaseModelBuilder.js';
|
143
144
|
|
144
145
|
const ElementRenamer = observer(() => {
|
145
146
|
const editorStore = useEditorStore();
|
@@ -457,8 +458,9 @@ const isRelationalDatabaseConnection = (
|
|
457
458
|
val instanceof PackageableConnection &&
|
458
459
|
val.connectionValue instanceof RelationalDatabaseConnection;
|
459
460
|
|
460
|
-
const isRelationalDatabase = (
|
461
|
-
val
|
461
|
+
const isRelationalDatabase = (
|
462
|
+
val: PackageableElement | undefined,
|
463
|
+
): Database | undefined => (val instanceof Database ? val : undefined);
|
462
464
|
|
463
465
|
const ExplorerContextMenu = observer(
|
464
466
|
forwardRef<
|
@@ -533,27 +535,22 @@ const ExplorerContextMenu = observer(
|
|
533
535
|
);
|
534
536
|
const generateModelsFromDatabaseSpecification =
|
535
537
|
editorStore.applicationStore.guardUnhandledError(async () => {
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
);
|
540
|
-
const graph = editorStore.graphManagerState.graph;
|
541
|
-
if (graph.getDatabase(databasePath).joins.length === 0) {
|
538
|
+
const database = isRelationalDatabase(node?.packageableElement);
|
539
|
+
if (database) {
|
540
|
+
if (database.joins.length === 0) {
|
542
541
|
applicationStore.alertService.setActionAlertInfo({
|
543
542
|
message:
|
544
|
-
'You are attempting to
|
543
|
+
'You are attempting to build models but have defined no joins. Are you sure you wish to proceed?',
|
545
544
|
type: ActionAlertType.CAUTION,
|
546
545
|
actions: [
|
547
546
|
{
|
548
547
|
label: 'Proceed',
|
549
548
|
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
550
549
|
handler: () => {
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
),
|
556
|
-
).catch(applicationStore.alertUnhandledError);
|
550
|
+
editorStore.explorerTreeState.buildDatabaseModels(
|
551
|
+
database,
|
552
|
+
editorStore.isInViewerMode,
|
553
|
+
);
|
557
554
|
},
|
558
555
|
},
|
559
556
|
{
|
@@ -564,9 +561,9 @@ const ExplorerContextMenu = observer(
|
|
564
561
|
],
|
565
562
|
});
|
566
563
|
} else {
|
567
|
-
editorStore.explorerTreeState.
|
568
|
-
|
569
|
-
|
564
|
+
editorStore.explorerTreeState.buildDatabaseModels(
|
565
|
+
database,
|
566
|
+
editorStore.isInViewerMode,
|
570
567
|
);
|
571
568
|
}
|
572
569
|
}
|
@@ -863,7 +860,7 @@ const ExplorerContextMenu = observer(
|
|
863
860
|
{isRelationalDatabase(node.packageableElement) && (
|
864
861
|
<>
|
865
862
|
<MenuContentItem onClick={generateModelsFromDatabaseSpecification}>
|
866
|
-
|
863
|
+
Build Models
|
867
864
|
</MenuContentItem>
|
868
865
|
<MenuContentDivider />
|
869
866
|
</>
|
@@ -1157,7 +1154,6 @@ const ExplorerTrees = observer(() => {
|
|
1157
1154
|
getTreeChildNodes(editorStore, node, dependencyTreeData, true);
|
1158
1155
|
const showPackageTrees =
|
1159
1156
|
treeData.nodes.size || graph.dependencyManager.hasDependencies;
|
1160
|
-
|
1161
1157
|
return (
|
1162
1158
|
<ContextMenu
|
1163
1159
|
className="explorer__content"
|
@@ -1191,6 +1187,14 @@ const ExplorerTrees = observer(() => {
|
|
1191
1187
|
isReadOnly={false}
|
1192
1188
|
/>
|
1193
1189
|
)}
|
1190
|
+
{editorStore.explorerTreeState.databaseModelBuilderState && (
|
1191
|
+
<DatabaseModelBuilder
|
1192
|
+
databaseModelBuilderState={
|
1193
|
+
editorStore.explorerTreeState.databaseModelBuilderState
|
1194
|
+
}
|
1195
|
+
isReadOnly={false}
|
1196
|
+
/>
|
1197
|
+
)}
|
1194
1198
|
{editorStore.projectConfigurationEditorState
|
1195
1199
|
.projectConfiguration && <ProjectConfig />}
|
1196
1200
|
{/* SYSTEM TREE */}
|
@@ -14,7 +14,7 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import { action, observable, makeObservable
|
17
|
+
import { action, observable, makeObservable } from 'mobx';
|
18
18
|
import type { EditorStore } from './EditorStore.js';
|
19
19
|
import {
|
20
20
|
LogEvent,
|
@@ -23,8 +23,6 @@ import {
|
|
23
23
|
UnsupportedOperationError,
|
24
24
|
guaranteeNonNullable,
|
25
25
|
ActionState,
|
26
|
-
type GeneratorFn,
|
27
|
-
assertErrorThrown,
|
28
26
|
} from '@finos/legend-shared';
|
29
27
|
import {
|
30
28
|
getDependenciesPackableElementTreeData,
|
@@ -51,12 +49,11 @@ import {
|
|
51
49
|
isDependencyElement,
|
52
50
|
type Class,
|
53
51
|
type RelationalDatabaseConnection,
|
54
|
-
type
|
52
|
+
type Database,
|
55
53
|
} from '@finos/legend-graph';
|
56
54
|
import { APPLICATION_EVENT } from '@finos/legend-application';
|
57
55
|
import { DatabaseBuilderWizardState } from './editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js';
|
58
|
-
import
|
59
|
-
import { EntityChangeType, type EntityChange } from '@finos/legend-server-sdlc';
|
56
|
+
import { DatabaseModelBuilderState } from './editor-state/element-editor-state/connection/DatabaseModelBuilderState.js';
|
60
57
|
|
61
58
|
export enum ExplorerTreeRootPackageLabel {
|
62
59
|
FILE_GENERATION = 'generated-files',
|
@@ -81,6 +78,7 @@ export class ExplorerTreeState {
|
|
81
78
|
elementToRename?: PackageableElement | undefined;
|
82
79
|
classToGenerateSampleData?: Class | undefined;
|
83
80
|
databaseBuilderState: DatabaseBuilderWizardState | undefined;
|
81
|
+
databaseModelBuilderState: DatabaseModelBuilderState | undefined;
|
84
82
|
|
85
83
|
constructor(editorStore: EditorStore) {
|
86
84
|
makeObservable(this, {
|
@@ -94,6 +92,7 @@ export class ExplorerTreeState {
|
|
94
92
|
elementToRename: observable,
|
95
93
|
classToGenerateSampleData: observable,
|
96
94
|
databaseBuilderState: observable,
|
95
|
+
databaseModelBuilderState: observable,
|
97
96
|
setTreeData: action,
|
98
97
|
setGenerationTreeData: action,
|
99
98
|
setSystemTreeData: action,
|
@@ -106,13 +105,13 @@ export class ExplorerTreeState {
|
|
106
105
|
build: action,
|
107
106
|
buildImmutableModelTrees: action,
|
108
107
|
buildTreeInTextMode: action,
|
108
|
+
buildDatabaseModels: action,
|
109
109
|
openExplorerTreeNodes: action,
|
110
110
|
reprocess: action,
|
111
111
|
buildDatabase: action,
|
112
112
|
setDatabaseBuilderState: action,
|
113
113
|
onTreeNodeSelect: action,
|
114
114
|
openNode: action,
|
115
|
-
generateModelsFromDatabaseSpecification: flow,
|
116
115
|
});
|
117
116
|
|
118
117
|
this.editorStore = editorStore;
|
@@ -194,49 +193,19 @@ export class ExplorerTreeState {
|
|
194
193
|
dbBuilderState.setShowModal(true);
|
195
194
|
this.setDatabaseBuilderState(dbBuilderState);
|
196
195
|
}
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
let entityChangeType: EntityChangeType;
|
211
|
-
if (graph.getNullableElement(entity.path) === undefined) {
|
212
|
-
entityChangeType = EntityChangeType.CREATE;
|
213
|
-
} else {
|
214
|
-
entityChangeType = EntityChangeType.MODIFY;
|
215
|
-
}
|
216
|
-
newEntities.push({
|
217
|
-
type: entityChangeType,
|
218
|
-
entityPath: entity.path,
|
219
|
-
content: entity.content,
|
220
|
-
});
|
221
|
-
}
|
222
|
-
yield flowResult(
|
223
|
-
this.editorStore.graphState.loadEntityChangesToGraph(
|
224
|
-
newEntities,
|
225
|
-
undefined,
|
226
|
-
),
|
227
|
-
);
|
228
|
-
this.editorStore.applicationStore.notificationService.notifySuccess(
|
229
|
-
'Generated models successfully!',
|
230
|
-
);
|
231
|
-
} catch (error) {
|
232
|
-
assertErrorThrown(error);
|
233
|
-
this.editorStore.applicationStore.logService.error(
|
234
|
-
LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERATION_FAILURE),
|
235
|
-
error,
|
236
|
-
);
|
237
|
-
this.editorStore.applicationStore.notificationService.notifyError(error);
|
238
|
-
throw error;
|
239
|
-
}
|
196
|
+
setDatabaseModelBuilderState(
|
197
|
+
val: DatabaseModelBuilderState | undefined,
|
198
|
+
): void {
|
199
|
+
this.databaseModelBuilderState = val;
|
200
|
+
}
|
201
|
+
buildDatabaseModels(val: Database, isReadOnly: boolean): void {
|
202
|
+
const dbBuilderState = new DatabaseModelBuilderState(
|
203
|
+
this.editorStore,
|
204
|
+
val,
|
205
|
+
isReadOnly,
|
206
|
+
);
|
207
|
+
dbBuilderState.setShowModal(true);
|
208
|
+
this.setDatabaseModelBuilderState(dbBuilderState);
|
240
209
|
}
|
241
210
|
|
242
211
|
setSelectedNode(node: PackageTreeNodeData | undefined): void {
|
package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts
CHANGED
@@ -28,8 +28,17 @@ import {
|
|
28
28
|
ActionState,
|
29
29
|
getNonNullableEntry,
|
30
30
|
guaranteeType,
|
31
|
+
assertNonEmptyString,
|
32
|
+
assertTrue,
|
31
33
|
} from '@finos/legend-shared';
|
32
|
-
import {
|
34
|
+
import {
|
35
|
+
observable,
|
36
|
+
action,
|
37
|
+
makeObservable,
|
38
|
+
flow,
|
39
|
+
flowResult,
|
40
|
+
computed,
|
41
|
+
} from 'mobx';
|
33
42
|
import { LEGEND_STUDIO_APP_EVENT } from '../../../../../__lib__/LegendStudioEvent.js';
|
34
43
|
import type { EditorStore } from '../../../EditorStore.js';
|
35
44
|
import {
|
@@ -45,8 +54,12 @@ import {
|
|
45
54
|
getSchema,
|
46
55
|
getNullableSchema,
|
47
56
|
getNullableTable,
|
57
|
+
isStubbed_PackageableElement,
|
58
|
+
isValidFullPath,
|
59
|
+
PackageableElementExplicitReference,
|
48
60
|
} from '@finos/legend-graph';
|
49
61
|
import { GraphEditFormModeState } from '../../../GraphEditFormModeState.js';
|
62
|
+
import { connection_setStore } from '../../../../graph-modifier/DSL_Mapping_GraphModifierHelper.js';
|
50
63
|
|
51
64
|
export abstract class DatabaseSchemaExplorerTreeNodeData
|
52
65
|
implements TreeNodeData
|
@@ -114,10 +127,13 @@ export interface DatabaseExplorerTreeData
|
|
114
127
|
database: Database;
|
115
128
|
}
|
116
129
|
|
130
|
+
const DEFAULT_DATABASE_PATH = 'store::MyDatabase';
|
131
|
+
|
117
132
|
export class DatabaseSchemaExplorerState {
|
118
133
|
readonly editorStore: EditorStore;
|
119
134
|
readonly connection: RelationalDatabaseConnection;
|
120
135
|
readonly database: Database;
|
136
|
+
targetDatabasePath: string;
|
121
137
|
|
122
138
|
isGeneratingDatabase = false;
|
123
139
|
isUpdatingDatabase = false;
|
@@ -131,7 +147,11 @@ export class DatabaseSchemaExplorerState {
|
|
131
147
|
isGeneratingDatabase: observable,
|
132
148
|
isUpdatingDatabase: observable,
|
133
149
|
treeData: observable,
|
150
|
+
targetDatabasePath: observable,
|
151
|
+
isCreatingNewDatabase: computed,
|
152
|
+
resolveDatabasePackageAndName: computed,
|
134
153
|
setTreeData: action,
|
154
|
+
setTargetDatabasePath: action,
|
135
155
|
onNodeSelect: flow,
|
136
156
|
fetchDatabaseMetadata: flow,
|
137
157
|
fetchSchemaMetadata: flow,
|
@@ -143,6 +163,33 @@ export class DatabaseSchemaExplorerState {
|
|
143
163
|
this.connection = connection;
|
144
164
|
this.database = guaranteeType(connection.store.value, Database);
|
145
165
|
this.editorStore = editorStore;
|
166
|
+
this.targetDatabasePath = DEFAULT_DATABASE_PATH;
|
167
|
+
}
|
168
|
+
|
169
|
+
get isCreatingNewDatabase(): boolean {
|
170
|
+
return isStubbed_PackageableElement(this.connection.store.value);
|
171
|
+
}
|
172
|
+
|
173
|
+
get resolveDatabasePackageAndName(): [string, string] {
|
174
|
+
if (!this.isCreatingNewDatabase) {
|
175
|
+
return [
|
176
|
+
guaranteeNonNullable(this.database.package).path,
|
177
|
+
this.database.name,
|
178
|
+
];
|
179
|
+
}
|
180
|
+
assertNonEmptyString(this.targetDatabasePath, 'Must specify database path');
|
181
|
+
assertTrue(
|
182
|
+
isValidFullPath(this.targetDatabasePath),
|
183
|
+
'Invalid database path',
|
184
|
+
);
|
185
|
+
return resolvePackagePathAndElementName(
|
186
|
+
this.targetDatabasePath,
|
187
|
+
this.targetDatabasePath,
|
188
|
+
);
|
189
|
+
}
|
190
|
+
|
191
|
+
setTargetDatabasePath(val: string): void {
|
192
|
+
this.targetDatabasePath = val;
|
146
193
|
}
|
147
194
|
|
148
195
|
setTreeData(builderTreeData?: DatabaseExplorerTreeData): void {
|
@@ -208,9 +255,10 @@ export class DatabaseSchemaExplorerState {
|
|
208
255
|
try {
|
209
256
|
this.isGeneratingDatabase = true;
|
210
257
|
const databaseBuilderInput = new DatabaseBuilderInput(this.connection);
|
258
|
+
const [packagePath, name] = this.resolveDatabasePackageAndName;
|
211
259
|
databaseBuilderInput.targetDatabase = new TargetDatabase(
|
212
|
-
|
213
|
-
|
260
|
+
packagePath,
|
261
|
+
name,
|
214
262
|
);
|
215
263
|
databaseBuilderInput.config.maxTables = undefined;
|
216
264
|
databaseBuilderInput.config.enrichTables = false;
|
@@ -266,9 +314,10 @@ export class DatabaseSchemaExplorerState {
|
|
266
314
|
|
267
315
|
const schema = schemaNode.schema;
|
268
316
|
const databaseBuilderInput = new DatabaseBuilderInput(this.connection);
|
317
|
+
const [packagePath, name] = this.resolveDatabasePackageAndName;
|
269
318
|
databaseBuilderInput.targetDatabase = new TargetDatabase(
|
270
|
-
|
271
|
-
|
319
|
+
packagePath,
|
320
|
+
name,
|
272
321
|
);
|
273
322
|
databaseBuilderInput.config.maxTables = undefined;
|
274
323
|
databaseBuilderInput.config.enrichTables = true;
|
@@ -328,9 +377,7 @@ export class DatabaseSchemaExplorerState {
|
|
328
377
|
this.isGeneratingDatabase = true;
|
329
378
|
|
330
379
|
const databaseBuilderInput = new DatabaseBuilderInput(this.connection);
|
331
|
-
const [packagePath, name] =
|
332
|
-
this.database.path,
|
333
|
-
);
|
380
|
+
const [packagePath, name] = this.resolveDatabasePackageAndName;
|
334
381
|
databaseBuilderInput.targetDatabase = new TargetDatabase(
|
335
382
|
packagePath,
|
336
383
|
name,
|
@@ -414,9 +461,10 @@ export class DatabaseSchemaExplorerState {
|
|
414
461
|
|
415
462
|
const treeData = guaranteeNonNullable(this.treeData);
|
416
463
|
const databaseBuilderInput = new DatabaseBuilderInput(this.connection);
|
464
|
+
const [packagePath, name] = this.resolveDatabasePackageAndName;
|
417
465
|
databaseBuilderInput.targetDatabase = new TargetDatabase(
|
418
|
-
|
419
|
-
|
466
|
+
packagePath,
|
467
|
+
name,
|
420
468
|
);
|
421
469
|
const config = databaseBuilderInput.config;
|
422
470
|
config.maxTables = undefined;
|
@@ -472,7 +520,11 @@ export class DatabaseSchemaExplorerState {
|
|
472
520
|
|
473
521
|
try {
|
474
522
|
this.isUpdatingDatabase = true;
|
475
|
-
|
523
|
+
const createDatabase =
|
524
|
+
this.isCreatingNewDatabase &&
|
525
|
+
!this.editorStore.graphManagerState.graph.databases.includes(
|
526
|
+
this.database,
|
527
|
+
);
|
476
528
|
const graph = this.editorStore.graphManagerState.createNewGraph();
|
477
529
|
(yield this.editorStore.graphManagerState.graphManager.buildGraph(
|
478
530
|
graph,
|
@@ -516,7 +568,23 @@ export class DatabaseSchemaExplorerState {
|
|
516
568
|
this.database.schemas.push(schema);
|
517
569
|
}
|
518
570
|
});
|
519
|
-
|
571
|
+
if (createDatabase) {
|
572
|
+
connection_setStore(
|
573
|
+
this.connection,
|
574
|
+
PackageableElementExplicitReference.create(database),
|
575
|
+
);
|
576
|
+
const packagePath = guaranteeNonNullable(
|
577
|
+
database.package?.name,
|
578
|
+
'Database package is missing',
|
579
|
+
);
|
580
|
+
yield flowResult(
|
581
|
+
this.editorStore.graphEditorMode.addElement(
|
582
|
+
database,
|
583
|
+
packagePath,
|
584
|
+
false,
|
585
|
+
),
|
586
|
+
);
|
587
|
+
}
|
520
588
|
this.editorStore.applicationStore.notificationService.notifySuccess(
|
521
589
|
`Database successfully updated`,
|
522
590
|
);
|
package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts
CHANGED
@@ -23,8 +23,8 @@ import {
|
|
23
23
|
import { observable, action, makeObservable, flow, flowResult } from 'mobx';
|
24
24
|
import { LEGEND_STUDIO_APP_EVENT } from '../../../../../__lib__/LegendStudioEvent.js';
|
25
25
|
import type { EditorStore } from '../../../EditorStore.js';
|
26
|
-
import { type RelationalDatabaseConnection } from '@finos/legend-graph';
|
27
26
|
import { DatabaseSchemaExplorerState } from './DatabaseBuilderState.js';
|
27
|
+
import type { RelationalDatabaseConnection } from '@finos/legend-graph';
|
28
28
|
|
29
29
|
export class DatabaseBuilderWizardState {
|
30
30
|
readonly editorStore: EditorStore;
|
@@ -70,7 +70,6 @@ export class DatabaseBuilderWizardState {
|
|
70
70
|
if (!this.schemaExplorerState.treeData) {
|
71
71
|
return;
|
72
72
|
}
|
73
|
-
|
74
73
|
try {
|
75
74
|
this.setDatabaseGrammarCode(
|
76
75
|
(yield this.editorStore.graphManagerState.graphManager.entitiesToPureCode(
|