@finos/legend-application-studio 28.8.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 (170) 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/__lib__/LegendStudioNavigation.d.ts +6 -0
  6. package/lib/__lib__/LegendStudioNavigation.d.ts.map +1 -1
  7. package/lib/__lib__/LegendStudioNavigation.js +5 -0
  8. package/lib/__lib__/LegendStudioNavigation.js.map +1 -1
  9. package/lib/components/LegendStudioWebApplication.d.ts.map +1 -1
  10. package/lib/components/LegendStudioWebApplication.js +4 -1
  11. package/lib/components/LegendStudioWebApplication.js.map +1 -1
  12. package/lib/components/ShowcaseManager.d.ts.map +1 -1
  13. package/lib/components/ShowcaseManager.js +10 -2
  14. package/lib/components/ShowcaseManager.js.map +1 -1
  15. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  16. package/lib/components/editor/ActivityBar.js +20 -17
  17. package/lib/components/editor/ActivityBar.js.map +1 -1
  18. package/lib/components/editor/editor-group/EditorGroup.d.ts.map +1 -1
  19. package/lib/components/editor/editor-group/EditorGroup.js +7 -1
  20. package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
  21. package/lib/components/editor/editor-group/GrammarTextEditor.js +1 -1
  22. package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
  23. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts +5 -0
  24. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -1
  25. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +28 -10
  26. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -1
  27. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts +11 -0
  28. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.d.ts.map +1 -1
  29. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js +22 -10
  30. package/lib/components/editor/editor-group/connection-editor/DatabaseModelBuilder.js.map +1 -1
  31. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts +7 -0
  32. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
  33. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +3 -3
  34. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  35. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts +59 -0
  36. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.d.ts.map +1 -0
  37. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js +145 -0
  38. package/lib/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.js.map +1 -0
  39. package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
  40. package/lib/components/editor/side-bar/Explorer.js +3 -2
  41. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  42. package/lib/components/editor/side-bar/SideBar.d.ts.map +1 -1
  43. package/lib/components/editor/side-bar/SideBar.js +4 -1
  44. package/lib/components/editor/side-bar/SideBar.js.map +1 -1
  45. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts +23 -0
  46. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.d.ts.map +1 -0
  47. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js +41 -0
  48. package/lib/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.js.map +1 -0
  49. package/lib/components/project-view/ProjectViewer.d.ts.map +1 -1
  50. package/lib/components/project-view/ProjectViewer.js +37 -5
  51. package/lib/components/project-view/ProjectViewer.js.map +1 -1
  52. package/lib/components/showcase/ShowcaseViewer.d.ts +18 -0
  53. package/lib/components/showcase/ShowcaseViewer.d.ts.map +1 -0
  54. package/lib/components/showcase/ShowcaseViewer.js +147 -0
  55. package/lib/components/showcase/ShowcaseViewer.js.map +1 -0
  56. package/lib/components/showcase/ShowcaseViewerStoreProvider.d.ts +23 -0
  57. package/lib/components/showcase/ShowcaseViewerStoreProvider.d.ts.map +1 -0
  58. package/lib/components/showcase/ShowcaseViewerStoreProvider.js +36 -0
  59. package/lib/components/showcase/ShowcaseViewerStoreProvider.js.map +1 -0
  60. package/lib/index.css +2 -2
  61. package/lib/index.css.map +1 -1
  62. package/lib/package.json +1 -1
  63. package/lib/stores/LegendStudioBaseStore.d.ts.map +1 -1
  64. package/lib/stores/LegendStudioBaseStore.js +1 -0
  65. package/lib/stores/LegendStudioBaseStore.js.map +1 -1
  66. package/lib/stores/ShowcaseManagerState.d.ts +1 -0
  67. package/lib/stores/ShowcaseManagerState.d.ts.map +1 -1
  68. package/lib/stores/ShowcaseManagerState.js +11 -1
  69. package/lib/stores/ShowcaseManagerState.js.map +1 -1
  70. package/lib/stores/editor/EditorConfig.d.ts +3 -1
  71. package/lib/stores/editor/EditorConfig.d.ts.map +1 -1
  72. package/lib/stores/editor/EditorConfig.js +4 -1
  73. package/lib/stores/editor/EditorConfig.js.map +1 -1
  74. package/lib/stores/editor/EditorMode.d.ts +4 -0
  75. package/lib/stores/editor/EditorMode.d.ts.map +1 -1
  76. package/lib/stores/editor/EditorMode.js +9 -0
  77. package/lib/stores/editor/EditorMode.js.map +1 -1
  78. package/lib/stores/editor/EditorStore.d.ts +2 -0
  79. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  80. package/lib/stores/editor/EditorStore.js +14 -3
  81. package/lib/stores/editor/EditorStore.js.map +1 -1
  82. package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
  83. package/lib/stores/editor/ExplorerTreeState.js +1 -1
  84. package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
  85. package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
  86. package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
  87. package/lib/stores/editor/NewElementState.d.ts +1 -0
  88. package/lib/stores/editor/NewElementState.d.ts.map +1 -1
  89. package/lib/stores/editor/NewElementState.js +1 -1
  90. package/lib/stores/editor/NewElementState.js.map +1 -1
  91. package/lib/stores/editor/StandardEditorMode.d.ts +1 -0
  92. package/lib/stores/editor/StandardEditorMode.d.ts.map +1 -1
  93. package/lib/stores/editor/StandardEditorMode.js +4 -0
  94. package/lib/stores/editor/StandardEditorMode.js.map +1 -1
  95. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +6 -2
  96. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts.map +1 -1
  97. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js +53 -34
  98. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
  99. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts.map +1 -1
  100. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +1 -1
  101. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js.map +1 -1
  102. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts +3 -2
  103. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.d.ts.map +1 -1
  104. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js +8 -5
  105. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.js.map +1 -1
  106. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts.map +1 -1
  107. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js +20 -4
  108. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js.map +1 -1
  109. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.d.ts +3 -0
  110. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.d.ts.map +1 -1
  111. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.js +17 -2
  112. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.js.map +1 -1
  113. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts +22 -0
  114. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.d.ts.map +1 -0
  115. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js +25 -0
  116. package/lib/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.js.map +1 -0
  117. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts +113 -0
  118. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.d.ts.map +1 -0
  119. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js +494 -0
  120. package/lib/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.js.map +1 -0
  121. package/lib/stores/project-view/ProjectViewerEditorMode.d.ts +3 -0
  122. package/lib/stores/project-view/ProjectViewerEditorMode.d.ts.map +1 -1
  123. package/lib/stores/project-view/ProjectViewerEditorMode.js +10 -0
  124. package/lib/stores/project-view/ProjectViewerEditorMode.js.map +1 -1
  125. package/lib/stores/showcase/ShowcaseViewerEditorMode.d.ts +28 -0
  126. package/lib/stores/showcase/ShowcaseViewerEditorMode.d.ts.map +1 -0
  127. package/lib/stores/showcase/ShowcaseViewerEditorMode.js +40 -0
  128. package/lib/stores/showcase/ShowcaseViewerEditorMode.js.map +1 -0
  129. package/lib/stores/showcase/ShowcaseViewerStore.d.ts +32 -0
  130. package/lib/stores/showcase/ShowcaseViewerStore.d.ts.map +1 -0
  131. package/lib/stores/showcase/ShowcaseViewerStore.js +193 -0
  132. package/lib/stores/showcase/ShowcaseViewerStore.js.map +1 -0
  133. package/package.json +7 -7
  134. package/src/__lib__/LegendStudioCommand.ts +5 -0
  135. package/src/__lib__/LegendStudioNavigation.ts +11 -0
  136. package/src/components/LegendStudioWebApplication.tsx +11 -1
  137. package/src/components/ShowcaseManager.tsx +44 -2
  138. package/src/components/editor/ActivityBar.tsx +56 -15
  139. package/src/components/editor/editor-group/EditorGroup.tsx +21 -1
  140. package/src/components/editor/editor-group/GrammarTextEditor.tsx +1 -1
  141. package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +135 -103
  142. package/src/components/editor/editor-group/connection-editor/DatabaseModelBuilder.tsx +97 -53
  143. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +4 -3
  144. package/src/components/editor/editor-group/end-to-end-flow-editor/QueryConnectionWorkflowEditor.tsx +478 -0
  145. package/src/components/editor/side-bar/Explorer.tsx +20 -12
  146. package/src/components/editor/side-bar/SideBar.tsx +13 -1
  147. package/src/components/editor/side-bar/end-to-end-workflow/EndToEndWorkflows.tsx +101 -0
  148. package/src/components/project-view/ProjectViewer.tsx +139 -4
  149. package/src/components/showcase/ShowcaseViewer.tsx +418 -0
  150. package/src/components/showcase/ShowcaseViewerStoreProvider.tsx +56 -0
  151. package/src/stores/LegendStudioBaseStore.ts +1 -0
  152. package/src/stores/ShowcaseManagerState.ts +19 -1
  153. package/src/stores/editor/EditorConfig.ts +3 -0
  154. package/src/stores/editor/EditorMode.ts +14 -0
  155. package/src/stores/editor/EditorStore.ts +17 -8
  156. package/src/stores/editor/ExplorerTreeState.ts +1 -0
  157. package/src/stores/editor/GraphEditGrammarModeState.ts +3 -3
  158. package/src/stores/editor/NewElementState.ts +1 -1
  159. package/src/stores/editor/StandardEditorMode.ts +7 -0
  160. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +77 -49
  161. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts +1 -2
  162. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseModelBuilderState.ts +12 -8
  163. package/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts +31 -9
  164. package/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.ts +23 -0
  165. package/src/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.ts +25 -0
  166. package/src/stores/editor/sidebar-state/end-to-end-workflow/GlobalEndToEndFlowState.tsx +884 -0
  167. package/src/stores/project-view/ProjectViewerEditorMode.ts +17 -0
  168. package/src/stores/showcase/ShowcaseViewerEditorMode.ts +51 -0
  169. package/src/stores/showcase/ShowcaseViewerStore.ts +289 -0
  170. package/tsconfig.json +9 -1
