@finos/legend-application-studio 27.1.1 → 27.1.2

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 (68) hide show
  1. package/lib/components/editor/editor-group/FunctionEditor.d.ts.map +1 -1
  2. package/lib/components/editor/editor-group/FunctionEditor.js +28 -24
  3. package/lib/components/editor/editor-group/FunctionEditor.js.map +1 -1
  4. package/lib/components/editor/editor-group/connection-editor/{DatabaseBuilder.d.ts → DatabaseBuilderWizard.d.ts} +4 -11
  5. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -0
  6. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +48 -0
  7. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -0
  8. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.d.ts +32 -0
  9. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.d.ts.map +1 -0
  10. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.js +99 -0
  11. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.js.map +1 -0
  12. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +1 -1
  13. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  14. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts +0 -7
  15. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts.map +1 -1
  16. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js +20 -77
  17. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js.map +1 -1
  18. package/lib/components/editor/side-bar/Explorer.js +3 -3
  19. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  20. package/lib/components/editor/side-bar/WorkflowManager.d.ts.map +1 -1
  21. package/lib/components/editor/side-bar/WorkflowManager.js +6 -1
  22. package/lib/components/editor/side-bar/WorkflowManager.js.map +1 -1
  23. package/lib/index.css +2 -2
  24. package/lib/index.css.map +1 -1
  25. package/lib/package.json +3 -3
  26. package/lib/stores/editor/ExplorerTreeState.d.ts +4 -4
  27. package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
  28. package/lib/stores/editor/ExplorerTreeState.js +4 -4
  29. package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
  30. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +12 -12
  31. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
  32. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +45 -46
  33. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
  34. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +20 -29
  35. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts.map +1 -1
  36. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js +60 -141
  37. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
  38. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts +33 -0
  39. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts.map +1 -0
  40. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +71 -0
  41. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js.map +1 -0
  42. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts +3 -48
  43. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts.map +1 -1
  44. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js +12 -350
  45. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js.map +1 -1
  46. package/lib/stores/editor/sidebar-state/WorkflowManagerState.d.ts +5 -0
  47. package/lib/stores/editor/sidebar-state/WorkflowManagerState.d.ts.map +1 -1
  48. package/lib/stores/editor/sidebar-state/WorkflowManagerState.js +26 -0
  49. package/lib/stores/editor/sidebar-state/WorkflowManagerState.js.map +1 -1
  50. package/package.json +9 -9
  51. package/src/components/editor/editor-group/FunctionEditor.tsx +133 -118
  52. package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +191 -0
  53. package/src/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.tsx +227 -0
  54. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +1 -1
  55. package/src/components/editor/panel-group/SQLPlaygroundPanel.tsx +47 -211
  56. package/src/components/editor/side-bar/Explorer.tsx +3 -3
  57. package/src/components/editor/side-bar/WorkflowManager.tsx +10 -0
  58. package/src/stores/editor/ExplorerTreeState.ts +6 -9
  59. package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +44 -50
  60. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +88 -212
  61. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts +102 -0
  62. package/src/stores/editor/panel-group/SQLPlaygroundPanelState.ts +13 -533
  63. package/src/stores/editor/sidebar-state/WorkflowManagerState.ts +47 -0
  64. package/tsconfig.json +3 -1
  65. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.d.ts.map +0 -1
  66. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js +0 -133
  67. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js.map +0 -1
  68. package/src/components/editor/editor-group/connection-editor/DatabaseBuilder.tsx +0 -397
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { observer } from 'mobx-react-lite';
18
+ import {
19
+ Dialog,
20
+ ResizablePanelGroup,
21
+ ResizablePanel,
22
+ ResizablePanelSplitter,
23
+ PanelLoadingIndicator,
24
+ PanelContent,
25
+ Modal,
26
+ ModalHeader,
27
+ ModalBody,
28
+ ModalFooter,
29
+ ModalTitle,
30
+ ModalHeaderActions,
31
+ TimesIcon,
32
+ ModalFooterButton,
33
+ BlankPanelContent,
34
+ PanelHeader,
35
+ Panel,
36
+ } from '@finos/legend-art';
37
+ import { useEffect } from 'react';
38
+ import { noop } from '@finos/legend-shared';
39
+ import {
40
+ useApplicationStore,
41
+ useConditionedApplicationNavigationContext,
42
+ } from '@finos/legend-application';
43
+ import { flowResult } from 'mobx';
44
+ import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
45
+ import {
46
+ CODE_EDITOR_LANGUAGE,
47
+ CodeEditor,
48
+ } from '@finos/legend-lego/code-editor';
49
+ import type { DatabaseBuilderWizardState } from '../../../../stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js';
50
+ import { DatabaseSchemaExplorer } from './DatabaseSchemaExplorer.js';
51
+
52
+ export const DatabaseBuilderWizard = observer(
53
+ (props: {
54
+ databaseBuilderState: DatabaseBuilderWizardState;
55
+ isReadOnly: boolean;
56
+ }) => {
57
+ const { databaseBuilderState, isReadOnly } = props;
58
+ const schemaExplorerState = databaseBuilderState.schemaExplorerState;
59
+ const applicationStore = useApplicationStore();
60
+ const preview = applicationStore.guardUnhandledError(() =>
61
+ flowResult(databaseBuilderState.previewDatabaseModel()),
62
+ );
63
+ const updateDatabase = applicationStore.guardUnhandledError(() =>
64
+ flowResult(databaseBuilderState.updateDatabase()),
65
+ );
66
+ const closeModal = (): void => {
67
+ databaseBuilderState.setShowModal(false);
68
+ databaseBuilderState.editorStore.explorerTreeState.setDatabaseBuilderState(
69
+ undefined,
70
+ );
71
+ };
72
+ const isExecutingAction =
73
+ schemaExplorerState.isGeneratingDatabase ||
74
+ schemaExplorerState.isUpdatingDatabase;
75
+
76
+ useEffect(() => {
77
+ flowResult(schemaExplorerState.fetchDatabaseMetadata()).catch(
78
+ applicationStore.alertUnhandledError,
79
+ );
80
+ }, [applicationStore, schemaExplorerState]);
81
+
82
+ useConditionedApplicationNavigationContext(
83
+ LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_BUILDER,
84
+ databaseBuilderState.showModal,
85
+ );
86
+
87
+ return (
88
+ <Dialog
89
+ open={databaseBuilderState.showModal}
90
+ onClose={noop} // disallow closing dialog by using Esc key or clicking on the backdrop
91
+ classes={{ container: 'search-modal__container' }}
92
+ PaperProps={{
93
+ classes: {
94
+ root: 'search-modal__inner-container database-builder__container',
95
+ },
96
+ }}
97
+ >
98
+ <Modal darkMode={true} className="database-builder">
99
+ <ModalHeader>
100
+ <ModalTitle title="Database Builder" />
101
+ <ModalHeaderActions>
102
+ <button
103
+ className="modal__header__action"
104
+ tabIndex={-1}
105
+ onClick={closeModal}
106
+ >
107
+ <TimesIcon />
108
+ </button>
109
+ </ModalHeaderActions>
110
+ </ModalHeader>
111
+ <ModalBody className="database-builder__content">
112
+ <PanelLoadingIndicator isLoading={isExecutingAction} />
113
+ <ResizablePanelGroup orientation="vertical">
114
+ <ResizablePanel size={450}>
115
+ <div className="database-builder__config">
116
+ <PanelHeader title="schema explorer" />
117
+ <PanelContent className="database-builder__config__content">
118
+ {schemaExplorerState.treeData && (
119
+ <DatabaseSchemaExplorer
120
+ treeData={schemaExplorerState.treeData}
121
+ isReadOnly={false}
122
+ schemaExplorerState={
123
+ databaseBuilderState.schemaExplorerState
124
+ }
125
+ />
126
+ )}
127
+ </PanelContent>
128
+ </div>
129
+ </ResizablePanel>
130
+ <ResizablePanelSplitter />
131
+ <ResizablePanel>
132
+ <Panel className="database-builder__model">
133
+ <PanelHeader title="database model" />
134
+
135
+ <PanelContent>
136
+ <div className="database-builder__modeller">
137
+ <div className="panel__content__form__section database-builder__modeller__path">
138
+ <div className="panel__content__form__section__header__label">
139
+ Target Database Path
140
+ </div>
141
+ <input
142
+ className="panel__content__form__section__input"
143
+ spellCheck={false}
144
+ disabled={true}
145
+ value={schemaExplorerState.database.path}
146
+ />
147
+ </div>
148
+ <div className="database-builder__modeller__preview">
149
+ {databaseBuilderState.databaseGrammarCode && (
150
+ <CodeEditor
151
+ language={CODE_EDITOR_LANGUAGE.PURE}
152
+ inputValue={
153
+ databaseBuilderState.databaseGrammarCode
154
+ }
155
+ isReadOnly={true}
156
+ />
157
+ )}
158
+ {!databaseBuilderState.databaseGrammarCode && (
159
+ <BlankPanelContent>
160
+ No database preview
161
+ </BlankPanelContent>
162
+ )}
163
+ </div>
164
+ </div>
165
+ </PanelContent>
166
+ </Panel>
167
+ </ResizablePanel>
168
+ </ResizablePanelGroup>
169
+ </ModalBody>
170
+ <ModalFooter>
171
+ <ModalFooterButton
172
+ className="database-builder__action--btn"
173
+ disabled={isReadOnly || isExecutingAction}
174
+ onClick={preview}
175
+ title="Preview database model..."
176
+ >
177
+ Preview
178
+ </ModalFooterButton>
179
+ <ModalFooterButton
180
+ className="database-builder__action--btn"
181
+ disabled={isReadOnly || isExecutingAction}
182
+ onClick={updateDatabase}
183
+ >
184
+ Update Database
185
+ </ModalFooterButton>
186
+ </ModalFooter>
187
+ </Modal>
188
+ </Dialog>
189
+ );
190
+ },
191
+ );
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { observer } from 'mobx-react-lite';
18
+ import {
19
+ type TreeNodeContainerProps,
20
+ TreeView,
21
+ PURE_DatabaseSchemaIcon,
22
+ PURE_DatabaseTableIcon,
23
+ CircleIcon,
24
+ ChevronDownIcon,
25
+ ChevronRightIcon,
26
+ CheckCircleIcon,
27
+ EmptyCircleIcon,
28
+ KeyIcon,
29
+ } from '@finos/legend-art';
30
+ import {
31
+ type DatabaseExplorerTreeData,
32
+ type DatabaseSchemaExplorerTreeNodeData,
33
+ DatabaseSchemaExplorerTreeColumnNodeData,
34
+ DatabaseSchemaExplorerTreeSchemaNodeData,
35
+ DatabaseSchemaExplorerTreeTableNodeData,
36
+ type DatabaseSchemaExplorerState,
37
+ } from '../../../../stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js';
38
+ import { useApplicationStore } from '@finos/legend-application';
39
+ import { renderColumnTypeIcon } from './DatabaseEditorHelper.js';
40
+ import { flowResult } from 'mobx';
41
+ import { stringifyDataType } from '@finos/legend-graph';
42
+ import { forwardRef } from 'react';
43
+
44
+ const getDatabaseSchemaNodeIcon = (
45
+ node: DatabaseSchemaExplorerTreeNodeData,
46
+ ): React.ReactNode => {
47
+ if (node instanceof DatabaseSchemaExplorerTreeSchemaNodeData) {
48
+ return (
49
+ <div className="database-schema-explorer__icon--schema">
50
+ <PURE_DatabaseSchemaIcon />
51
+ </div>
52
+ );
53
+ } else if (node instanceof DatabaseSchemaExplorerTreeTableNodeData) {
54
+ return (
55
+ <div className="database-schema-explorer__icon--table">
56
+ <PURE_DatabaseTableIcon />
57
+ </div>
58
+ );
59
+ } else if (node instanceof DatabaseSchemaExplorerTreeColumnNodeData) {
60
+ return renderColumnTypeIcon(node.column.type);
61
+ }
62
+ return null;
63
+ };
64
+
65
+ export type DatabaseSchemaExplorerTreeNodeContainerProps =
66
+ TreeNodeContainerProps<
67
+ DatabaseSchemaExplorerTreeNodeData,
68
+ {
69
+ toggleCheckedNode: (node: DatabaseSchemaExplorerTreeNodeData) => void;
70
+ isPartiallySelected: (
71
+ node: DatabaseSchemaExplorerTreeNodeData,
72
+ ) => boolean;
73
+ }
74
+ >;
75
+
76
+ export const DatabaseSchemaExplorerTreeNodeContainer = observer(
77
+ forwardRef<HTMLDivElement, DatabaseSchemaExplorerTreeNodeContainerProps>(
78
+ function DatabaseSchemaExplorerTreeNodeContainer(props, ref) {
79
+ const { node, level, stepPaddingInRem, onNodeSelect, innerProps } = props;
80
+ const { toggleCheckedNode, isPartiallySelected } = innerProps;
81
+ const isExpandable =
82
+ Boolean(!node.childrenIds || node.childrenIds.length) &&
83
+ !(node instanceof DatabaseSchemaExplorerTreeColumnNodeData);
84
+ const nodeExpandIcon = isExpandable ? (
85
+ node.isOpen ? (
86
+ <ChevronDownIcon />
87
+ ) : (
88
+ <ChevronRightIcon />
89
+ )
90
+ ) : (
91
+ <div />
92
+ );
93
+ const nodeTypeIcon = getDatabaseSchemaNodeIcon(node);
94
+ const toggleExpandNode = (): void => {
95
+ onNodeSelect?.(node);
96
+ if (!isExpandable) {
97
+ toggleCheckedNode(node);
98
+ }
99
+ };
100
+ const isPrimaryKeyColumn =
101
+ node instanceof DatabaseSchemaExplorerTreeColumnNodeData &&
102
+ node.owner.primaryKey.includes(node.column);
103
+
104
+ const renderCheckedIcon = (
105
+ _node: DatabaseSchemaExplorerTreeNodeData,
106
+ ): React.ReactNode => {
107
+ if (_node instanceof DatabaseSchemaExplorerTreeColumnNodeData) {
108
+ return null;
109
+ } else if (isPartiallySelected(_node)) {
110
+ return <CircleIcon />;
111
+ } else if (_node.isChecked) {
112
+ return <CheckCircleIcon />;
113
+ }
114
+ return <EmptyCircleIcon />;
115
+ };
116
+
117
+ return (
118
+ <div
119
+ className="tree-view__node__container"
120
+ ref={ref}
121
+ style={{
122
+ paddingLeft: `${level * (stepPaddingInRem ?? 1)}rem`,
123
+ display: 'flex',
124
+ }}
125
+ onClick={toggleExpandNode}
126
+ >
127
+ <div className="tree-view__node__icon database-schema-explorer__node__icon__group">
128
+ <div className="database-schema-explorer__expand-icon">
129
+ {nodeExpandIcon}
130
+ </div>
131
+ <div
132
+ className="database-schema-explorer__checker-icon"
133
+ onClick={(event) => {
134
+ event.stopPropagation();
135
+ toggleCheckedNode(node);
136
+ }}
137
+ >
138
+ {renderCheckedIcon(node)}
139
+ </div>
140
+ <div className="database-schema-explorer__type-icon">
141
+ {nodeTypeIcon}
142
+ </div>
143
+ </div>
144
+ <div className="tree-view__node__label database-schema-explorer__node__label">
145
+ {node.label}
146
+ {node instanceof DatabaseSchemaExplorerTreeColumnNodeData && (
147
+ <div className="database-schema-explorer__node__type">
148
+ <div className="database-schema-explorer__node__type__label">
149
+ {stringifyDataType(node.column.type)}
150
+ </div>
151
+ </div>
152
+ )}
153
+ {isPrimaryKeyColumn && (
154
+ <div
155
+ className="database-schema-explorer__node__pk"
156
+ title="Primary Key"
157
+ >
158
+ <KeyIcon />
159
+ </div>
160
+ )}
161
+ </div>
162
+ </div>
163
+ );
164
+ },
165
+ ),
166
+ );
167
+
168
+ export const DatabaseSchemaExplorer = observer(
169
+ (props: {
170
+ schemaExplorerState: DatabaseSchemaExplorerState;
171
+ treeData: DatabaseExplorerTreeData;
172
+ isReadOnly?: boolean | undefined;
173
+ treeNodeContainerComponent?:
174
+ | React.FC<DatabaseSchemaExplorerTreeNodeContainerProps>
175
+ | undefined;
176
+ }) => {
177
+ const { treeData, schemaExplorerState, treeNodeContainerComponent } = props;
178
+ const applicationStore = useApplicationStore();
179
+ const onNodeSelect = (node: DatabaseSchemaExplorerTreeNodeData): void => {
180
+ flowResult(schemaExplorerState.onNodeSelect(node, treeData)).catch(
181
+ applicationStore.alertUnhandledError,
182
+ );
183
+ };
184
+ const getChildNodes = (
185
+ node: DatabaseSchemaExplorerTreeNodeData,
186
+ ): DatabaseSchemaExplorerTreeNodeData[] =>
187
+ schemaExplorerState
188
+ .getChildNodes(node, treeData)
189
+ ?.sort((a, b) => a.label.localeCompare(b.label)) ?? [];
190
+ const isPartiallySelected = (
191
+ node: DatabaseSchemaExplorerTreeNodeData,
192
+ ): boolean => {
193
+ if (
194
+ node instanceof DatabaseSchemaExplorerTreeSchemaNodeData &&
195
+ !node.isChecked
196
+ ) {
197
+ return Boolean(
198
+ schemaExplorerState
199
+ .getChildNodes(node, treeData)
200
+ ?.find((childNode) => childNode.isChecked === true),
201
+ );
202
+ }
203
+ return false;
204
+ };
205
+ const toggleCheckedNode = (
206
+ node: DatabaseSchemaExplorerTreeNodeData,
207
+ ): void => schemaExplorerState.toggleCheckedNode(node, treeData);
208
+
209
+ return (
210
+ <TreeView
211
+ className="database-schema-explorer"
212
+ components={{
213
+ TreeNodeContainer:
214
+ treeNodeContainerComponent ??
215
+ DatabaseSchemaExplorerTreeNodeContainer,
216
+ }}
217
+ innerProps={{
218
+ toggleCheckedNode,
219
+ isPartiallySelected,
220
+ }}
221
+ treeData={treeData}
222
+ onNodeSelect={onNodeSelect}
223
+ getChildNodes={getChildNodes}
224
+ />
225
+ );
226
+ },
227
+ );
@@ -1109,7 +1109,7 @@ const RelationalConnectionStoreEditor = observer(
1109
1109
  }
1110
1110
  };
1111
1111
  const openDatabaseBuilder = (): void =>
1112
- connectionValueState.editorStore.explorerTreeState.buildDbBuilderState(
1112
+ connectionValueState.editorStore.explorerTreeState.buildDatabase(
1113
1113
  connection,
1114
1114
  isReadOnly,
1115
1115
  );