@finos/legend-application-studio 28.20.0 → 28.21.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 (61) hide show
  1. package/lib/__lib__/LegendStudioUserDataHelper.d.ts +4 -1
  2. package/lib/__lib__/LegendStudioUserDataHelper.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioUserDataHelper.js +18 -0
  4. package/lib/__lib__/LegendStudioUserDataHelper.js.map +1 -1
  5. package/lib/components/editor/editor-group/EditorGroup.d.ts.map +1 -1
  6. package/lib/components/editor/editor-group/EditorGroup.js +5 -0
  7. package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
  8. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
  9. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +13 -44
  10. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
  11. package/lib/components/editor/editor-group/database-editor/DatabaseAnnotationDisplay.d.ts +26 -0
  12. package/lib/components/editor/editor-group/database-editor/DatabaseAnnotationDisplay.d.ts.map +1 -0
  13. package/lib/components/editor/editor-group/database-editor/DatabaseAnnotationDisplay.js +101 -0
  14. package/lib/components/editor/editor-group/database-editor/DatabaseAnnotationDisplay.js.map +1 -0
  15. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.d.ts +23 -0
  16. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.d.ts.map +1 -0
  17. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.js +434 -0
  18. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.js.map +1 -0
  19. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramHelper.d.ts +242 -0
  20. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramHelper.d.ts.map +1 -0
  21. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramHelper.js +371 -0
  22. package/lib/components/editor/editor-group/database-editor/DatabaseDiagramHelper.js.map +1 -0
  23. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.d.ts +29 -0
  24. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.d.ts.map +1 -0
  25. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.js +78 -0
  26. package/lib/components/editor/editor-group/database-editor/DatabaseEditor.js.map +1 -0
  27. package/lib/components/editor/editor-group/database-editor/DatabaseSchemaTree.d.ts +30 -0
  28. package/lib/components/editor/editor-group/database-editor/DatabaseSchemaTree.d.ts.map +1 -0
  29. package/lib/components/editor/editor-group/database-editor/DatabaseSchemaTree.js +331 -0
  30. package/lib/components/editor/editor-group/database-editor/DatabaseSchemaTree.js.map +1 -0
  31. package/lib/components/editor/editor-group/database-editor/DatabaseTableNode.d.ts +104 -0
  32. package/lib/components/editor/editor-group/database-editor/DatabaseTableNode.d.ts.map +1 -0
  33. package/lib/components/editor/editor-group/database-editor/DatabaseTableNode.js +151 -0
  34. package/lib/components/editor/editor-group/database-editor/DatabaseTableNode.js.map +1 -0
  35. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -1
  36. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +3 -78
  37. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -1
  38. package/lib/index.css +2 -2
  39. package/lib/index.css.map +1 -1
  40. package/lib/package.json +4 -1
  41. package/lib/stores/editor/EditorTabManagerState.d.ts.map +1 -1
  42. package/lib/stores/editor/EditorTabManagerState.js +5 -3
  43. package/lib/stores/editor/EditorTabManagerState.js.map +1 -1
  44. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.d.ts +252 -0
  45. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.d.ts.map +1 -0
  46. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.js +755 -0
  47. package/lib/stores/editor/editor-state/element-editor-state/DatabaseEditorState.js.map +1 -0
  48. package/package.json +12 -9
  49. package/src/__lib__/LegendStudioUserDataHelper.ts +30 -0
  50. package/src/components/editor/editor-group/EditorGroup.tsx +4 -0
  51. package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +0 -52
  52. package/src/components/editor/editor-group/database-editor/DatabaseAnnotationDisplay.tsx +200 -0
  53. package/src/components/editor/editor-group/database-editor/DatabaseDiagramCanvas.tsx +701 -0
  54. package/src/components/editor/editor-group/database-editor/DatabaseDiagramHelper.ts +555 -0
  55. package/src/components/editor/editor-group/database-editor/DatabaseEditor.tsx +246 -0
  56. package/src/components/editor/editor-group/database-editor/DatabaseSchemaTree.tsx +1053 -0
  57. package/src/components/editor/editor-group/database-editor/DatabaseTableNode.tsx +465 -0
  58. package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +2 -242
  59. package/src/stores/editor/EditorTabManagerState.ts +4 -5
  60. package/src/stores/editor/editor-state/element-editor-state/DatabaseEditorState.ts +938 -0
  61. package/tsconfig.json +7 -0
