@finos/legend-application-studio 28.9.0 → 28.10.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__/LegendStudioCommand.d.ts +1 -0
- package/lib/__lib__/LegendStudioCommand.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioCommand.js +5 -0
- package/lib/__lib__/LegendStudioCommand.js.map +1 -1
- package/lib/components/ShowcaseManager.d.ts.map +1 -1
- package/lib/components/ShowcaseManager.js +5 -2
- package/lib/components/ShowcaseManager.js.map +1 -1
- package/lib/components/editor/ActivityBar.d.ts.map +1 -1
- package/lib/components/editor/ActivityBar.js +20 -17
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/editor-group/EditorGroup.d.ts.map +1 -1
- package/lib/components/editor/editor-group/EditorGroup.js +7 -1
- package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts +5 -0
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +28 -10
- package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts +11 -0
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js +22 -10
- package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts +7 -0
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +3 -3
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
- package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts +59 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js +145 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js.map +1 -0
- package/lib/components/editor/side-bar/SideBar.d.ts.map +1 -1
- package/lib/components/editor/side-bar/SideBar.js +4 -1
- package/lib/components/editor/side-bar/SideBar.js.map +1 -1
- package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts +23 -0
- package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts.map +1 -0
- package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js +41 -0
- package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js.map +1 -0
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/ShowcaseManagerState.d.ts +1 -0
- package/lib/stores/ShowcaseManagerState.d.ts.map +1 -1
- package/lib/stores/ShowcaseManagerState.js +11 -1
- package/lib/stores/ShowcaseManagerState.js.map +1 -1
- package/lib/stores/editor/EditorConfig.d.ts +3 -1
- package/lib/stores/editor/EditorConfig.d.ts.map +1 -1
- package/lib/stores/editor/EditorConfig.js +4 -1
- package/lib/stores/editor/EditorConfig.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts +2 -0
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +13 -0
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
- package/lib/stores/editor/ExplorerTreeState.js +1 -1
- package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
- package/lib/stores/editor/NewElementState.d.ts +1 -0
- package/lib/stores/editor/NewElementState.d.ts.map +1 -1
- package/lib/stores/editor/NewElementState.js +1 -1
- package/lib/stores/editor/NewElementState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +6 -2
- 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 +53 -34
- 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.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +1 -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 +3 -2
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js +8 -5
- package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js.map +1 -1
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts +22 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js +25 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js.map +1 -0
- package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts +113 -0
- package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts.map +1 -0
- package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js +494 -0
- package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js.map +1 -0
- package/lib/stores/showcase/ShowcaseViewerStore.d.ts.map +1 -1
- package/lib/stores/showcase/ShowcaseViewerStore.js +5 -1
- package/lib/stores/showcase/ShowcaseViewerStore.js.map +1 -1
- package/package.json +5 -5
- package/src/__lib__/LegendStudioCommand.ts +5 -0
- package/src/components/ShowcaseManager.tsx +18 -0
- package/src/components/editor/ActivityBar.tsx +56 -15
- package/src/components/editor/editor-group/EditorGroup.tsx +21 -1
- package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +135 -103
- package/src/components/editor/editor-group/connection-editor/DatabaseModelBuilder.tsx +97 -53
- package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +4 -3
- package/src/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.tsx +478 -0
- package/src/components/editor/side-bar/SideBar.tsx +13 -1
- package/src/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.tsx +101 -0
- package/src/stores/ShowcaseManagerState.ts +19 -1
- package/src/stores/editor/EditorConfig.ts +3 -0
- package/src/stores/editor/EditorStore.ts +16 -0
- package/src/stores/editor/ExplorerTreeState.ts +1 -0
- package/src/stores/editor/GraphEditGrammarModeState.ts +3 -3
- package/src/stores/editor/NewElementState.ts +1 -1
- package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +77 -49
- 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 +12 -8
- package/src/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.ts +25 -0
- package/src/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.tsx +884 -0
- package/src/stores/showcase/ShowcaseViewerStore.ts +4 -0
- package/tsconfig.json +5 -1
package/src/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.tsx
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
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 {
|
|
18
|
+
ResizablePanelGroup,
|
|
19
|
+
ResizablePanel,
|
|
20
|
+
Panel,
|
|
21
|
+
BaseStepper,
|
|
22
|
+
PanelContent,
|
|
23
|
+
Modal,
|
|
24
|
+
ModalBody,
|
|
25
|
+
InputWithInlineValidation,
|
|
26
|
+
PanelHeader,
|
|
27
|
+
PanelLoadingIndicator,
|
|
28
|
+
ResizablePanelSplitter,
|
|
29
|
+
EyeIcon,
|
|
30
|
+
BlankPanelContent,
|
|
31
|
+
} from '@finos/legend-art';
|
|
32
|
+
import { observer } from 'mobx-react-lite';
|
|
33
|
+
import type {
|
|
34
|
+
ConnectionValueStepperState,
|
|
35
|
+
DatabaseGrammarEditorStepperState,
|
|
36
|
+
DatabaseModelBuilderStepperState,
|
|
37
|
+
QueryConnectionConfirmationAndGrammarEditorStepperState,
|
|
38
|
+
QueryConnectionEndToEndWorkflowState,
|
|
39
|
+
} from '../../../../stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js';
|
|
40
|
+
import { useEffect, useMemo } from 'react';
|
|
41
|
+
import { RelationalConnectionGeneralEditor } from '../connection-editor/RelationalDatabaseConnectionEditor.js';
|
|
42
|
+
import { flowResult } from 'mobx';
|
|
43
|
+
import { useApplicationStore } from '@finos/legend-application';
|
|
44
|
+
import { DatabaseBuilderModalContent } from '../connection-editor/DatabaseBuilderWizard.js';
|
|
45
|
+
import { debounce, guaranteeNonNullable } from '@finos/legend-shared';
|
|
46
|
+
import {
|
|
47
|
+
CODE_EDITOR_LANGUAGE,
|
|
48
|
+
CodeEditor,
|
|
49
|
+
} from '@finos/legend-lego/code-editor';
|
|
50
|
+
import type { DatabaseBuilderWizardState } from '../../../../stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js';
|
|
51
|
+
import {
|
|
52
|
+
DatabaseModelPackageInput,
|
|
53
|
+
DatabaseModelPreviewEditor,
|
|
54
|
+
} from '../connection-editor/DatabaseModelBuilder.js';
|
|
55
|
+
|
|
56
|
+
export enum QUERY_CONNECTION_WORKFLOW_STEPS {
|
|
57
|
+
CREATE_CONNECTION = 'Create Connection',
|
|
58
|
+
CREATE_DATABASE = 'Create Database',
|
|
59
|
+
EDIT_DATABASE = 'Edit Database',
|
|
60
|
+
CREATE_CLASS_MAPPING_RUNTIME = 'Create Class/Mapping/Runtime',
|
|
61
|
+
CONFIRMATION = 'Confirmation',
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const QueryConnectionRelationalConnectionEditor = observer(
|
|
65
|
+
(props: {
|
|
66
|
+
queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowState;
|
|
67
|
+
connectionValueStepperState: ConnectionValueStepperState;
|
|
68
|
+
}) => {
|
|
69
|
+
const {
|
|
70
|
+
queryConnectionEndToEndWorkflowState,
|
|
71
|
+
connectionValueStepperState,
|
|
72
|
+
} = props;
|
|
73
|
+
const elementAlreadyExistsMessage =
|
|
74
|
+
queryConnectionEndToEndWorkflowState.globalEndToEndWorkflowState.editorStore.graphManagerState.graph.allElements
|
|
75
|
+
.map((s) => s.path)
|
|
76
|
+
.includes(connectionValueStepperState.targetConnectionPath)
|
|
77
|
+
? 'Element with same path already exists'
|
|
78
|
+
: undefined;
|
|
79
|
+
const onTargetPathChange: React.ChangeEventHandler<HTMLInputElement> = (
|
|
80
|
+
event,
|
|
81
|
+
) => {
|
|
82
|
+
connectionValueStepperState.setTargetConnectionPath(event.target.value);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Panel className="query-connection-workflow-panel query-connection-relational-connection-editor">
|
|
87
|
+
<PanelHeader title="build a connection" />
|
|
88
|
+
<PanelContent>
|
|
89
|
+
<div className="query-connection-relational-connection-editor__connection-builder">
|
|
90
|
+
<div className="panel__content__form__section query-connection-relational-connection-editor__connection-builder__path">
|
|
91
|
+
<div className="panel__content__form__section__header__label">
|
|
92
|
+
Target Connection Path
|
|
93
|
+
</div>
|
|
94
|
+
<InputWithInlineValidation
|
|
95
|
+
className="panel__content__form__section__input"
|
|
96
|
+
spellCheck={false}
|
|
97
|
+
onChange={onTargetPathChange}
|
|
98
|
+
value={connectionValueStepperState.targetConnectionPath}
|
|
99
|
+
error={elementAlreadyExistsMessage}
|
|
100
|
+
showEditableIcon={true}
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
<div className="query-connection-relational-connection-editor__editor">
|
|
104
|
+
<RelationalConnectionGeneralEditor
|
|
105
|
+
connectionValueState={
|
|
106
|
+
connectionValueStepperState.connectionValueState
|
|
107
|
+
}
|
|
108
|
+
isReadOnly={false}
|
|
109
|
+
hideHeader={true}
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</PanelContent>
|
|
114
|
+
</Panel>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
export const QueryConnectionDatabaseBuilderEditor = observer(
|
|
120
|
+
(props: { databaseBuilderState: DatabaseBuilderWizardState }) => {
|
|
121
|
+
const { databaseBuilderState } = props;
|
|
122
|
+
const applicationStore = useApplicationStore();
|
|
123
|
+
const preview = applicationStore.guardUnhandledError(() =>
|
|
124
|
+
flowResult(databaseBuilderState.previewDatabaseModel()),
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<Panel className="query-connection-workflow-panel query-connection-database-builder-editor">
|
|
129
|
+
<div className="query-connection-workflow-panel query-connection-database-builder-editor__header">
|
|
130
|
+
<PanelHeader title="Database Builder" />
|
|
131
|
+
<button
|
|
132
|
+
className="query-connection-workflow-panel query-connection-database-builder-editor__header__action"
|
|
133
|
+
onClick={preview}
|
|
134
|
+
title="Preview database..."
|
|
135
|
+
>
|
|
136
|
+
<EyeIcon className="query-connection-database-builder-editor__header__action__icon" />
|
|
137
|
+
<div className="query-connection-database-builder-editor__header__action__label">
|
|
138
|
+
Preview
|
|
139
|
+
</div>
|
|
140
|
+
</button>
|
|
141
|
+
</div>
|
|
142
|
+
<Modal
|
|
143
|
+
darkMode={true}
|
|
144
|
+
className="query-connection-database-builder-editor__modal"
|
|
145
|
+
>
|
|
146
|
+
<div className="query-connection-database-builder-editor__modal__content">
|
|
147
|
+
<DatabaseBuilderModalContent
|
|
148
|
+
databaseBuilderState={databaseBuilderState}
|
|
149
|
+
/>
|
|
150
|
+
</div>
|
|
151
|
+
</Modal>
|
|
152
|
+
</Panel>
|
|
153
|
+
);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
export const QueryConnectionDatabaseGrammarEditor = observer(
|
|
158
|
+
(props: {
|
|
159
|
+
queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowState;
|
|
160
|
+
databaseGrammarEditorStepperState: DatabaseGrammarEditorStepperState;
|
|
161
|
+
}) => {
|
|
162
|
+
const {
|
|
163
|
+
queryConnectionEndToEndWorkflowState,
|
|
164
|
+
databaseGrammarEditorStepperState,
|
|
165
|
+
} = props;
|
|
166
|
+
const applicationStore = useApplicationStore();
|
|
167
|
+
|
|
168
|
+
const compile = (): void => {
|
|
169
|
+
flowResult(
|
|
170
|
+
databaseGrammarEditorStepperState.compileDatabaseGrammarCode(),
|
|
171
|
+
).catch(applicationStore.alertUnhandledError);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const updateDatabaseGrammar = (val: string): void => {
|
|
175
|
+
queryConnectionEndToEndWorkflowState.setDatabaseGrammarCode(val);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<Panel className="query-connection-workflow-panel query-connection-database-builder-editor">
|
|
180
|
+
<div className="query-connection-workflow-panel query-connection-database-builder-editor__header">
|
|
181
|
+
<PanelHeader title="Database Editor" />
|
|
182
|
+
<button
|
|
183
|
+
className="query-connection-workflow-panel query-connection-database-builder-editor__header__action"
|
|
184
|
+
onClick={compile}
|
|
185
|
+
title="Compile database model..."
|
|
186
|
+
>
|
|
187
|
+
Compile
|
|
188
|
+
</button>
|
|
189
|
+
</div>
|
|
190
|
+
<PanelLoadingIndicator
|
|
191
|
+
isLoading={
|
|
192
|
+
databaseGrammarEditorStepperState.isCompilingGrammarCode
|
|
193
|
+
.isInProgress
|
|
194
|
+
}
|
|
195
|
+
/>
|
|
196
|
+
<div className="panel__content__form__section__header__prompt query-connection-database-builder-editor__prompt">
|
|
197
|
+
Joins could be added manually and please be aware that only one
|
|
198
|
+
database is supported in this flow
|
|
199
|
+
</div>
|
|
200
|
+
<div className="query-connection-database-builder-editor__editor">
|
|
201
|
+
<CodeEditor
|
|
202
|
+
inputValue={
|
|
203
|
+
queryConnectionEndToEndWorkflowState.databaseGrammarCode
|
|
204
|
+
}
|
|
205
|
+
updateInput={updateDatabaseGrammar}
|
|
206
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
|
207
|
+
error={queryConnectionEndToEndWorkflowState.compileError}
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
</Panel>
|
|
211
|
+
);
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
export const QueryConnectionModelsEditor = observer(
|
|
216
|
+
(props: {
|
|
217
|
+
databaseModelBuilderStepperState: DatabaseModelBuilderStepperState;
|
|
218
|
+
queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowState;
|
|
219
|
+
}) => {
|
|
220
|
+
const {
|
|
221
|
+
databaseModelBuilderStepperState,
|
|
222
|
+
queryConnectionEndToEndWorkflowState,
|
|
223
|
+
} = props;
|
|
224
|
+
const applicationStore = useApplicationStore();
|
|
225
|
+
|
|
226
|
+
const runtimeElementAlreadyExistsMessage =
|
|
227
|
+
queryConnectionEndToEndWorkflowState.globalEndToEndWorkflowState.editorStore.graphManagerState.graph.allElements
|
|
228
|
+
.map((s) => s.path)
|
|
229
|
+
.includes(queryConnectionEndToEndWorkflowState.targetRuntimePath)
|
|
230
|
+
? 'Element with same path already exists or must contain ::'
|
|
231
|
+
: undefined;
|
|
232
|
+
|
|
233
|
+
const debouncedRegenerateRuntime = useMemo(
|
|
234
|
+
() =>
|
|
235
|
+
debounce(
|
|
236
|
+
(val: string) => {
|
|
237
|
+
if (val !== '') {
|
|
238
|
+
queryConnectionEndToEndWorkflowState.updateRuntime(val);
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
500,
|
|
243
|
+
),
|
|
244
|
+
[queryConnectionEndToEndWorkflowState],
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const changeTargetRuntimePackage: React.ChangeEventHandler<
|
|
248
|
+
HTMLInputElement
|
|
249
|
+
> = (event) => {
|
|
250
|
+
queryConnectionEndToEndWorkflowState.setTargetRuntimePath(
|
|
251
|
+
event.target.value,
|
|
252
|
+
);
|
|
253
|
+
debouncedRegenerateRuntime(event.target.value);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
flowResult(
|
|
258
|
+
databaseModelBuilderStepperState.databaseModelBuilderState.previewDatabaseModels(),
|
|
259
|
+
)
|
|
260
|
+
.then(() =>
|
|
261
|
+
databaseModelBuilderStepperState.updateGraphWithModels(
|
|
262
|
+
guaranteeNonNullable(
|
|
263
|
+
databaseModelBuilderStepperState.databaseModelBuilderState
|
|
264
|
+
.entities,
|
|
265
|
+
),
|
|
266
|
+
),
|
|
267
|
+
)
|
|
268
|
+
.catch(applicationStore.alertUnhandledError);
|
|
269
|
+
}, [
|
|
270
|
+
applicationStore,
|
|
271
|
+
databaseModelBuilderStepperState,
|
|
272
|
+
databaseModelBuilderStepperState.databaseModelBuilderState,
|
|
273
|
+
databaseModelBuilderStepperState.databaseModelBuilderState.targetPackage,
|
|
274
|
+
queryConnectionEndToEndWorkflowState,
|
|
275
|
+
]);
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<Panel className="query-connection-workflow-panel query-connection-database-builder-editor">
|
|
279
|
+
<div className="query-connection-workflow-panel query-connection-database-builder-editor__header">
|
|
280
|
+
<PanelHeader title="Model Builder" />
|
|
281
|
+
</div>
|
|
282
|
+
<Modal
|
|
283
|
+
darkMode={true}
|
|
284
|
+
className="query-connection-connection-model-editor__modal"
|
|
285
|
+
>
|
|
286
|
+
<div className="query-connection-connection-model-editor__modal">
|
|
287
|
+
<ModalBody className="database-builder__content">
|
|
288
|
+
<ResizablePanelGroup orientation="vertical">
|
|
289
|
+
<ResizablePanel size={450}>
|
|
290
|
+
<div className="database-builder__config">
|
|
291
|
+
<PanelHeader title="schema explorer" />
|
|
292
|
+
<PanelContent className="database-builder__config__content">
|
|
293
|
+
<DatabaseModelPackageInput
|
|
294
|
+
databaseModelBuilderState={
|
|
295
|
+
databaseModelBuilderStepperState.databaseModelBuilderState
|
|
296
|
+
}
|
|
297
|
+
/>
|
|
298
|
+
<div className="panel__content__form__section">
|
|
299
|
+
<div className="panel__content__form__section__header__label">
|
|
300
|
+
Target Runtime Path
|
|
301
|
+
</div>
|
|
302
|
+
<div className="panel__content__form__section__header__prompt">
|
|
303
|
+
Target path for runtime
|
|
304
|
+
</div>
|
|
305
|
+
<InputWithInlineValidation
|
|
306
|
+
className="query-builder__variables__variable__name__input input-group__input"
|
|
307
|
+
spellCheck={false}
|
|
308
|
+
value={
|
|
309
|
+
queryConnectionEndToEndWorkflowState.targetRuntimePath
|
|
310
|
+
}
|
|
311
|
+
onChange={changeTargetRuntimePackage}
|
|
312
|
+
placeholder="Target Runtime path"
|
|
313
|
+
error={runtimeElementAlreadyExistsMessage}
|
|
314
|
+
showEditableIcon={true}
|
|
315
|
+
/>
|
|
316
|
+
</div>
|
|
317
|
+
</PanelContent>
|
|
318
|
+
</div>
|
|
319
|
+
</ResizablePanel>
|
|
320
|
+
<ResizablePanelSplitter />
|
|
321
|
+
<ResizablePanel>
|
|
322
|
+
<DatabaseModelPreviewEditor
|
|
323
|
+
databaseModelBuilderState={
|
|
324
|
+
databaseModelBuilderStepperState.databaseModelBuilderState
|
|
325
|
+
}
|
|
326
|
+
grammarCode={databaseModelBuilderStepperState.databaseModelBuilderState.generatedGrammarCode.concat(
|
|
327
|
+
queryConnectionEndToEndWorkflowState.runtimeGrammarCode,
|
|
328
|
+
)}
|
|
329
|
+
/>
|
|
330
|
+
</ResizablePanel>
|
|
331
|
+
</ResizablePanelGroup>
|
|
332
|
+
</ModalBody>
|
|
333
|
+
</div>
|
|
334
|
+
</Modal>
|
|
335
|
+
</Panel>
|
|
336
|
+
);
|
|
337
|
+
},
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
export const QueryConnectionConfirmationAndGrammarEditor = observer(
|
|
341
|
+
(props: {
|
|
342
|
+
queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowState;
|
|
343
|
+
queryConnectionConfirmationAndGrammarEditorStepperState: QueryConnectionConfirmationAndGrammarEditorStepperState;
|
|
344
|
+
}) => {
|
|
345
|
+
const {
|
|
346
|
+
queryConnectionEndToEndWorkflowState,
|
|
347
|
+
queryConnectionConfirmationAndGrammarEditorStepperState,
|
|
348
|
+
} = props;
|
|
349
|
+
const applicationStore = useApplicationStore();
|
|
350
|
+
|
|
351
|
+
const compile = (): void => {
|
|
352
|
+
flowResult(
|
|
353
|
+
queryConnectionConfirmationAndGrammarEditorStepperState.compile(),
|
|
354
|
+
).catch(applicationStore.alertUnhandledError);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const updateInput = (val: string): void => {
|
|
358
|
+
queryConnectionEndToEndWorkflowState.setFinalGrammarCode(val);
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
<Panel className="query-connection-workflow-panel query-connection-database-builder-editor">
|
|
363
|
+
<div className="query-connection-workflow-panel query-connection-database-builder-editor__header">
|
|
364
|
+
<PanelHeader title="Database Editor" />
|
|
365
|
+
<button
|
|
366
|
+
className="query-connection-workflow-panel query-connection-database-builder-editor__header__action"
|
|
367
|
+
onClick={compile}
|
|
368
|
+
title="Compile model..."
|
|
369
|
+
>
|
|
370
|
+
Compile
|
|
371
|
+
</button>
|
|
372
|
+
</div>
|
|
373
|
+
<PanelLoadingIndicator
|
|
374
|
+
isLoading={
|
|
375
|
+
queryConnectionConfirmationAndGrammarEditorStepperState
|
|
376
|
+
.isCompilingCode.isInProgress
|
|
377
|
+
}
|
|
378
|
+
/>
|
|
379
|
+
<div className="panel__content__form__section__header__prompt query-connection-database-builder-editor__prompt">
|
|
380
|
+
Please confirm models below will be added to the project and click
|
|
381
|
+
query to open query builder
|
|
382
|
+
</div>
|
|
383
|
+
<div className="query-connection-database-builder-editor__editor">
|
|
384
|
+
<CodeEditor
|
|
385
|
+
inputValue={queryConnectionEndToEndWorkflowState.finalGrammarCode}
|
|
386
|
+
updateInput={updateInput}
|
|
387
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
|
388
|
+
error={queryConnectionEndToEndWorkflowState.compileError}
|
|
389
|
+
/>
|
|
390
|
+
</div>
|
|
391
|
+
</Panel>
|
|
392
|
+
);
|
|
393
|
+
},
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
export const QueryConnectionWorflowEditor = observer(
|
|
397
|
+
(props: {
|
|
398
|
+
queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowState;
|
|
399
|
+
}) => {
|
|
400
|
+
const { queryConnectionEndToEndWorkflowState } = props;
|
|
401
|
+
const applicationStore = useApplicationStore();
|
|
402
|
+
const stepLabel =
|
|
403
|
+
queryConnectionEndToEndWorkflowState.activeStepToStepLabel.get(
|
|
404
|
+
queryConnectionEndToEndWorkflowState.activeStep,
|
|
405
|
+
);
|
|
406
|
+
const increaseActiveStep = (): void => {
|
|
407
|
+
if (queryConnectionEndToEndWorkflowState.isValid) {
|
|
408
|
+
queryConnectionEndToEndWorkflowState.setActiveStep(
|
|
409
|
+
queryConnectionEndToEndWorkflowState.activeStep + 1,
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
const handleNext = (): void => {
|
|
414
|
+
if (stepLabel) {
|
|
415
|
+
flowResult(
|
|
416
|
+
queryConnectionEndToEndWorkflowState.activeStepToBaseStepperState
|
|
417
|
+
.get(stepLabel)
|
|
418
|
+
?.handleNext(),
|
|
419
|
+
)
|
|
420
|
+
.then(() => increaseActiveStep())
|
|
421
|
+
.catch(applicationStore.alertUnhandledError);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
const handleBack = (): void => {
|
|
425
|
+
queryConnectionEndToEndWorkflowState.setCompileError(undefined);
|
|
426
|
+
queryConnectionEndToEndWorkflowState.setActiveStep(
|
|
427
|
+
queryConnectionEndToEndWorkflowState.activeStep - 1,
|
|
428
|
+
);
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const renderStepContent = (): React.ReactNode => {
|
|
432
|
+
if (stepLabel) {
|
|
433
|
+
return queryConnectionEndToEndWorkflowState.activeStepToBaseStepperState
|
|
434
|
+
.get(stepLabel)
|
|
435
|
+
?.renderStepContent();
|
|
436
|
+
} else {
|
|
437
|
+
return <BlankPanelContent> </BlankPanelContent>;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
return (
|
|
442
|
+
<div>
|
|
443
|
+
<Panel>
|
|
444
|
+
<PanelContent className="test-runner-panel__result">
|
|
445
|
+
<BaseStepper
|
|
446
|
+
steps={Object.values(QUERY_CONNECTION_WORKFLOW_STEPS)}
|
|
447
|
+
activeStep={queryConnectionEndToEndWorkflowState.activeStep}
|
|
448
|
+
></BaseStepper>
|
|
449
|
+
<PanelContent>
|
|
450
|
+
<div className="query-connection-workflow__content">
|
|
451
|
+
{renderStepContent()}
|
|
452
|
+
</div>
|
|
453
|
+
</PanelContent>
|
|
454
|
+
</PanelContent>
|
|
455
|
+
<div className="query-connection-workflow__actions">
|
|
456
|
+
<button
|
|
457
|
+
className="query-connection-workflow__actions__action-btn"
|
|
458
|
+
disabled={queryConnectionEndToEndWorkflowState.activeStep === 0}
|
|
459
|
+
onClick={handleBack}
|
|
460
|
+
title="Go to previous step..."
|
|
461
|
+
>
|
|
462
|
+
Back
|
|
463
|
+
</button>
|
|
464
|
+
<button
|
|
465
|
+
className="query-connection-workflow__actions__action-btn query-connection-workflow__actions__action-btn--primary"
|
|
466
|
+
onClick={handleNext}
|
|
467
|
+
>
|
|
468
|
+
{queryConnectionEndToEndWorkflowState.activeStep ===
|
|
469
|
+
Object.values(QUERY_CONNECTION_WORKFLOW_STEPS).length - 1
|
|
470
|
+
? 'Import And Query'
|
|
471
|
+
: 'Next'}
|
|
472
|
+
</button>
|
|
473
|
+
</div>
|
|
474
|
+
</Panel>
|
|
475
|
+
</div>
|
|
476
|
+
);
|
|
477
|
+
},
|
|
478
|
+
);
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { observer } from 'mobx-react-lite';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
ACTIVITY_MODE,
|
|
20
|
+
USER_JOURNEYS,
|
|
21
|
+
} from '../../../stores/editor/EditorConfig.js';
|
|
19
22
|
import { Explorer } from './Explorer.js';
|
|
20
23
|
import { LocalChanges } from './LocalChanges.js';
|
|
21
24
|
import { WorkspaceReview } from './WorkspaceReview.js';
|
|
@@ -26,6 +29,7 @@ import { WorkflowManager } from './WorkflowManager.js';
|
|
|
26
29
|
import { useEditorStore } from '../EditorStoreProvider.js';
|
|
27
30
|
import { GlobalTestRunner } from './testable/GlobalTestRunner.js';
|
|
28
31
|
import { RegisterService } from './RegisterService.js';
|
|
32
|
+
import { EndToEndWorkflow } from './end-to-end-workflow/EndToEndWorkflows.js';
|
|
29
33
|
|
|
30
34
|
/**
|
|
31
35
|
* Wrapper component around different implementations of sidebar, such as to view domain, to manage SDLC, etc.
|
|
@@ -67,6 +71,14 @@ export const SideBar = observer(() => {
|
|
|
67
71
|
}
|
|
68
72
|
/>
|
|
69
73
|
);
|
|
74
|
+
case USER_JOURNEYS.END_TO_END_WORKFLOWS:
|
|
75
|
+
return (
|
|
76
|
+
<EndToEndWorkflow
|
|
77
|
+
globalEndToEndWorkflowState={
|
|
78
|
+
editorStore.globalEndToEndWorkflowState
|
|
79
|
+
}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
70
82
|
default:
|
|
71
83
|
return null;
|
|
72
84
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
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 {
|
|
18
|
+
PanelContent,
|
|
19
|
+
PURE_ConnectionIcon,
|
|
20
|
+
PURE_UnknownElementTypeIcon,
|
|
21
|
+
} from '@finos/legend-art';
|
|
22
|
+
import { observer } from 'mobx-react-lite';
|
|
23
|
+
import {
|
|
24
|
+
type GlobalEndToEndWorkflowState,
|
|
25
|
+
SupportedEndToEndWorkflow,
|
|
26
|
+
} from '../../../../stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js';
|
|
27
|
+
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
|
28
|
+
|
|
29
|
+
export const getWorkflowIcon = (currentFlow: string): React.ReactNode => {
|
|
30
|
+
if (currentFlow === SupportedEndToEndWorkflow.CREATE_QUERY_FROM_CONNECTION) {
|
|
31
|
+
return (
|
|
32
|
+
<div
|
|
33
|
+
title="Create Query From Connection"
|
|
34
|
+
className="icon icon--connection color--connection"
|
|
35
|
+
>
|
|
36
|
+
<PURE_ConnectionIcon />
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
} else {
|
|
40
|
+
return (
|
|
41
|
+
<div title="Query From Workflow" className="icon">
|
|
42
|
+
<PURE_UnknownElementTypeIcon />
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const EndToEndWorkflow = observer(
|
|
49
|
+
(props: { globalEndToEndWorkflowState: GlobalEndToEndWorkflowState }) => {
|
|
50
|
+
const { globalEndToEndWorkflowState } = props;
|
|
51
|
+
|
|
52
|
+
const openWorkflow = (
|
|
53
|
+
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
|
54
|
+
flow: string,
|
|
55
|
+
): void => {
|
|
56
|
+
event.stopPropagation();
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
globalEndToEndWorkflowState.visitWorkflow(flow);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const endToEndWorkflow = (): React.ReactNode => (
|
|
62
|
+
<>
|
|
63
|
+
{Object.values(SupportedEndToEndWorkflow).map((flow) => (
|
|
64
|
+
<div className="side-bar__panel__item" key={flow}>
|
|
65
|
+
<div
|
|
66
|
+
className="end-to-end-workflow__container"
|
|
67
|
+
onClick={(event) => {
|
|
68
|
+
openWorkflow(event, flow);
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<div className="end-to-end-workflow__container__icon">
|
|
72
|
+
{getWorkflowIcon(flow)}
|
|
73
|
+
</div>
|
|
74
|
+
<div className="end-to-end-workflow__container__name">{flow}</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
))}
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
data-testid={LEGEND_STUDIO_TEST_ID.END_TO_END_WORKFLOW}
|
|
84
|
+
className="panel"
|
|
85
|
+
>
|
|
86
|
+
<div className="panel__header side-bar__header">
|
|
87
|
+
<div className="panel__header__title">
|
|
88
|
+
<div className="panel__header__title__content side-bar__header__title__content">
|
|
89
|
+
Guided End to End Workflows
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<div className="panel__content side-bar__content">
|
|
94
|
+
<div className="panel side-bar__panel">
|
|
95
|
+
<PanelContent>{endToEndWorkflow()}</PanelContent>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
},
|
|
101
|
+
);
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
} from '@finos/legend-application';
|
|
40
40
|
import type { TreeData, TreeNodeData } from '@finos/legend-art';
|
|
41
41
|
import { DIRECTORY_PATH_DELIMITER } from '@finos/legend-graph';
|
|
42
|
+
import { SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY } from '../components/extensions/Core_LegendStudioApplicationPlugin.js';
|
|
42
43
|
|
|
43
44
|
export enum SHOWCASE_MANAGER_VIEW {
|
|
44
45
|
EXPLORER = 'EXPLORER',
|
|
@@ -307,7 +308,9 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
|
|
|
307
308
|
this.initState.inProgress();
|
|
308
309
|
|
|
309
310
|
try {
|
|
310
|
-
this.showcases = (
|
|
311
|
+
this.showcases = (
|
|
312
|
+
(yield this.client.getShowcases()) as ShowcaseMetadata[]
|
|
313
|
+
).filter((showcase) => !showcase.development);
|
|
311
314
|
this.explorerTreeData = buildShowcasesExplorerTreeData(this.showcases);
|
|
312
315
|
// expand all the root nodes by default
|
|
313
316
|
this.explorerTreeData.rootIds.forEach((rootId) => {
|
|
@@ -372,3 +375,18 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
|
|
|
372
375
|
}
|
|
373
376
|
}
|
|
374
377
|
}
|
|
378
|
+
|
|
379
|
+
export const openShowcaseManager = (
|
|
380
|
+
applicationStore: LegendStudioApplicationStore,
|
|
381
|
+
): void => {
|
|
382
|
+
const showcaseManagerState =
|
|
383
|
+
ShowcaseManagerState.retrieveNullableState(applicationStore);
|
|
384
|
+
if (showcaseManagerState?.isEnabled) {
|
|
385
|
+
applicationStore.assistantService.setIsHidden(false);
|
|
386
|
+
applicationStore.assistantService.setIsOpen(true);
|
|
387
|
+
applicationStore.assistantService.setIsPanelMaximized(true);
|
|
388
|
+
applicationStore.assistantService.setSelectedTab(
|
|
389
|
+
SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
};
|