@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.
Files changed (106) hide show
  1. package/lib/__lib__/LegendStudioCommand.d.ts +1 -0
  2. package/lib/__lib__/LegendStudioCommand.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioCommand.js +5 -0
  4. package/lib/__lib__/LegendStudioCommand.js.map +1 -1
  5. package/lib/components/ShowcaseManager.d.ts.map +1 -1
  6. package/lib/components/ShowcaseManager.js +5 -2
  7. package/lib/components/ShowcaseManager.js.map +1 -1
  8. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  9. package/lib/components/editor/ActivityBar.js +20 -17
  10. package/lib/components/editor/ActivityBar.js.map +1 -1
  11. package/lib/components/editor/editor-group/EditorGroup.d.ts.map +1 -1
  12. package/lib/components/editor/editor-group/EditorGroup.js +7 -1
  13. package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
  14. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts +5 -0
  15. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -1
  16. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +28 -10
  17. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -1
  18. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts +11 -0
  19. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts.map +1 -1
  20. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js +22 -10
  21. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js.map +1 -1
  22. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts +7 -0
  23. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
  24. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +3 -3
  25. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  26. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts +59 -0
  27. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts.map +1 -0
  28. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js +145 -0
  29. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js.map +1 -0
  30. package/lib/components/editor/side-bar/SideBar.d.ts.map +1 -1
  31. package/lib/components/editor/side-bar/SideBar.js +4 -1
  32. package/lib/components/editor/side-bar/SideBar.js.map +1 -1
  33. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts +23 -0
  34. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts.map +1 -0
  35. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js +41 -0
  36. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js.map +1 -0
  37. package/lib/index.css +2 -2
  38. package/lib/index.css.map +1 -1
  39. package/lib/package.json +1 -1
  40. package/lib/stores/ShowcaseManagerState.d.ts +1 -0
  41. package/lib/stores/ShowcaseManagerState.d.ts.map +1 -1
  42. package/lib/stores/ShowcaseManagerState.js +11 -1
  43. package/lib/stores/ShowcaseManagerState.js.map +1 -1
  44. package/lib/stores/editor/EditorConfig.d.ts +3 -1
  45. package/lib/stores/editor/EditorConfig.d.ts.map +1 -1
  46. package/lib/stores/editor/EditorConfig.js +4 -1
  47. package/lib/stores/editor/EditorConfig.js.map +1 -1
  48. package/lib/stores/editor/EditorStore.d.ts +2 -0
  49. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  50. package/lib/stores/editor/EditorStore.js +13 -0
  51. package/lib/stores/editor/EditorStore.js.map +1 -1
  52. package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
  53. package/lib/stores/editor/ExplorerTreeState.js +1 -1
  54. package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
  55. package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
  56. package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
  57. package/lib/stores/editor/NewElementState.d.ts +1 -0
  58. package/lib/stores/editor/NewElementState.d.ts.map +1 -1
  59. package/lib/stores/editor/NewElementState.js +1 -1
  60. package/lib/stores/editor/NewElementState.js.map +1 -1
  61. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +6 -2
  62. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts.map +1 -1
  63. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js +53 -34
  64. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
  65. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts.map +1 -1
  66. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +1 -1
  67. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js.map +1 -1
  68. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts +3 -2
  69. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts.map +1 -1
  70. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js +8 -5
  71. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js.map +1 -1
  72. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts +22 -0
  73. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts.map +1 -0
  74. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js +25 -0
  75. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js.map +1 -0
  76. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts +113 -0
  77. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts.map +1 -0
  78. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js +494 -0
  79. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js.map +1 -0
  80. package/lib/stores/showcase/ShowcaseViewerStore.d.ts.map +1 -1
  81. package/lib/stores/showcase/ShowcaseViewerStore.js +5 -1
  82. package/lib/stores/showcase/ShowcaseViewerStore.js.map +1 -1
  83. package/package.json +5 -5
  84. package/src/__lib__/LegendStudioCommand.ts +5 -0
  85. package/src/components/ShowcaseManager.tsx +18 -0
  86. package/src/components/editor/ActivityBar.tsx +56 -15
  87. package/src/components/editor/editor-group/EditorGroup.tsx +21 -1
  88. package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +135 -103
  89. package/src/components/editor/editor-group/connection-editor/DatabaseModelBuilder.tsx +97 -53
  90. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +4 -3
  91. package/src/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.tsx +478 -0
  92. package/src/components/editor/side-bar/SideBar.tsx +13 -1
  93. package/src/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.tsx +101 -0
  94. package/src/stores/ShowcaseManagerState.ts +19 -1
  95. package/src/stores/editor/EditorConfig.ts +3 -0
  96. package/src/stores/editor/EditorStore.ts +16 -0
  97. package/src/stores/editor/ExplorerTreeState.ts +1 -0
  98. package/src/stores/editor/GraphEditGrammarModeState.ts +3 -3
  99. package/src/stores/editor/NewElementState.ts +1 -1
  100. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +77 -49
  101. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts +1 -2
  102. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.ts +12 -8
  103. package/src/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.ts +25 -0
  104. package/src/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.tsx +884 -0
  105. package/src/stores/showcase/ShowcaseViewerStore.ts +4 -0
  106. package/tsconfig.json +5 -1
@@ -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 { ACTIVITY_MODE } from '../../../stores/editor/EditorConfig.js';
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 = (yield this.client.getShowcases()) as ShowcaseMetadata[];
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
+ };
@@ -37,6 +37,9 @@ export enum ACTIVITY_MODE {
37
37
  WORKFLOW_MANAGER = 'WORKFLOW_MANAGER',
38
38
  TEST_RUNNER = 'TEST_RUNNER',
39
39
  REGISTER_SERVICES = 'REGISTER_SERVICES',
40
+ }
41
+
42
+ export enum USER_JOURNEYS {
40
43
  END_TO_END_WORKFLOWS = 'END_TO_END_WORKFLOWS',
41
44
  }
42
45