@@ -0,0 +1,246 @@
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
+ ChevronLeftIcon,
20
+ ChevronRightIcon,
21
+ InfoCircleIcon,
22
+ LockIcon,
23
+ MoonIcon,
24
+ ResizablePanel,
25
+ ResizablePanelGroup,
26
+ ResizablePanelSplitter,
27
+ ResizablePanelSplitterLine,
28
+ SunIcon,
29
+ clsx,
30
+ getCollapsiblePanelGroupProps,
31
+ } from '@finos/legend-art';
32
+ import { prettyCONSTName } from '@finos/legend-shared';
33
+ import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
34
+ import { CodeEditor } from '@finos/legend-lego/code-editor';
35
+ import { INTERNAL__LakehouseGeneratedDatabase } from '@finos/legend-graph';
36
+ import { useEditorStore } from '../../EditorStoreProvider.js';
37
+ import {
38
+ DATABASE_EDITOR_TAB,
39
+ DatabaseEditorState,
40
+ } from '../../../../stores/editor/editor-state/element-editor-state/DatabaseEditorState.js';
41
+ import { DatabaseDiagramCanvas } from './DatabaseDiagramCanvas.js';
42
+ import { DatabaseSchemaTree } from './DatabaseSchemaTree.js';
43
+
44
+ const TABS: DATABASE_EDITOR_TAB[] = [
45
+ DATABASE_EDITOR_TAB.VIEW,
46
+ DATABASE_EDITOR_TAB.GRAMMAR,
47
+ ];
48
+
49
+ /**
50
+ * Top-level editor for `Database` elements in form mode. Has two tabs:
51
+ * - VIEW (default): Schema → Table → Column tree (left) + React-Flow ERD
52
+ * canvas (right). The interactive form mode.
53
+ * - GRAMMAR: read-only Pure DSL preview, regenerated on tab switch by
54
+ * `setSelectedTab` so it always reflects the current metamodel state.
55
+ * Mirrors what global Text Mode would render for this element — included
56
+ * here for users who want to peek at the grammar without leaving form
57
+ * mode.
58
+ */
59
+ export const DatabaseEditor = observer(() => {
60
+ const editorStore = useEditorStore();
61
+ const editorState =
62
+ editorStore.tabManagerState.getCurrentEditorState(DatabaseEditorState);
63
+ const { selectedTab, database } = editorState;
64
+
65
+ // Resizable left panel: dragging the splitter all the way left snaps the
66
+ // panel to flex=0 (collapsed). The toggle button in the panel header (and
67
+ // the expand-rail rendered when collapsed) drives the same flag, so both
68
+ // controls stay in sync via `editorState.isSidePanelCollapsed`.
69
+ const sidePanelCollapseProps = getCollapsiblePanelGroupProps(
70
+ editorState.isSidePanelCollapsed,
71
+ {
72
+ // Default width when first opened (in pixels). React-reflex owns the
73
+ // exact width after the first user-drag.
74
+ size: 320,
75
+ onStopResize: (handleProps) => {
76
+ // If the user drags the splitter to (or near) zero, persist it as
77
+ // collapsed so the toggle button and rail stay in sync. Mirrors
78
+ // what `getCollapsiblePanelGroupProps` does internally for the
79
+ // styling class but lifts that signal back up to MobX.
80
+ const flexGrow = Number(
81
+ (handleProps.domElement as HTMLDivElement).style.flexGrow,
82
+ );
83
+ if (flexGrow <= 0.01) {
84
+ editorState.setSidePanelCollapsed(true);
85
+ } else if (editorState.isSidePanelCollapsed) {
86
+ editorState.setSidePanelCollapsed(false);
87
+ }
88
+ },
89
+ },
90
+ );
91
+
92
+ return (
93
+ <div
94
+ className={clsx('database-editor', {
95
+ // Local light-theme opt-in. Scoped to this editor only — the rest
96
+ // of Studio remains in its configured theme. SCSS overrides hang
97
+ // off this modifier class.
98
+ 'database-editor--light': editorState.theme === 'light',
99
+ })}
100
+ >
101
+ <div className="database-editor__tabs__header">
102
+ <div className="database-editor__tabs">
103
+ {TABS.map((tab) => (
104
+ <button
105
+ key={tab}
106
+ type="button"
107
+ onClick={() => editorState.setSelectedTab(tab)}
108
+ className={clsx('database-editor__tab', {
109
+ 'database-editor__tab--active': tab === selectedTab,
110
+ })}
111
+ >
112
+ {prettyCONSTName(tab)}
113
+ </button>
114
+ ))}
115
+ </div>
116
+ {/*
117
+ * Read-only sticker is part of the tab strip — visible across both
118
+ * VIEW and GRAMMAR tabs because the whole form mode is currently
119
+ * read-only. Once edit support lands, the sticker can be hidden
120
+ * conditionally on `editorState.isReadOnly` (or removed entirely).
121
+ */}
122
+ <div
123
+ className="database-editor__read-only-badge"
124
+ title="This editor is read-only"
125
+ >
126
+ <LockIcon />
127
+ <span className="database-editor__read-only-badge__label">
128
+ READ ONLY
129
+ </span>
130
+ </div>
131
+ {/*
132
+ * Light/dark theme toggle. Scoped to this editor only — see
133
+ * `DatabaseEditorState.toggleTheme`. Icon switches to surface the
134
+ * mode the user would jump TO if they clicked (current=dark shows
135
+ * a sun, current=light shows a moon).
136
+ */}
137
+ <button
138
+ type="button"
139
+ className="database-editor__theme-toggle"
140
+ onClick={() => editorState.toggleTheme()}
141
+ title={
142
+ editorState.theme === 'dark'
143
+ ? 'Switch to light theme (this editor only)'
144
+ : 'Switch to dark theme'
145
+ }
146
+ >
147
+ {editorState.theme === 'dark' ? <SunIcon /> : <MoonIcon />}
148
+ </button>
149
+ </div>
150
+ <div className="database-editor__content">
151
+ {database instanceof INTERNAL__LakehouseGeneratedDatabase && (
152
+ <div
153
+ className="database-editor__generated-banner"
154
+ title={`Generated from ${database.generatorElement.path}\nOwned by ${database.OWNER.path}`}
155
+ >
156
+ <InfoCircleIcon />
157
+ <span className="database-editor__generated-banner__text">
158
+ This database is generated by{' '}
159
+ <span className="database-editor__generated-banner__path">
160
+ {database.generatorElement.path}
161
+ </span>
162
+ {' — owned by '}
163
+ <span className="database-editor__generated-banner__path">
164
+ {database.OWNER.path}
165
+ </span>
166
+ .
167
+ </span>
168
+ </div>
169
+ )}
170
+ <div className="database-editor__content__body">
171
+ {selectedTab === DATABASE_EDITOR_TAB.VIEW && (
172
+ <div className="database-diagram">
173
+ {/*
174
+ * The schema tree (left) and ERD canvas (right) are split by
175
+ * a draggable splitter. Drag-to-resize is the primary control;
176
+ * the small toggle button in the panel header (and the
177
+ * "expand" rail rendered when collapsed) lets users snap the
178
+ * panel fully closed/open without dragging. The collapsed
179
+ * state lives on the editor state so it survives tab
180
+ * switches and recompiles.
181
+ */}
182
+ <ResizablePanelGroup orientation="vertical">
183
+ <ResizablePanel
184
+ {...sidePanelCollapseProps.collapsiblePanel}
185
+ direction={1}
186
+ minSize={0}
187
+ >
188
+ <div className="database-diagram__side-panel-wrapper">
189
+ <div className="database-diagram__side-panel-wrapper__header">
190
+ <span className="database-diagram__side-panel-wrapper__header__title">
191
+ Database
192
+ </span>
193
+ <button
194
+ type="button"
195
+ className="database-diagram__side-panel-wrapper__header__action"
196
+ onClick={() => editorState.toggleSidePanelCollapsed()}
197
+ title="Collapse panel"
198
+ >
199
+ <ChevronLeftIcon />
200
+ </button>
201
+ </div>
202
+ <div className="database-diagram__side-panel-wrapper__body">
203
+ <DatabaseSchemaTree editorState={editorState} />
204
+ </div>
205
+ </div>
206
+ </ResizablePanel>
207
+ <ResizablePanelSplitter>
208
+ <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
209
+ </ResizablePanelSplitter>
210
+ <ResizablePanel
211
+ {...sidePanelCollapseProps.remainingPanel}
212
+ minSize={200}
213
+ >
214
+ <div className="database-diagram__canvas-area">
215
+ {editorState.isSidePanelCollapsed && (
216
+ <button
217
+ type="button"
218
+ className="database-diagram__expand-rail"
219
+ onClick={() => editorState.toggleSidePanelCollapsed()}
220
+ title="Expand panel"
221
+ >
222
+ <ChevronRightIcon />
223
+ </button>
224
+ )}
225
+ <div className="database-diagram__canvas-container">
226
+ <DatabaseDiagramCanvas editorState={editorState} />
227
+ </div>
228
+ </div>
229
+ </ResizablePanel>
230
+ </ResizablePanelGroup>
231
+ </div>
232
+ )}
233
+ {selectedTab === DATABASE_EDITOR_TAB.GRAMMAR && (
234
+ <div className="database-editor__grammar">
235
+ <CodeEditor
236
+ inputValue={editorState.textContent}
237
+ isReadOnly={true}
238
+ language={CODE_EDITOR_LANGUAGE.PURE}
239
+ />
240
+ </div>
241
+ )}
242
+ </div>
243
+ </div>
244
+ </div>
245
+ );
246
+ });