@finos/legend-application-studio 28.9.0 → 28.10.1
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 +29 -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/ConnectionToQueryWorkflowEditor.d.ts +52 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/ConnectionToQueryWorkflowEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/ConnectionToQueryWorkflowEditor.js +150 -0
- package/lib/components/editor/editor-group/end-to-end-flow-editor/ConnectionToQueryWorkflowEditor.js.map +1 -0
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js.map +1 -1
- package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
- package/lib/components/editor/side-bar/Explorer.js +6 -6
- package/lib/components/editor/side-bar/Explorer.js.map +1 -1
- 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 +43 -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 +3 -0
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +17 -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/ElementEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.js +2 -1
- package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.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 +23 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js.map +1 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.d.ts +111 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.js +453 -0
- package/lib/stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.js.map +1 -0
- package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts +24 -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 +37 -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 +136 -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/ConnectionToQueryWorkflowEditor.tsx +518 -0
- package/src/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.tsx +1 -1
- package/src/components/editor/side-bar/Explorer.tsx +7 -6
- package/src/components/editor/side-bar/SideBar.tsx +13 -1
- package/src/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.tsx +102 -0
- package/src/stores/ShowcaseManagerState.ts +19 -1
- package/src/stores/editor/EditorConfig.ts +3 -0
- package/src/stores/editor/EditorStore.ts +21 -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/ElementEditorState.ts +2 -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 +23 -0
- package/src/stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.ts +775 -0
- package/src/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.ts +43 -0
- package/src/stores/showcase/ShowcaseViewerStore.ts +4 -0
- package/tsconfig.json +5 -0
@@ -20,6 +20,7 @@ export enum LEGEND_STUDIO_COMMAND_KEY {
|
|
20
20
|
SYNC_WITH_WORKSPACE = 'editor.sync-workspace',
|
21
21
|
CREATE_ELEMENT = 'editor.create-new-element',
|
22
22
|
SEARCH_ELEMENT = 'editor.search-element',
|
23
|
+
OPEN_SHOWCASES = 'editor.show-showcases',
|
23
24
|
TOGGLE_TEXT_MODE = 'editor.toggle-text-mode',
|
24
25
|
GENERATE = 'editor.generate',
|
25
26
|
COMPILE = 'editor.compile',
|
@@ -48,6 +49,10 @@ export const LEGEND_STUDIO_COMMAND_CONFIG: CommandConfigData = {
|
|
48
49
|
title: 'Toggle model loader',
|
49
50
|
defaultKeyboardShortcut: 'F2',
|
50
51
|
},
|
52
|
+
[LEGEND_STUDIO_COMMAND_KEY.OPEN_SHOWCASES]: {
|
53
|
+
title: 'Open Showcases',
|
54
|
+
defaultKeyboardShortcut: 'F7',
|
55
|
+
},
|
51
56
|
[LEGEND_STUDIO_COMMAND_KEY.TOGGLE_TEXT_MODE]: {
|
52
57
|
title: 'Toggle text mode',
|
53
58
|
defaultKeyboardShortcut: 'F8',
|
@@ -32,6 +32,7 @@ import {
|
|
32
32
|
TimesIcon,
|
33
33
|
CodeIcon,
|
34
34
|
clsx,
|
35
|
+
CopyIcon,
|
35
36
|
} from '@finos/legend-art';
|
36
37
|
import {
|
37
38
|
SHOWCASE_MANAGER_SEARCH_CATEGORY,
|
@@ -545,6 +546,15 @@ const ShowcaseViewer = observer(
|
|
545
546
|
),
|
546
547
|
);
|
547
548
|
};
|
549
|
+
const handleCopy =
|
550
|
+
showcaseManagerState.applicationStore.guardUnhandledError(() =>
|
551
|
+
showcaseManagerState.applicationStore.clipboardService.copyTextToClipboard(
|
552
|
+
showcase.code,
|
553
|
+
{
|
554
|
+
notifySuccessMessage: 'Showcase grammar copied to clipboard',
|
555
|
+
},
|
556
|
+
),
|
557
|
+
);
|
548
558
|
return (
|
549
559
|
<div className="showcase-manager__view">
|
550
560
|
<div className="showcase-manager__view__header">
|
@@ -608,6 +618,14 @@ const ShowcaseViewer = observer(
|
|
608
618
|
</button>
|
609
619
|
</div>
|
610
620
|
</div>
|
621
|
+
<div className="showcase-manager__viewer__title__action">
|
622
|
+
<div
|
623
|
+
onClick={handleCopy}
|
624
|
+
className="showcase-manager__viewer__title__action-icon"
|
625
|
+
>
|
626
|
+
<CopyIcon />
|
627
|
+
</div>
|
628
|
+
</div>
|
611
629
|
</div>
|
612
630
|
<div className="showcase-manager__viewer__path">{prettyPath}</div>
|
613
631
|
<div className="showcase-manager__viewer__code">
|
@@ -15,7 +15,11 @@
|
|
15
15
|
*/
|
16
16
|
|
17
17
|
import { observer } from 'mobx-react-lite';
|
18
|
-
import {
|
18
|
+
import {
|
19
|
+
ACTIVITY_MODE,
|
20
|
+
PANEL_MODE,
|
21
|
+
USER_JOURNEYS,
|
22
|
+
} from '../../stores/editor/EditorConfig.js';
|
19
23
|
import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js';
|
20
24
|
import {
|
21
25
|
clsx,
|
@@ -36,6 +40,8 @@ import {
|
|
36
40
|
MenuContentDivider,
|
37
41
|
FlaskIcon,
|
38
42
|
RobotIcon,
|
43
|
+
WorkflowIcon,
|
44
|
+
ReadMeIcon,
|
39
45
|
} from '@finos/legend-art';
|
40
46
|
import { useEditorStore } from './EditorStoreProvider.js';
|
41
47
|
import { forwardRef, useState } from 'react';
|
@@ -47,8 +53,10 @@ import {
|
|
47
53
|
ActivityBarItemExperimentalBadge,
|
48
54
|
type ActivityBarItemConfig,
|
49
55
|
} from '@finos/legend-lego/application';
|
50
|
-
import {
|
51
|
-
|
56
|
+
import {
|
57
|
+
ShowcaseManagerState,
|
58
|
+
openShowcaseManager,
|
59
|
+
} from '../../stores/ShowcaseManagerState.js';
|
52
60
|
|
53
61
|
const SettingsMenu = observer(
|
54
62
|
forwardRef<HTMLDivElement, unknown>(function SettingsMenu(props, ref) {
|
@@ -103,17 +111,6 @@ export const ActivityBarMenu: React.FC = () => {
|
|
103
111
|
// showcases
|
104
112
|
const showcaseManagerState =
|
105
113
|
ShowcaseManagerState.retrieveNullableState(applicationStore);
|
106
|
-
const openShowcaseManager = (): void => {
|
107
|
-
if (showcaseManagerState?.isEnabled) {
|
108
|
-
applicationStore.assistantService.setIsHidden(false);
|
109
|
-
applicationStore.assistantService.setIsOpen(true);
|
110
|
-
applicationStore.assistantService.setIsPanelMaximized(true);
|
111
|
-
applicationStore.assistantService.setSelectedTab(
|
112
|
-
SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY,
|
113
|
-
);
|
114
|
-
}
|
115
|
-
};
|
116
|
-
|
117
114
|
return (
|
118
115
|
<>
|
119
116
|
<div className="activity-bar__menu">
|
@@ -128,7 +125,9 @@ export const ActivityBarMenu: React.FC = () => {
|
|
128
125
|
<MenuContent>
|
129
126
|
<MenuContentItem onClick={showAppInfo}>About</MenuContentItem>
|
130
127
|
{showcaseManagerState?.isEnabled && (
|
131
|
-
<MenuContentItem
|
128
|
+
<MenuContentItem
|
129
|
+
onClick={() => openShowcaseManager(applicationStore)}
|
130
|
+
>
|
132
131
|
See Showcases
|
133
132
|
</MenuContentItem>
|
134
133
|
)}
|
@@ -363,6 +362,23 @@ export const ActivityBar = observer(() => {
|
|
363
362
|
] as (ActivityBarItemConfig | boolean)[]
|
364
363
|
).filter((activity): activity is ActivityBarItemConfig => Boolean(activity));
|
365
364
|
|
365
|
+
const userJourneys: ActivityBarItemConfig[] = (
|
366
|
+
[
|
367
|
+
!editorStore.isInConflictResolutionMode &&
|
368
|
+
editorStore.applicationStore.config.options
|
369
|
+
.TEMPORARY__enableEndtoEndWorkflow && {
|
370
|
+
mode: USER_JOURNEYS.END_TO_END_WORKFLOWS,
|
371
|
+
title: 'End to End Workflows (Beta)',
|
372
|
+
icon: (
|
373
|
+
<div>
|
374
|
+
<WorkflowIcon className="activity-bar__icon--service-registrar" />
|
375
|
+
<ActivityBarItemExperimentalBadge />
|
376
|
+
</div>
|
377
|
+
),
|
378
|
+
},
|
379
|
+
] as (ActivityBarItemConfig | boolean)[]
|
380
|
+
).filter((activity): activity is ActivityBarItemConfig => Boolean(activity));
|
381
|
+
|
366
382
|
return (
|
367
383
|
<div className="activity-bar">
|
368
384
|
<ActivityBarMenu />
|
@@ -382,9 +398,34 @@ export const ActivityBar = observer(() => {
|
|
382
398
|
{activity.icon}
|
383
399
|
</button>
|
384
400
|
))}
|
401
|
+
<MenuContentDivider />
|
402
|
+
{userJourneys.map((activity) => (
|
403
|
+
<button
|
404
|
+
key={activity.mode}
|
405
|
+
className={clsx('activity-bar__item', {
|
406
|
+
'activity-bar__item--active':
|
407
|
+
editorStore.sideBarDisplayState.isOpen &&
|
408
|
+
editorStore.activeActivity === activity.mode,
|
409
|
+
})}
|
410
|
+
onClick={changeActivity(activity.mode)}
|
411
|
+
tabIndex={-1}
|
412
|
+
title={activity.title}
|
413
|
+
>
|
414
|
+
{activity.icon}
|
415
|
+
</button>
|
416
|
+
))}
|
385
417
|
</div>
|
418
|
+
<button
|
419
|
+
className={clsx('activity-bar__item')}
|
420
|
+
onClick={() => openShowcaseManager(editorStore.applicationStore)}
|
421
|
+
tabIndex={-1}
|
422
|
+
title={'Open Showcases'}
|
423
|
+
>
|
424
|
+
<ReadMeIcon />
|
425
|
+
</button>
|
386
426
|
<DropdownMenu
|
387
427
|
className="activity-bar__item"
|
428
|
+
title="Settings"
|
388
429
|
content={<SettingsMenu />}
|
389
430
|
menuProps={{
|
390
431
|
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
@@ -77,6 +77,8 @@ import { INTERNAL__UnknownFunctionActivatorEdtiorState } from '../../../stores/e
|
|
77
77
|
import { INTERNAL__UnknownFunctionActivatorEdtior } from './INTERNAL__UnknownFunctionActivatorEdtior.js';
|
78
78
|
import { getElementIcon } from '../../ElementIconUtils.js';
|
79
79
|
import { ArtifactGenerationViewerState } from '../../../stores/editor/editor-state/ArtifactGenerationViewerState.js';
|
80
|
+
import { QueryConnectionWorflowEditor } from './end-to-end-flow-editor/ConnectionToQueryWorkflowEditor.js';
|
81
|
+
import { QueryConnectionEndToEndWorkflowEditorState } from '../../../stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.js';
|
80
82
|
|
81
83
|
export const ViewerEditorGroupSplashScreen: React.FC = () => {
|
82
84
|
const commandListWidth = 300;
|
@@ -119,7 +121,6 @@ export const EditorGroupSplashScreen: React.FC = () => {
|
|
119
121
|
const commandListHeight = 180;
|
120
122
|
const [showCommandList, setShowCommandList] = useState(false);
|
121
123
|
const { ref, width, height } = useResizeDetector<HTMLDivElement>();
|
122
|
-
|
123
124
|
useEffect(() => {
|
124
125
|
setShowCommandList(
|
125
126
|
(width ?? 0) > commandListWidth && (height ?? 0) > commandListHeight,
|
@@ -157,6 +158,14 @@ export const EditorGroupSplashScreen: React.FC = () => {
|
|
157
158
|
<div className="hotkey__key">S</div>
|
158
159
|
</div>
|
159
160
|
</div>
|
161
|
+
<div className="editor-group__splash-screen__content__item">
|
162
|
+
<div className="editor-group__splash-screen__content__item__label">
|
163
|
+
Open Showcases
|
164
|
+
</div>
|
165
|
+
<div className="editor-group__splash-screen__content__item__hot-keys">
|
166
|
+
<div className="hotkey__key">F7</div>
|
167
|
+
</div>
|
168
|
+
</div>
|
160
169
|
<div className="editor-group__splash-screen__content__item">
|
161
170
|
<div className="editor-group__splash-screen__content__item__label">
|
162
171
|
Toggle Hackermode
|
@@ -315,6 +324,17 @@ export const EditorGroup = observer(() => {
|
|
315
324
|
return <ModelImporter />;
|
316
325
|
} else if (currentTabState instanceof ProjectConfigurationEditorState) {
|
317
326
|
return <ProjectConfigurationEditor />;
|
327
|
+
} else if (
|
328
|
+
currentTabState instanceof QueryConnectionEndToEndWorkflowEditorState
|
329
|
+
) {
|
330
|
+
return (
|
331
|
+
<QueryConnectionWorflowEditor
|
332
|
+
connectionToQueryWorkflowState={
|
333
|
+
editorStore.globalEndToEndWorkflowState
|
334
|
+
.queryToConnectionWorkflowEditorState
|
335
|
+
}
|
336
|
+
/>
|
337
|
+
);
|
318
338
|
}
|
319
339
|
// TODO: create an editor for unsupported tab
|
320
340
|
return null;
|
@@ -127,6 +127,139 @@ const QueryBuilderGridResult = observer(
|
|
127
127
|
},
|
128
128
|
);
|
129
129
|
|
130
|
+
export const DatabaseBuilderModalContent = observer(
|
131
|
+
(props: { databaseBuilderState: DatabaseBuilderWizardState }) => {
|
132
|
+
const { databaseBuilderState } = props;
|
133
|
+
const applicationStore = useApplicationStore();
|
134
|
+
const schemaExplorerState = databaseBuilderState.schemaExplorerState;
|
135
|
+
const isCreatingNewDatabase = schemaExplorerState.isCreatingNewDatabase;
|
136
|
+
const elementAlreadyExistsMessage =
|
137
|
+
isCreatingNewDatabase &&
|
138
|
+
databaseBuilderState.editorStore.graphManagerState.graph.allElements
|
139
|
+
.map((s) => s.path)
|
140
|
+
.includes(schemaExplorerState.targetDatabasePath)
|
141
|
+
? 'Element with same path already exists'
|
142
|
+
: undefined;
|
143
|
+
|
144
|
+
const isExecutingAction =
|
145
|
+
schemaExplorerState.isGeneratingDatabase ||
|
146
|
+
schemaExplorerState.isUpdatingDatabase ||
|
147
|
+
schemaExplorerState.previewDataState.isInProgress;
|
148
|
+
|
149
|
+
const onTargetPathChange: React.ChangeEventHandler<HTMLInputElement> = (
|
150
|
+
event,
|
151
|
+
) => {
|
152
|
+
schemaExplorerState.setTargetDatabasePath(event.target.value);
|
153
|
+
};
|
154
|
+
|
155
|
+
useEffect(() => {
|
156
|
+
flowResult(schemaExplorerState.fetchDatabaseMetadata()).catch(
|
157
|
+
applicationStore.alertUnhandledError,
|
158
|
+
);
|
159
|
+
}, [applicationStore, schemaExplorerState]);
|
160
|
+
|
161
|
+
useConditionedApplicationNavigationContext(
|
162
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_BUILDER,
|
163
|
+
databaseBuilderState.showModal,
|
164
|
+
);
|
165
|
+
|
166
|
+
return (
|
167
|
+
<ModalBody className="database-builder__content">
|
168
|
+
<PanelLoadingIndicator isLoading={isExecutingAction} />
|
169
|
+
<ResizablePanelGroup orientation="vertical">
|
170
|
+
<ResizablePanel size={450}>
|
171
|
+
<ResizablePanelGroup>
|
172
|
+
<ResizablePanel>
|
173
|
+
<div className="database-builder__config">
|
174
|
+
<PanelHeader title="schema explorer" />
|
175
|
+
<PanelContent className="database-builder__config__content">
|
176
|
+
{schemaExplorerState.treeData && (
|
177
|
+
<DatabaseSchemaExplorer
|
178
|
+
treeData={schemaExplorerState.treeData}
|
179
|
+
isReadOnly={false}
|
180
|
+
schemaExplorerState={
|
181
|
+
databaseBuilderState.schemaExplorerState
|
182
|
+
}
|
183
|
+
/>
|
184
|
+
)}
|
185
|
+
</PanelContent>
|
186
|
+
</div>
|
187
|
+
</ResizablePanel>
|
188
|
+
<ResizablePanelSplitter>
|
189
|
+
<ResizablePanelSplitterLine
|
190
|
+
color={'var(--color-dark-grey-250)'}
|
191
|
+
/>
|
192
|
+
</ResizablePanelSplitter>
|
193
|
+
<ResizablePanel>
|
194
|
+
<div className="database-builder__config">
|
195
|
+
<PanelHeader title="preview" />
|
196
|
+
<PanelContent className="database-builder__config__content">
|
197
|
+
{databaseBuilderState.schemaExplorerState.previewer && (
|
198
|
+
<QueryBuilderGridResult
|
199
|
+
executionResult={
|
200
|
+
databaseBuilderState.schemaExplorerState.previewer
|
201
|
+
}
|
202
|
+
/>
|
203
|
+
)}
|
204
|
+
</PanelContent>
|
205
|
+
</div>
|
206
|
+
</ResizablePanel>
|
207
|
+
</ResizablePanelGroup>
|
208
|
+
</ResizablePanel>
|
209
|
+
<ResizablePanelSplitter />
|
210
|
+
<ResizablePanel>
|
211
|
+
<Panel className="database-builder__model">
|
212
|
+
<PanelHeader title="database model" />
|
213
|
+
<PanelContent>
|
214
|
+
<div className="database-builder__modeler">
|
215
|
+
<div className="panel__content__form__section database-builder__modeler__path">
|
216
|
+
<div className="panel__content__form__section__header__label">
|
217
|
+
Target Database Path
|
218
|
+
</div>
|
219
|
+
<InputWithInlineValidation
|
220
|
+
className="panel__content__form__section__input"
|
221
|
+
spellCheck={false}
|
222
|
+
onChange={onTargetPathChange}
|
223
|
+
disabled={
|
224
|
+
schemaExplorerState.makeTargetDatabasePathEditable
|
225
|
+
? false
|
226
|
+
: !isCreatingNewDatabase
|
227
|
+
}
|
228
|
+
value={
|
229
|
+
schemaExplorerState.makeTargetDatabasePathEditable ||
|
230
|
+
isCreatingNewDatabase
|
231
|
+
? schemaExplorerState.targetDatabasePath
|
232
|
+
: schemaExplorerState.database.path
|
233
|
+
}
|
234
|
+
error={elementAlreadyExistsMessage}
|
235
|
+
showEditableIcon={true}
|
236
|
+
/>
|
237
|
+
</div>
|
238
|
+
<div className="database-builder__modeler__preview">
|
239
|
+
<div className="database-builder__modeler__preview__header">
|
240
|
+
readonly
|
241
|
+
</div>
|
242
|
+
{databaseBuilderState.databaseGrammarCode && (
|
243
|
+
<CodeEditor
|
244
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
245
|
+
inputValue={databaseBuilderState.databaseGrammarCode}
|
246
|
+
isReadOnly={true}
|
247
|
+
/>
|
248
|
+
)}
|
249
|
+
{!databaseBuilderState.databaseGrammarCode && (
|
250
|
+
<BlankPanelContent>No database preview</BlankPanelContent>
|
251
|
+
)}
|
252
|
+
</div>
|
253
|
+
</div>
|
254
|
+
</PanelContent>
|
255
|
+
</Panel>
|
256
|
+
</ResizablePanel>
|
257
|
+
</ResizablePanelGroup>
|
258
|
+
</ModalBody>
|
259
|
+
);
|
260
|
+
},
|
261
|
+
);
|
262
|
+
|
130
263
|
export const DatabaseBuilderWizard = observer(
|
131
264
|
(props: {
|
132
265
|
databaseBuilderState: DatabaseBuilderWizardState;
|
@@ -147,11 +280,6 @@ export const DatabaseBuilderWizard = observer(
|
|
147
280
|
const preview = applicationStore.guardUnhandledError(() =>
|
148
281
|
flowResult(databaseBuilderState.previewDatabaseModel()),
|
149
282
|
);
|
150
|
-
const onTargetPathChange: React.ChangeEventHandler<HTMLInputElement> = (
|
151
|
-
event,
|
152
|
-
) => {
|
153
|
-
schemaExplorerState.setTargetDatabasePath(event.target.value);
|
154
|
-
};
|
155
283
|
const updateDatabase = applicationStore.guardUnhandledError(() =>
|
156
284
|
flowResult(databaseBuilderState.updateDatabase()),
|
157
285
|
);
|
@@ -166,17 +294,6 @@ export const DatabaseBuilderWizard = observer(
|
|
166
294
|
schemaExplorerState.isUpdatingDatabase ||
|
167
295
|
schemaExplorerState.previewDataState.isInProgress;
|
168
296
|
|
169
|
-
useEffect(() => {
|
170
|
-
flowResult(schemaExplorerState.fetchDatabaseMetadata()).catch(
|
171
|
-
applicationStore.alertUnhandledError,
|
172
|
-
);
|
173
|
-
}, [applicationStore, schemaExplorerState]);
|
174
|
-
|
175
|
-
useConditionedApplicationNavigationContext(
|
176
|
-
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_BUILDER,
|
177
|
-
databaseBuilderState.showModal,
|
178
|
-
);
|
179
|
-
|
180
297
|
return (
|
181
298
|
<Dialog
|
182
299
|
open={databaseBuilderState.showModal}
|
@@ -201,93 +318,9 @@ export const DatabaseBuilderWizard = observer(
|
|
201
318
|
</button>
|
202
319
|
</ModalHeaderActions>
|
203
320
|
</ModalHeader>
|
204
|
-
<
|
205
|
-
|
206
|
-
|
207
|
-
<ResizablePanel size={450}>
|
208
|
-
<ResizablePanelGroup>
|
209
|
-
<ResizablePanel>
|
210
|
-
<div className="database-builder__config">
|
211
|
-
<PanelHeader title="schema explorer" />
|
212
|
-
<PanelContent className="database-builder__config__content">
|
213
|
-
{schemaExplorerState.treeData && (
|
214
|
-
<DatabaseSchemaExplorer
|
215
|
-
treeData={schemaExplorerState.treeData}
|
216
|
-
isReadOnly={false}
|
217
|
-
schemaExplorerState={
|
218
|
-
databaseBuilderState.schemaExplorerState
|
219
|
-
}
|
220
|
-
/>
|
221
|
-
)}
|
222
|
-
</PanelContent>
|
223
|
-
</div>
|
224
|
-
</ResizablePanel>
|
225
|
-
<ResizablePanelSplitter>
|
226
|
-
<ResizablePanelSplitterLine
|
227
|
-
color={'var(--color-dark-grey-250)'}
|
228
|
-
/>
|
229
|
-
</ResizablePanelSplitter>
|
230
|
-
<ResizablePanel>
|
231
|
-
<div className="database-builder__config">
|
232
|
-
<PanelHeader title="preview" />
|
233
|
-
<PanelContent className="database-builder__config__content">
|
234
|
-
{databaseBuilderState.schemaExplorerState.previewer && (
|
235
|
-
<QueryBuilderGridResult
|
236
|
-
executionResult={
|
237
|
-
databaseBuilderState.schemaExplorerState.previewer
|
238
|
-
}
|
239
|
-
/>
|
240
|
-
)}
|
241
|
-
</PanelContent>
|
242
|
-
</div>
|
243
|
-
</ResizablePanel>
|
244
|
-
</ResizablePanelGroup>
|
245
|
-
</ResizablePanel>
|
246
|
-
<ResizablePanelSplitter />
|
247
|
-
<ResizablePanel>
|
248
|
-
<Panel className="database-builder__model">
|
249
|
-
<PanelHeader title="database model" />
|
250
|
-
<PanelContent>
|
251
|
-
<div className="database-builder__modeler">
|
252
|
-
<div className="panel__content__form__section database-builder__modeler__path">
|
253
|
-
<div className="panel__content__form__section__header__label">
|
254
|
-
Target Database Path
|
255
|
-
</div>
|
256
|
-
<InputWithInlineValidation
|
257
|
-
className="panel__content__form__section__input"
|
258
|
-
spellCheck={false}
|
259
|
-
onChange={onTargetPathChange}
|
260
|
-
disabled={!isCreatingNewDatabase}
|
261
|
-
value={
|
262
|
-
isCreatingNewDatabase
|
263
|
-
? schemaExplorerState.targetDatabasePath
|
264
|
-
: schemaExplorerState.database.path
|
265
|
-
}
|
266
|
-
error={elementAlreadyExistsMessage}
|
267
|
-
/>
|
268
|
-
</div>
|
269
|
-
<div className="database-builder__modeler__preview">
|
270
|
-
{databaseBuilderState.databaseGrammarCode && (
|
271
|
-
<CodeEditor
|
272
|
-
language={CODE_EDITOR_LANGUAGE.PURE}
|
273
|
-
inputValue={
|
274
|
-
databaseBuilderState.databaseGrammarCode
|
275
|
-
}
|
276
|
-
isReadOnly={true}
|
277
|
-
/>
|
278
|
-
)}
|
279
|
-
{!databaseBuilderState.databaseGrammarCode && (
|
280
|
-
<BlankPanelContent>
|
281
|
-
No database preview
|
282
|
-
</BlankPanelContent>
|
283
|
-
)}
|
284
|
-
</div>
|
285
|
-
</div>
|
286
|
-
</PanelContent>
|
287
|
-
</Panel>
|
288
|
-
</ResizablePanel>
|
289
|
-
</ResizablePanelGroup>
|
290
|
-
</ModalBody>
|
321
|
+
<DatabaseBuilderModalContent
|
322
|
+
databaseBuilderState={databaseBuilderState}
|
323
|
+
/>
|
291
324
|
<ModalFooter>
|
292
325
|
<ModalFooterButton
|
293
326
|
className="database-builder__action--btn"
|
@@ -50,6 +50,95 @@ import {
|
|
50
50
|
import { debounce, noop } from '@finos/legend-shared';
|
51
51
|
import { isValidPath } from '@finos/legend-graph';
|
52
52
|
|
53
|
+
export const DatabaseModelPackageInput = observer(
|
54
|
+
(props: { databaseModelBuilderState: DatabaseModelBuilderState }) => {
|
55
|
+
const { databaseModelBuilderState } = props;
|
56
|
+
|
57
|
+
const applicationStore = useApplicationStore();
|
58
|
+
const debouncedRegenerate = useMemo(
|
59
|
+
() =>
|
60
|
+
debounce(
|
61
|
+
() => flowResult(databaseModelBuilderState.previewDatabaseModels()),
|
62
|
+
500,
|
63
|
+
),
|
64
|
+
[databaseModelBuilderState],
|
65
|
+
);
|
66
|
+
|
67
|
+
const changeTargetPackage: React.ChangeEventHandler<HTMLInputElement> = (
|
68
|
+
event,
|
69
|
+
) => {
|
70
|
+
databaseModelBuilderState.setTargetPackage(event.target.value);
|
71
|
+
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
|
72
|
+
};
|
73
|
+
|
74
|
+
const targetPackageValidationMessage =
|
75
|
+
!databaseModelBuilderState.targetPackage
|
76
|
+
? `Target package path can't be empty`
|
77
|
+
: !isValidPath(databaseModelBuilderState.targetPackage)
|
78
|
+
? 'Invalid target package path'
|
79
|
+
: undefined;
|
80
|
+
|
81
|
+
return (
|
82
|
+
<div className="panel__content__form__section">
|
83
|
+
<div className="panel__content__form__section__header__label">
|
84
|
+
Target Package
|
85
|
+
</div>
|
86
|
+
<div className="panel__content__form__section__header__prompt">
|
87
|
+
Target Package of Mapping and Models Generated
|
88
|
+
</div>
|
89
|
+
<InputWithInlineValidation
|
90
|
+
className="query-builder__variables__variable__name__input input-group__input"
|
91
|
+
spellCheck={false}
|
92
|
+
value={databaseModelBuilderState.targetPackage}
|
93
|
+
onChange={changeTargetPackage}
|
94
|
+
placeholder="Target package path"
|
95
|
+
error={targetPackageValidationMessage}
|
96
|
+
showEditableIcon={true}
|
97
|
+
/>
|
98
|
+
</div>
|
99
|
+
);
|
100
|
+
},
|
101
|
+
);
|
102
|
+
|
103
|
+
export const DatabaseModelPreviewEditor = observer(
|
104
|
+
(props: {
|
105
|
+
databaseModelBuilderState: DatabaseModelBuilderState;
|
106
|
+
grammarCode: string;
|
107
|
+
}) => {
|
108
|
+
const { databaseModelBuilderState, grammarCode } = props;
|
109
|
+
|
110
|
+
const isExecutingAction =
|
111
|
+
databaseModelBuilderState.generatingModelState.isInProgress ||
|
112
|
+
databaseModelBuilderState.saveModelState.isInProgress;
|
113
|
+
|
114
|
+
return (
|
115
|
+
<Panel className="database-builder__model">
|
116
|
+
<PanelHeader title="database model" />
|
117
|
+
<PanelContent>
|
118
|
+
<PanelLoadingIndicator isLoading={isExecutingAction} />
|
119
|
+
<div className="database-builder__modeler">
|
120
|
+
<div className="database-builder__modeler__preview">
|
121
|
+
<div className="database-builder__modeler__preview__header">
|
122
|
+
readonly
|
123
|
+
</div>
|
124
|
+
{databaseModelBuilderState.generatedGrammarCode && (
|
125
|
+
<CodeEditor
|
126
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
127
|
+
inputValue={grammarCode}
|
128
|
+
isReadOnly={true}
|
129
|
+
/>
|
130
|
+
)}
|
131
|
+
{!databaseModelBuilderState.generatedGrammarCode && (
|
132
|
+
<BlankPanelContent>No model preview</BlankPanelContent>
|
133
|
+
)}
|
134
|
+
</div>
|
135
|
+
</div>
|
136
|
+
</PanelContent>
|
137
|
+
</Panel>
|
138
|
+
);
|
139
|
+
},
|
140
|
+
);
|
141
|
+
|
53
142
|
export const DatabaseModelBuilder = observer(
|
54
143
|
(props: {
|
55
144
|
databaseModelBuilderState: DatabaseModelBuilderState;
|
@@ -66,6 +155,7 @@ export const DatabaseModelBuilder = observer(
|
|
66
155
|
),
|
67
156
|
[databaseModelBuilderState],
|
68
157
|
);
|
158
|
+
|
69
159
|
const preview = (): void => {
|
70
160
|
debouncedRegenerate.cancel();
|
71
161
|
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
|
@@ -78,19 +168,6 @@ export const DatabaseModelBuilder = observer(
|
|
78
168
|
databaseModelBuilderState.close();
|
79
169
|
};
|
80
170
|
|
81
|
-
const targetPackageValidationMessage =
|
82
|
-
!databaseModelBuilderState.targetPackage
|
83
|
-
? `Target package path can't be empty`
|
84
|
-
: !isValidPath(databaseModelBuilderState.targetPackage)
|
85
|
-
? 'Invalid target package path'
|
86
|
-
: undefined;
|
87
|
-
|
88
|
-
const changeTargetPackage: React.ChangeEventHandler<HTMLInputElement> = (
|
89
|
-
event,
|
90
|
-
) => {
|
91
|
-
databaseModelBuilderState.setTargetPackage(event.target.value);
|
92
|
-
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
|
93
|
-
};
|
94
171
|
const isExecutingAction =
|
95
172
|
databaseModelBuilderState.generatingModelState.isInProgress ||
|
96
173
|
databaseModelBuilderState.saveModelState.isInProgress;
|
@@ -136,51 +213,18 @@ export const DatabaseModelBuilder = observer(
|
|
136
213
|
<div className="database-builder__config">
|
137
214
|
<PanelHeader title="schema explorer" />
|
138
215
|
<PanelContent className="database-builder__config__content">
|
139
|
-
<
|
140
|
-
|
141
|
-
|
142
|
-
</div>
|
143
|
-
<div className="panel__content__form__section__header__prompt">
|
144
|
-
{'Target Package of Mapping and Models Generated'}
|
145
|
-
</div>
|
146
|
-
<InputWithInlineValidation
|
147
|
-
className="query-builder__variables__variable__name__input input-group__input"
|
148
|
-
spellCheck={false}
|
149
|
-
value={databaseModelBuilderState.targetPackage}
|
150
|
-
onChange={changeTargetPackage}
|
151
|
-
placeholder="Target package path"
|
152
|
-
error={targetPackageValidationMessage}
|
153
|
-
/>
|
154
|
-
</div>
|
216
|
+
<DatabaseModelPackageInput
|
217
|
+
databaseModelBuilderState={databaseModelBuilderState}
|
218
|
+
/>
|
155
219
|
</PanelContent>
|
156
220
|
</div>
|
157
221
|
</ResizablePanel>
|
158
222
|
<ResizablePanelSplitter />
|
159
223
|
<ResizablePanel>
|
160
|
-
<
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
<div className="database-builder__modeler">
|
165
|
-
<div className="database-builder__modeler__preview">
|
166
|
-
{databaseModelBuilderState.generatedGrammarCode && (
|
167
|
-
<CodeEditor
|
168
|
-
language={CODE_EDITOR_LANGUAGE.PURE}
|
169
|
-
inputValue={
|
170
|
-
databaseModelBuilderState.generatedGrammarCode
|
171
|
-
}
|
172
|
-
isReadOnly={true}
|
173
|
-
/>
|
174
|
-
)}
|
175
|
-
{!databaseModelBuilderState.generatedGrammarCode && (
|
176
|
-
<BlankPanelContent>
|
177
|
-
No model preview
|
178
|
-
</BlankPanelContent>
|
179
|
-
)}
|
180
|
-
</div>
|
181
|
-
</div>
|
182
|
-
</PanelContent>
|
183
|
-
</Panel>
|
224
|
+
<DatabaseModelPreviewEditor
|
225
|
+
databaseModelBuilderState={databaseModelBuilderState}
|
226
|
+
grammarCode={databaseModelBuilderState.generatedGrammarCode}
|
227
|
+
/>
|
184
228
|
</ResizablePanel>
|
185
229
|
</ResizablePanelGroup>
|
186
230
|
</ModalBody>
|