@@ -37,6 +37,11 @@ import {
37
37
  FileTrayIcon,
38
38
  AssistantIcon,
39
39
  useResizeDetector,
40
+ FireIcon,
41
+ TrashIcon,
42
+ HammerIcon,
43
+ TerminalIcon,
44
+ ResizablePanelSplitterLine,
40
45
  } from '@finos/legend-art';
41
46
  import { isNonNullable } from '@finos/legend-shared';
42
47
  import {
@@ -65,6 +70,7 @@ import {
65
70
  import { EmbeddedQueryBuilder } from '../editor/EmbeddedQueryBuilder.js';
66
71
  import type { ActivityBarItemConfig } from '@finos/legend-lego/application';
67
72
  import { ActivityBarMenu } from '../editor/ActivityBar.js';
73
+ import { PanelGroup } from '../editor/panel-group/PanelGroup.js';
68
74
 
69
75
  const ProjectViewerStatusBar = observer(() => {
70
76
  const params = useParams<ProjectViewerPathParams>();
@@ -90,11 +96,26 @@ const ProjectViewerStatusBar = observer(() => {
90
96
  ? 'current'
91
97
  : ''
92
98
  }`;
99
+
100
+ const editable =
101
+ editorStore.graphManagerState.graphBuildState.hasCompleted &&
102
+ editorStore.isInitialized;
93
103
  const handleTextModeClick = applicationStore.guardUnhandledError(() =>
94
104
  flowResult(editorStore.toggleTextMode()),
95
105
  );
106
+ const compile = applicationStore.guardUnhandledError(() =>
107
+ flowResult(editorStore.graphEditorMode.globalCompile()),
108
+ );
109
+ const generate = applicationStore.guardUnhandledError(() =>
110
+ flowResult(editorStore.graphState.graphGenerationState.globalGenerate()),
111
+ );
112
+ const emptyGenerationEntities = applicationStore.guardUnhandledError(() =>
113
+ flowResult(editorStore.graphState.graphGenerationState.clearGenerations()),
114
+ );
115
+
96
116
  const toggleAssistant = (): void =>
97
117
  applicationStore.assistantService.toggleAssistant();
118
+ const togglePanel = (): void => editorStore.panelGroupDisplayState.toggle();
98
119
 
99
120
  return (
100
121
  <div
@@ -136,6 +157,76 @@ const ProjectViewerStatusBar = observer(() => {
136
157
  )}
137
158
  </div>
138
159
  <div className="editor__status-bar__right">
160
+ <button
161
+ className={clsx(
162
+ 'editor__status-bar__action editor__status-bar__generate-btn',
163
+ {
164
+ 'editor__status-bar__generate-btn--wiggling':
165
+ editorStore.graphState.graphGenerationState
166
+ .isRunningGlobalGenerate,
167
+ },
168
+ )}
169
+ disabled={
170
+ editorStore.graphState.isApplicationUpdateOperationIsRunning
171
+ }
172
+ onClick={generate}
173
+ tabIndex={-1}
174
+ title="Generate (F10)"
175
+ >
176
+ <FireIcon />
177
+ </button>
178
+ <button
179
+ className={clsx(
180
+ 'editor__status-bar__action editor__status-bar__clear__generation-btn ',
181
+
182
+ {
183
+ 'editor__status-bar__action editor__status-bar__clear__generation-btn--wiggling':
184
+ editorStore.graphState.graphGenerationState
185
+ .clearingGenerationEntitiesState.isInProgress,
186
+ },
187
+ )}
188
+ disabled={
189
+ editorStore.graphState.isApplicationUpdateOperationIsRunning ||
190
+ !editable
191
+ }
192
+ onClick={emptyGenerationEntities}
193
+ tabIndex={-1}
194
+ title="Clear generation entities"
195
+ >
196
+ <TrashIcon />
197
+ </button>
198
+ <button
199
+ className={clsx(
200
+ 'editor__status-bar__action editor__status-bar__compile-btn',
201
+ {
202
+ 'editor__status-bar__compile-btn--wiggling':
203
+ editorStore.graphState.isRunningGlobalCompile,
204
+ },
205
+ )}
206
+ disabled={
207
+ editorStore.graphState.isApplicationUpdateOperationIsRunning ||
208
+ !editable
209
+ }
210
+ onClick={compile}
211
+ tabIndex={-1}
212
+ title="Compile (F9)"
213
+ >
214
+ <HammerIcon />
215
+ </button>
216
+ <button
217
+ className={clsx(
218
+ 'editor__status-bar__action editor__status-bar__action__toggler',
219
+ {
220
+ 'editor__status-bar__action__toggler--active':
221
+ editorStore.panelGroupDisplayState.isOpen,
222
+ },
223
+ )}
224
+ onClick={togglePanel}
225
+ tabIndex={-1}
226
+ title="Toggle panel (Ctrl + `)"
227
+ >
228
+ <TerminalIcon />
229
+ </button>
139
230
  <button
140
231
  className={clsx(
141
232
  'editor__status-bar__action editor__status-bar__action__toggler',
@@ -288,6 +379,21 @@ export const ProjectViewer = withEditorStore(
288
379
  size: editorStore.sideBarDisplayState.size,
289
380
  },
290
381
  );
382
+ const resizePanel = (handleProps: ResizablePanelHandlerProps): void =>
383
+ editorStore.panelGroupDisplayState.setSize(
384
+ (handleProps.domElement as HTMLDivElement).getBoundingClientRect()
385
+ .height,
386
+ );
387
+ const maximizedCollapsiblePanelGroupProps = getCollapsiblePanelGroupProps(
388
+ editorStore.panelGroupDisplayState.isMaximized,
389
+ );
390
+ const collapsiblePanelGroupProps = getCollapsiblePanelGroupProps(
391
+ editorStore.panelGroupDisplayState.size === 0,
392
+ {
393
+ onStopResize: resizePanel,
394
+ size: editorStore.panelGroupDisplayState.size,
395
+ },
396
+ );
291
397
  const { ref, width, height } = useResizeDetector<HTMLDivElement>();
292
398
  useEffect(() => {
293
399
  if (ref.current) {
@@ -330,10 +436,39 @@ export const ProjectViewer = withEditorStore(
330
436
  {...sideBarCollapsiblePanelGroupProps.remainingPanel}
331
437
  minSize={300}
332
438
  >
333
- {editorStore.graphEditorMode.mode ===
334
- GRAPH_EDITOR_MODE.FORM && <EditorGroup />}
335
- {editorStore.graphEditorMode.mode ===
336
- GRAPH_EDITOR_MODE.GRAMMAR_TEXT && <GrammarTextEditor />}
439
+ <ResizablePanelGroup orientation="horizontal">
440
+ <ResizablePanel
441
+ {...maximizedCollapsiblePanelGroupProps.collapsiblePanel}
442
+ {...(editorStore.panelGroupDisplayState.size === 0
443
+ ? collapsiblePanelGroupProps.remainingPanel
444
+ : {})}
445
+ >
446
+ {editorStore.graphEditorMode.mode ===
447
+ GRAPH_EDITOR_MODE.FORM && <EditorGroup />}
448
+ {editorStore.graphEditorMode.mode ===
449
+ GRAPH_EDITOR_MODE.GRAMMAR_TEXT && (
450
+ <GrammarTextEditor />
451
+ )}
452
+ </ResizablePanel>
453
+ <ResizablePanelSplitter>
454
+ <ResizablePanelSplitterLine
455
+ color={
456
+ editorStore.panelGroupDisplayState.isMaximized
457
+ ? 'transparent'
458
+ : 'var(--color-dark-grey-250)'
459
+ }
460
+ />
461
+ </ResizablePanelSplitter>
462
+ <ResizablePanel
463
+ {...collapsiblePanelGroupProps.collapsiblePanel}
464
+ {...(editorStore.panelGroupDisplayState.isMaximized
465
+ ? maximizedCollapsiblePanelGroupProps.remainingPanel
466
+ : {})}
467
+ direction={-1}
468
+ >
469
+ <PanelGroup />
470
+ </ResizablePanel>
471
+ </ResizablePanelGroup>
337
472
  </ResizablePanel>
338
473
  </ResizablePanelGroup>
339
474
  </div>
@@ -0,0 +1,418 @@
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
+ useEditorStore,
20
+ withEditorStore,
21
+ } from '../editor/EditorStoreProvider.js';
22
+ import {
23
+ useShowcaseViewerStore,
24
+ withShowcaseViewerStore,
25
+ } from './ShowcaseViewerStoreProvider.js';
26
+ import { useParams } from '@finos/legend-application/browser';
27
+ import type { ShowcaseViewerPathParams } from '../../__lib__/LegendStudioNavigation.js';
28
+ import { isNonNullable } from '@finos/legend-shared';
29
+ import { Fragment, useEffect } from 'react';
30
+ import {
31
+ getCollapsiblePanelGroupProps,
32
+ useResizeDetector,
33
+ type ResizablePanelHandlerProps,
34
+ ResizablePanel,
35
+ ResizablePanelSplitter,
36
+ ResizablePanelGroup,
37
+ FileTrayIcon,
38
+ clsx,
39
+ HackerIcon,
40
+ AssistantIcon,
41
+ ReadMeIcon,
42
+ FireIcon,
43
+ HammerIcon,
44
+ TerminalIcon,
45
+ TrashIcon,
46
+ ResizablePanelSplitterLine,
47
+ } from '@finos/legend-art';
48
+ import { useApplicationStore, useCommands } from '@finos/legend-application';
49
+ import { flowResult } from 'mobx';
50
+ import { EditorGroup } from '../editor/editor-group/EditorGroup.js';
51
+ import { GrammarTextEditor } from '../editor/editor-group/GrammarTextEditor.js';
52
+ import { ProjectSearchCommand } from '../editor/command-center/ProjectSearchCommand.js';
53
+ import { EmbeddedQueryBuilder } from '../editor/EmbeddedQueryBuilder.js';
54
+ import {
55
+ ACTIVITY_MODE,
56
+ GRAPH_EDITOR_MODE,
57
+ } from '../../stores/editor/EditorConfig.js';
58
+ import { ActivityBarMenu } from '../editor/ActivityBar.js';
59
+ import type { ActivityBarItemConfig } from '@finos/legend-lego/application';
60
+ import { useLegendStudioApplicationStore } from '../LegendStudioFrameworkProvider.js';
61
+ import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js';
62
+ import { Explorer } from '../editor/side-bar/Explorer.js';
63
+ import { PanelGroup } from '../editor/panel-group/PanelGroup.js';
64
+
65
+ const ShowcaseViewerStatusBar = observer(() => {
66
+ const editorStore = useEditorStore();
67
+ const showcaseStore = useShowcaseViewerStore();
68
+ const showcase = showcaseStore._showcase;
69
+ const applicationStore = useLegendStudioApplicationStore();
70
+ const handleTextModeClick = applicationStore.guardUnhandledError(() =>
71
+ flowResult(editorStore.toggleTextMode()),
72
+ );
73
+ const editable =
74
+ editorStore.graphManagerState.graphBuildState.hasCompleted &&
75
+ editorStore.isInitialized;
76
+ const togglePanel = (): void => editorStore.panelGroupDisplayState.toggle();
77
+
78
+ const compile = applicationStore.guardUnhandledError(() =>
79
+ flowResult(editorStore.graphEditorMode.globalCompile()),
80
+ );
81
+ const generate = applicationStore.guardUnhandledError(() =>
82
+ flowResult(editorStore.graphState.graphGenerationState.globalGenerate()),
83
+ );
84
+ const emptyGenerationEntities = applicationStore.guardUnhandledError(() =>
85
+ flowResult(editorStore.graphState.graphGenerationState.clearGenerations()),
86
+ );
87
+ const toggleAssistant = (): void =>
88
+ applicationStore.assistantService.toggleAssistant();
89
+
90
+ return (
91
+ <div
92
+ data-testid={LEGEND_STUDIO_TEST_ID.STATUS_BAR}
93
+ className="editor__status-bar project-view__status-bar"
94
+ >
95
+ <div className="editor__status-bar__left">
96
+ {showcase && (
97
+ <div className="editor__status-bar__workspace">
98
+ <div className="editor__status-bar__workspace__icon">
99
+ <ReadMeIcon />
100
+ </div>
101
+ <div className="editor__status-bar__workspace__project">
102
+ <button
103
+ className="editor__status-bar__workspace__project"
104
+ tabIndex={-1}
105
+ >
106
+ {`Showcase : ${showcase.title}`}
107
+ </button>
108
+ </div>
109
+ </div>
110
+ )}
111
+ </div>
112
+ <div className="editor__status-bar__right">
113
+ <button
114
+ className={clsx(
115
+ 'editor__status-bar__action editor__status-bar__generate-btn',
116
+ {
117
+ 'editor__status-bar__generate-btn--wiggling':
118
+ editorStore.graphState.graphGenerationState
119
+ .isRunningGlobalGenerate,
120
+ },
121
+ )}
122
+ disabled={
123
+ editorStore.graphState.isApplicationUpdateOperationIsRunning
124
+ }
125
+ onClick={generate}
126
+ tabIndex={-1}
127
+ title="Generate (F10)"
128
+ >
129
+ <FireIcon />
130
+ </button>
131
+ <button
132
+ className={clsx(
133
+ 'editor__status-bar__action editor__status-bar__clear__generation-btn ',
134
+
135
+ {
136
+ 'editor__status-bar__action editor__status-bar__clear__generation-btn--wiggling':
137
+ editorStore.graphState.graphGenerationState
138
+ .clearingGenerationEntitiesState.isInProgress,
139
+ },
140
+ )}
141
+ disabled={
142
+ editorStore.graphState.isApplicationUpdateOperationIsRunning ||
143
+ !editable
144
+ }
145
+ onClick={emptyGenerationEntities}
146
+ tabIndex={-1}
147
+ title="Clear generation entities"
148
+ >
149
+ <TrashIcon />
150
+ </button>
151
+ <button
152
+ className={clsx(
153
+ 'editor__status-bar__action editor__status-bar__compile-btn',
154
+ {
155
+ 'editor__status-bar__compile-btn--wiggling':
156
+ editorStore.graphState.isRunningGlobalCompile,
157
+ },
158
+ )}
159
+ disabled={
160
+ editorStore.graphState.isApplicationUpdateOperationIsRunning ||
161
+ !editable
162
+ }
163
+ onClick={compile}
164
+ tabIndex={-1}
165
+ title="Compile (F9)"
166
+ >
167
+ <HammerIcon />
168
+ </button>
169
+ <button
170
+ className={clsx(
171
+ 'editor__status-bar__action editor__status-bar__action__toggler',
172
+ {
173
+ 'editor__status-bar__action__toggler--active':
174
+ editorStore.panelGroupDisplayState.isOpen,
175
+ },
176
+ )}
177
+ onClick={togglePanel}
178
+ tabIndex={-1}
179
+ title="Toggle panel (Ctrl + `)"
180
+ >
181
+ <TerminalIcon />
182
+ </button>
183
+ <button
184
+ className={clsx(
185
+ 'editor__status-bar__action editor__status-bar__action__toggler',
186
+ {
187
+ 'editor__status-bar__action__toggler--active':
188
+ editorStore.graphEditorMode.mode ===
189
+ GRAPH_EDITOR_MODE.GRAMMAR_TEXT,
190
+ },
191
+ )}
192
+ onClick={handleTextModeClick}
193
+ tabIndex={-1}
194
+ title="Toggle text mode (F8)"
195
+ >
196
+ <HackerIcon />
197
+ </button>
198
+ <button
199
+ className={clsx(
200
+ 'editor__status-bar__action editor__status-bar__action__toggler',
201
+ {
202
+ 'editor__status-bar__action__toggler--active':
203
+ !applicationStore.assistantService.isHidden,
204
+ },
205
+ )}
206
+ onClick={toggleAssistant}
207
+ tabIndex={-1}
208
+ title="Toggle assistant"
209
+ >
210
+ <AssistantIcon />
211
+ </button>
212
+ </div>
213
+ </div>
214
+ );
215
+ });
216
+
217
+ const ShowcaseViewerActivityBar = observer(() => {
218
+ const editorStore = useEditorStore();
219
+
220
+ const changeActivity =
221
+ (activity: string): (() => void) =>
222
+ (): void =>
223
+ editorStore.setActiveActivity(activity);
224
+ // tabs
225
+ const activities: ActivityBarItemConfig[] = (
226
+ [
227
+ {
228
+ mode: ACTIVITY_MODE.EXPLORER,
229
+ title: 'Explorer (Ctrl + Shift + X)',
230
+ icon: <FileTrayIcon />,
231
+ },
232
+ ] as (ActivityBarItemConfig | boolean)[]
233
+ ).filter((activity): activity is ActivityBarItemConfig => Boolean(activity));
234
+
235
+ return (
236
+ <div className="activity-bar">
237
+ <ActivityBarMenu />
238
+ <div className="activity-bar__items">
239
+ {activities.map((activity) => (
240
+ <button
241
+ key={activity.mode}
242
+ className={clsx('activity-bar__item', {
243
+ 'activity-bar__item--active':
244
+ editorStore.sideBarDisplayState.isOpen &&
245
+ editorStore.activeActivity === activity.mode,
246
+ })}
247
+ onClick={changeActivity(activity.mode)}
248
+ tabIndex={-1}
249
+ title={activity.title}
250
+ >
251
+ {activity.icon}
252
+ </button>
253
+ ))}
254
+ </div>
255
+ </div>
256
+ );
257
+ });
258
+
259
+ const ShowcaseViewerSideBar = observer(() => {
260
+ const editorStore = useEditorStore();
261
+ const renderSideBar = (): React.ReactNode => {
262
+ switch (editorStore.activeActivity) {
263
+ case ACTIVITY_MODE.EXPLORER:
264
+ return <Explorer />;
265
+ default:
266
+ return null;
267
+ }
268
+ };
269
+ return (
270
+ <div className="side-bar">
271
+ <div className="side-bar__view">{renderSideBar()}</div>
272
+ </div>
273
+ );
274
+ });
275
+
276
+ export const ShowcaseViewer = withEditorStore(
277
+ withShowcaseViewerStore(
278
+ observer(() => {
279
+ const params = useParams<ShowcaseViewerPathParams>();
280
+ const showcaseStore = useShowcaseViewerStore();
281
+ const applicationStore = useApplicationStore();
282
+ const editorStore = useEditorStore();
283
+
284
+ // Extensions
285
+ const extraEditorExtensionComponents = editorStore.pluginManager
286
+ .getApplicationPlugins()
287
+ .flatMap(
288
+ (plugin) =>
289
+ plugin.getExtraEditorExtensionComponentRendererConfigurations?.() ??
290
+ [],
291
+ )
292
+ .filter(isNonNullable)
293
+ .map((config) => (
294
+ <Fragment key={config.key}>{config.renderer(editorStore)}</Fragment>
295
+ ));
296
+
297
+ // layout
298
+ const resizeSideBar = (handleProps: ResizablePanelHandlerProps): void =>
299
+ editorStore.sideBarDisplayState.setSize(
300
+ (handleProps.domElement as HTMLDivElement).getBoundingClientRect()
301
+ .width,
302
+ );
303
+ const sideBarCollapsiblePanelGroupProps = getCollapsiblePanelGroupProps(
304
+ editorStore.sideBarDisplayState.size === 0,
305
+ {
306
+ onStopResize: resizeSideBar,
307
+ size: editorStore.sideBarDisplayState.size,
308
+ },
309
+ );
310
+ const resizePanel = (handleProps: ResizablePanelHandlerProps): void =>
311
+ editorStore.panelGroupDisplayState.setSize(
312
+ (handleProps.domElement as HTMLDivElement).getBoundingClientRect()
313
+ .height,
314
+ );
315
+ const collapsiblePanelGroupProps = getCollapsiblePanelGroupProps(
316
+ editorStore.panelGroupDisplayState.size === 0,
317
+ {
318
+ onStopResize: resizePanel,
319
+ size: editorStore.panelGroupDisplayState.size,
320
+ },
321
+ );
322
+ const collapsibleSideBarGroupProps = getCollapsiblePanelGroupProps(
323
+ editorStore.sideBarDisplayState.size === 0,
324
+ {
325
+ onStopResize: resizeSideBar,
326
+ size: editorStore.sideBarDisplayState.size,
327
+ },
328
+ );
329
+ const maximizedCollapsiblePanelGroupProps = getCollapsiblePanelGroupProps(
330
+ editorStore.panelGroupDisplayState.isMaximized,
331
+ );
332
+ const { ref, width, height } = useResizeDetector<HTMLDivElement>();
333
+ useEffect(() => {
334
+ if (ref.current) {
335
+ editorStore.panelGroupDisplayState.setMaxSize(
336
+ ref.current.offsetHeight,
337
+ );
338
+ }
339
+ }, [ref, editorStore, width, height]);
340
+
341
+ // initialize
342
+ useEffect(() => {
343
+ flowResult(showcaseStore.initialize(params)).catch(
344
+ applicationStore.alertUnhandledError,
345
+ );
346
+ }, [applicationStore, showcaseStore, params]);
347
+
348
+ useCommands(editorStore);
349
+
350
+ return (
351
+ <div className="app__page">
352
+ <div className="editor viewer">
353
+ <div className="editor__body">
354
+ <ShowcaseViewerActivityBar />
355
+ <div ref={ref} className="editor__content-container">
356
+ <div className="editor__content">
357
+ <ResizablePanelGroup orientation="vertical">
358
+ <ResizablePanel
359
+ {...sideBarCollapsiblePanelGroupProps.collapsiblePanel}
360
+ direction={1}
361
+ >
362
+ <ShowcaseViewerSideBar />
363
+ </ResizablePanel>
364
+ <ResizablePanelSplitter />
365
+ <ResizablePanel
366
+ {...collapsibleSideBarGroupProps.remainingPanel}
367
+ minSize={300}
368
+ >
369
+ <ResizablePanelGroup orientation="horizontal">
370
+ <ResizablePanel
371
+ {...maximizedCollapsiblePanelGroupProps.collapsiblePanel}
372
+ {...(editorStore.panelGroupDisplayState.size === 0
373
+ ? collapsiblePanelGroupProps.remainingPanel
374
+ : {})}
375
+ >
376
+ {editorStore.graphEditorMode.mode ===
377
+ GRAPH_EDITOR_MODE.FORM && <EditorGroup />}
378
+ {editorStore.graphEditorMode.mode ===
379
+ GRAPH_EDITOR_MODE.GRAMMAR_TEXT && (
380
+ <GrammarTextEditor />
381
+ )}
382
+ </ResizablePanel>
383
+ <ResizablePanelSplitter>
384
+ <ResizablePanelSplitterLine
385
+ color={
386
+ editorStore.panelGroupDisplayState.isMaximized
387
+ ? 'transparent'
388
+ : 'var(--color-dark-grey-250)'
389
+ }
390
+ />
391
+ </ResizablePanelSplitter>
392
+ <ResizablePanel
393
+ {...collapsiblePanelGroupProps.collapsiblePanel}
394
+ {...(editorStore.panelGroupDisplayState.isMaximized
395
+ ? maximizedCollapsiblePanelGroupProps.remainingPanel
396
+ : {})}
397
+ direction={-1}
398
+ >
399
+ <PanelGroup />
400
+ </ResizablePanel>
401
+ </ResizablePanelGroup>
402
+ </ResizablePanel>
403
+ </ResizablePanelGroup>
404
+ </div>
405
+ </div>
406
+ </div>
407
+ {editorStore.graphManagerState.graphBuildState.hasSucceeded && (
408
+ <ProjectSearchCommand />
409
+ )}
410
+ <ShowcaseViewerStatusBar />
411
+ <EmbeddedQueryBuilder />
412
+ {extraEditorExtensionComponents}
413
+ </div>
414
+ </div>
415
+ );
416
+ }),
417
+ ),
418
+ );
@@ -0,0 +1,56 @@
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 { createContext, useContext } from 'react';
18
+ import { ShowcaseViewerStore } from '../../stores/showcase/ShowcaseViewerStore.js';
19
+ import { useEditorStore } from '../editor/EditorStoreProvider.js';
20
+ import { useLocalObservable } from 'mobx-react-lite';
21
+ import { guaranteeNonNullable } from '@finos/legend-shared';
22
+ import { EDITOR_MODE } from '../../stores/editor/EditorConfig.js';
23
+ import { ShowcaseViewerEditorMode } from '../../stores/showcase/ShowcaseViewerEditorMode.js';
24
+
25
+ const ShowcaseViewerStoreContext = createContext<
26
+ ShowcaseViewerStore | undefined
27
+ >(undefined);
28
+
29
+ export const ShowcaseViewerStoreProvider: React.FC<{
30
+ children: React.ReactNode;
31
+ }> = ({ children }) => {
32
+ const editorStore = useEditorStore();
33
+ editorStore.setMode(EDITOR_MODE.VIEWER);
34
+ const store = useLocalObservable(() => new ShowcaseViewerStore(editorStore));
35
+ editorStore.setEditorMode(new ShowcaseViewerEditorMode(store));
36
+ return (
37
+ <ShowcaseViewerStoreContext.Provider value={store}>
38
+ {children}
39
+ </ShowcaseViewerStoreContext.Provider>
40
+ );
41
+ };
42
+
43
+ export const useShowcaseViewerStore = (): ShowcaseViewerStore =>
44
+ guaranteeNonNullable(
45
+ useContext(ShowcaseViewerStoreContext),
46
+ `Can't find showcase viewer store in context`,
47
+ );
48
+
49
+ export const withShowcaseViewerStore = (WrapperComponent: React.FC): React.FC =>
50
+ function WithShowcaseViewerStore() {
51
+ return (
52
+ <ShowcaseViewerStoreProvider>
53
+ <WrapperComponent />
54
+ </ShowcaseViewerStoreProvider>
55
+ );
56
+ };
@@ -124,6 +124,7 @@ export class LegendStudioBaseStore {
124
124
  LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.VIEW_BY_GAV,
125
125
  LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.VIEW_BY_GAV_ENTITY,
126
126
  LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.PREVIEW_BY_GAV_ENTITY,
127
+ LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.SHOWCASE_PROJECT,
127
128
  ],
128
129
  )
129
130
  ) {