@finos/legend-application-studio 27.1.11 → 28.0.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 (119) hide show
  1. package/lib/__lib__/LegendStudioEvent.d.ts +1 -0
  2. package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioEvent.js +3 -0
  4. package/lib/__lib__/LegendStudioEvent.js.map +1 -1
  5. package/lib/application/LegendStudioApplicationConfig.d.ts +6 -2
  6. package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
  7. package/lib/application/LegendStudioApplicationConfig.js +7 -2
  8. package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
  9. package/lib/components/ShowcaseManager.d.ts +19 -0
  10. package/lib/components/ShowcaseManager.d.ts.map +1 -0
  11. package/lib/components/ShowcaseManager.js +94 -0
  12. package/lib/components/ShowcaseManager.js.map +1 -0
  13. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  14. package/lib/components/editor/ActivityBar.js +13 -1
  15. package/lib/components/editor/ActivityBar.js.map +1 -1
  16. package/lib/components/editor/Editor.js +1 -1
  17. package/lib/components/editor/Editor.js.map +1 -1
  18. package/lib/components/editor/EmbeddedQueryBuilder.d.ts.map +1 -0
  19. package/lib/components/{EmbeddedQueryBuilder.js → editor/EmbeddedQueryBuilder.js} +3 -3
  20. package/lib/components/editor/EmbeddedQueryBuilder.js.map +1 -0
  21. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts +1 -1
  22. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts.map +1 -1
  23. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js +2 -1
  24. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js.map +1 -1
  25. package/lib/components/editor/editor-group/element-generation-editor/ElementXTGenerationEditor.js.map +1 -1
  26. package/lib/components/editor/editor-group/element-generation-editor/FileGenerationEditor.d.ts +1 -1
  27. package/lib/components/editor/editor-group/element-generation-editor/FileGenerationEditor.d.ts.map +1 -1
  28. package/lib/components/editor/editor-group/element-generation-editor/FileGenerationEditor.js.map +1 -1
  29. package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.js.map +1 -1
  30. package/lib/components/editor/editor-group/mapping-editor/InstanceSetImplementationEditor.js.map +1 -1
  31. package/lib/components/editor/editor-group/mapping-editor/InstanceSetImplementationSourceSelectorModal.d.ts +3 -3
  32. package/lib/components/editor/editor-group/mapping-editor/InstanceSetImplementationSourceSelectorModal.d.ts.map +1 -1
  33. package/lib/components/editor/editor-group/mapping-editor/InstanceSetImplementationSourceSelectorModal.js.map +1 -1
  34. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.d.ts.map +1 -1
  35. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js +1 -1
  36. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js.map +1 -1
  37. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
  38. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +4 -4
  39. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
  40. package/lib/components/editor/side-bar/testable/GlobalTestRunner.d.ts.map +1 -1
  41. package/lib/components/editor/side-bar/testable/GlobalTestRunner.js +1 -1
  42. package/lib/components/editor/side-bar/testable/GlobalTestRunner.js.map +1 -1
  43. package/lib/components/extensions/Core_LegendStudioApplicationPlugin.d.ts +4 -1
  44. package/lib/components/extensions/Core_LegendStudioApplicationPlugin.d.ts.map +1 -1
  45. package/lib/components/extensions/Core_LegendStudioApplicationPlugin.js +21 -0
  46. package/lib/components/extensions/Core_LegendStudioApplicationPlugin.js.map +1 -1
  47. package/lib/components/project-view/ProjectViewer.js +1 -1
  48. package/lib/components/project-view/ProjectViewer.js.map +1 -1
  49. package/lib/index.css +2 -2
  50. package/lib/index.css.map +1 -1
  51. package/lib/index.d.ts +1 -1
  52. package/lib/index.d.ts.map +1 -1
  53. package/lib/index.js +1 -0
  54. package/lib/index.js.map +1 -1
  55. package/lib/package.json +9 -8
  56. package/lib/stores/LegendStudioApplicationPlugin.d.ts +12 -10
  57. package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
  58. package/lib/stores/LegendStudioApplicationPlugin.js.map +1 -1
  59. package/lib/stores/LegendStudioBaseStore.d.ts.map +1 -1
  60. package/lib/stores/LegendStudioBaseStore.js +16 -6
  61. package/lib/stores/LegendStudioBaseStore.js.map +1 -1
  62. package/lib/stores/ShowcaseManagerState.d.ts +56 -0
  63. package/lib/stores/ShowcaseManagerState.d.ts.map +1 -0
  64. package/lib/stores/ShowcaseManagerState.js +176 -0
  65. package/lib/stores/ShowcaseManagerState.js.map +1 -0
  66. package/lib/stores/editor/EditorStore.d.ts +7 -1
  67. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  68. package/lib/stores/editor/EditorStore.js +8 -3
  69. package/lib/stores/editor/EditorStore.js.map +1 -1
  70. package/lib/stores/editor/__test-utils__/EditorStoreTestUtils.js +1 -1
  71. package/lib/stores/editor/editor-state/element-editor-state/external-format/DSL_ExternalFormat_SchemaSetEditorState.d.ts +1 -1
  72. package/lib/stores/editor/editor-state/element-editor-state/external-format/DSL_ExternalFormat_SchemaSetEditorState.d.ts.map +1 -1
  73. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.d.ts +1 -1
  74. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.d.ts.map +1 -1
  75. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.js.map +1 -1
  76. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts +2 -2
  77. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
  78. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
  79. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.d.ts +1 -1
  80. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.d.ts.map +1 -1
  81. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js.map +1 -1
  82. package/lib/stores/editor/sidebar-state/testable/GlobalTestRunnerState.js +1 -1
  83. package/lib/stores/editor/sidebar-state/testable/GlobalTestRunnerState.js.map +1 -1
  84. package/lib/stores/extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.d.ts +2 -2
  85. package/lib/stores/extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.d.ts.map +1 -1
  86. package/package.json +19 -18
  87. package/src/__lib__/LegendStudioEvent.ts +4 -0
  88. package/src/application/LegendStudioApplicationConfig.ts +12 -3
  89. package/src/components/ShowcaseManager.tsx +298 -0
  90. package/src/components/editor/ActivityBar.tsx +21 -1
  91. package/src/components/editor/Editor.tsx +1 -1
  92. package/src/components/{EmbeddedQueryBuilder.tsx → editor/EmbeddedQueryBuilder.tsx} +5 -3
  93. package/src/components/editor/__test-utils__/EditorComponentTestUtils.tsx +2 -2
  94. package/src/components/editor/editor-group/element-generation-editor/ElementXTGenerationEditor.tsx +1 -1
  95. package/src/components/editor/editor-group/element-generation-editor/FileGenerationEditor.tsx +8 -8
  96. package/src/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetModelGenerationEditor.tsx +1 -1
  97. package/src/components/editor/editor-group/mapping-editor/InstanceSetImplementationEditor.tsx +1 -1
  98. package/src/components/editor/editor-group/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx +3 -5
  99. package/src/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.tsx +5 -7
  100. package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +8 -10
  101. package/src/components/editor/side-bar/testable/GlobalTestRunner.tsx +3 -1
  102. package/src/components/extensions/Core_LegendStudioApplicationPlugin.tsx +29 -0
  103. package/src/components/project-view/ProjectViewer.tsx +1 -1
  104. package/src/index.ts +1 -1
  105. package/src/stores/LegendStudioApplicationPlugin.ts +12 -10
  106. package/src/stores/LegendStudioBaseStore.ts +21 -8
  107. package/src/stores/ShowcaseManagerState.ts +275 -0
  108. package/src/stores/editor/EditorStore.ts +12 -4
  109. package/src/stores/editor/__test-utils__/EditorStoreTestUtils.ts +1 -1
  110. package/src/stores/editor/editor-state/element-editor-state/external-format/DSL_ExternalFormat_SchemaSetEditorState.ts +1 -1
  111. package/src/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.ts +1 -1
  112. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +2 -2
  113. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.ts +1 -1
  114. package/src/stores/editor/sidebar-state/testable/GlobalTestRunnerState.ts +1 -1
  115. package/src/stores/extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.ts +2 -2
  116. package/tsconfig.json +3 -1
  117. package/lib/components/EmbeddedQueryBuilder.d.ts.map +0 -1
  118. package/lib/components/EmbeddedQueryBuilder.js.map +0 -1
  119. /package/lib/components/{EmbeddedQueryBuilder.d.ts → editor/EmbeddedQueryBuilder.d.ts} +0 -0
@@ -0,0 +1,298 @@
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 { useApplicationStore } from '@finos/legend-application';
18
+ import { observer } from 'mobx-react-lite';
19
+ import {
20
+ BlankPanelContent,
21
+ Panel,
22
+ PanelLoadingIndicator,
23
+ TreeView,
24
+ type TreeNodeContainerProps,
25
+ ChevronDownIcon,
26
+ ChevronRightIcon,
27
+ GenericTextFileIcon,
28
+ FolderIcon,
29
+ FolderOpenIcon,
30
+ HomeIcon,
31
+ } from '@finos/legend-art';
32
+ import {
33
+ SHOWCASE_MANAGER_VIEW,
34
+ ShowcaseManagerState,
35
+ type ShowcasesExplorerTreeNodeData,
36
+ } from '../stores/ShowcaseManagerState.js';
37
+ import { isNonNullable } from '@finos/legend-shared';
38
+ import { flowResult } from 'mobx';
39
+ import type { Showcase } from '@finos/legend-server-showcase';
40
+ import {
41
+ CODE_EDITOR_LANGUAGE,
42
+ CodeEditor,
43
+ } from '@finos/legend-lego/code-editor';
44
+
45
+ const ShowcasesExplorerTreeNodeContainer = observer(
46
+ (
47
+ props: TreeNodeContainerProps<
48
+ ShowcasesExplorerTreeNodeData,
49
+ {
50
+ showcaseManagerState: ShowcaseManagerState;
51
+ toggleExpandNode: (node: ShowcasesExplorerTreeNodeData) => void;
52
+ }
53
+ >,
54
+ ) => {
55
+ const { node, level, innerProps } = props;
56
+ const { toggleExpandNode, showcaseManagerState } = innerProps;
57
+ const applicationStore = useApplicationStore();
58
+
59
+ const expandIcon = !node.metadata ? (
60
+ node.isOpen ? (
61
+ <ChevronDownIcon />
62
+ ) : (
63
+ <ChevronRightIcon />
64
+ )
65
+ ) : (
66
+ <div />
67
+ );
68
+ const nodeIcon = !node.metadata ? (
69
+ node.isOpen ? (
70
+ <FolderOpenIcon />
71
+ ) : (
72
+ <FolderIcon />
73
+ )
74
+ ) : (
75
+ <GenericTextFileIcon />
76
+ );
77
+ const onNodeClick = (): void => {
78
+ if (!node.metadata) {
79
+ toggleExpandNode(node);
80
+ } else {
81
+ flowResult(showcaseManagerState.openShowcase(node.metadata)).catch(
82
+ applicationStore.alertUnhandledError,
83
+ );
84
+ }
85
+ };
86
+
87
+ return (
88
+ <div
89
+ className="tree-view__node__container showcase-manager__explorer__node__container"
90
+ style={{
91
+ paddingLeft: `${(level - 1) * 1.4}rem`,
92
+ display: 'flex',
93
+ }}
94
+ onClick={onNodeClick}
95
+ >
96
+ <div className="showcase-manager__explorer__node__expand-icon">
97
+ {expandIcon}
98
+ </div>
99
+ <div className="showcase-manager__explorer__node__type-icon">
100
+ {nodeIcon}
101
+ </div>
102
+ <div
103
+ className="tree-view__node__label showcase-manager__explorer__node__label"
104
+ title={
105
+ node.metadata
106
+ ? `${
107
+ node.metadata.description
108
+ ? `${node.metadata.description}\n\n`
109
+ : ''
110
+ }Click to open showcase`
111
+ : undefined
112
+ }
113
+ >
114
+ {node.label}
115
+ </div>
116
+ </div>
117
+ );
118
+ },
119
+ );
120
+
121
+ const ShowcaseManagerExplorer = observer(
122
+ (props: { showcaseManagerState: ShowcaseManagerState }) => {
123
+ const { showcaseManagerState } = props;
124
+ const treeData = showcaseManagerState.explorerTreeData;
125
+ const getChildNodes = (
126
+ node: ShowcasesExplorerTreeNodeData,
127
+ ): ShowcasesExplorerTreeNodeData[] => {
128
+ if (treeData) {
129
+ return node.childrenIds
130
+ .map((id) => treeData.nodes.get(id))
131
+ .filter(isNonNullable)
132
+ .sort((a, b) => a.label.localeCompare(b.label));
133
+ }
134
+ return [];
135
+ };
136
+ const toggleExpandNode = (node: ShowcasesExplorerTreeNodeData): void => {
137
+ if (treeData) {
138
+ node.isOpen = !node.isOpen;
139
+ showcaseManagerState.setExplorerTreeData({ ...treeData });
140
+ }
141
+ };
142
+
143
+ return (
144
+ <div className="showcase-manager__view">
145
+ <div className="showcase-manager__view__header">
146
+ <div className="showcase-manager__view__breadcrumbs">
147
+ <div className="showcase-manager__view__breadcrumb">
148
+ <div className="showcase-manager__view__breadcrumb__icon">
149
+ <HomeIcon />
150
+ </div>
151
+ <div className="showcase-manager__view__breadcrumb__text">
152
+ Showcaces
153
+ </div>
154
+ </div>
155
+ <div className="showcase-manager__view__breadcrumb__arrow">
156
+ <ChevronRightIcon />
157
+ </div>
158
+ <div className="showcase-manager__view__breadcrumb">
159
+ <div className="showcase-manager__view__breadcrumb__text">
160
+ Explorer
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ <div className="showcase-manager__view__content">
166
+ {showcaseManagerState.explorerTreeData && (
167
+ <TreeView
168
+ components={{
169
+ TreeNodeContainer: ShowcasesExplorerTreeNodeContainer,
170
+ }}
171
+ treeData={showcaseManagerState.explorerTreeData}
172
+ getChildNodes={getChildNodes}
173
+ innerProps={{
174
+ toggleExpandNode,
175
+ showcaseManagerState,
176
+ }}
177
+ />
178
+ )}
179
+ </div>
180
+ </div>
181
+ );
182
+ },
183
+ );
184
+
185
+ const ShowcaseViewer = observer(
186
+ (props: {
187
+ showcaseManagerState: ShowcaseManagerState;
188
+ showcase: Showcase;
189
+ }) => {
190
+ const { showcaseManagerState, showcase } = props;
191
+ const prettyPath = showcase.path.replaceAll(/\s*\/\s*/g, ' / ');
192
+
193
+ return (
194
+ <div className="showcase-manager__view">
195
+ <div className="showcase-manager__view__header">
196
+ <div className="showcase-manager__view__breadcrumbs">
197
+ <div
198
+ className="showcase-manager__view__breadcrumb"
199
+ onClick={() => {
200
+ showcaseManagerState.closeShowcase();
201
+ showcaseManagerState.setCurrentView(
202
+ SHOWCASE_MANAGER_VIEW.EXPLORER,
203
+ );
204
+ }}
205
+ >
206
+ <div className="showcase-manager__view__breadcrumb__icon">
207
+ <HomeIcon />
208
+ </div>
209
+ <div className="showcase-manager__view__breadcrumb__text">
210
+ Showcaces
211
+ </div>
212
+ </div>
213
+ <div className="showcase-manager__view__breadcrumb__arrow">
214
+ <ChevronRightIcon />
215
+ </div>
216
+ <div className="showcase-manager__view__breadcrumb">
217
+ <div className="showcase-manager__view__breadcrumb__icon">
218
+ <GenericTextFileIcon />
219
+ </div>
220
+ <div className="showcase-manager__view__breadcrumb__text">
221
+ {showcase.title}
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ <div className="showcase-manager__view__content showcase-manager__viewer__content">
227
+ <div className="showcase-manager__viewer__title">
228
+ {showcase.title}
229
+ </div>
230
+ <div className="showcase-manager__viewer__path">{prettyPath}</div>
231
+ <div className="showcase-manager__viewer__code">
232
+ <CodeEditor
233
+ language={CODE_EDITOR_LANGUAGE.PURE}
234
+ inputValue={showcase.code}
235
+ isReadOnly={true}
236
+ />
237
+ </div>
238
+ </div>
239
+ </div>
240
+ );
241
+ },
242
+ );
243
+
244
+ const ShowcaseManagerContent = observer(
245
+ (props: { showcaseManagerState: ShowcaseManagerState }) => {
246
+ const { showcaseManagerState } = props;
247
+ const currentShowcase = showcaseManagerState.currentShowcase;
248
+ const currentView = showcaseManagerState.currentView;
249
+
250
+ return (
251
+ <div className="showcase-manager">
252
+ {currentShowcase && (
253
+ <ShowcaseViewer
254
+ showcaseManagerState={showcaseManagerState}
255
+ showcase={currentShowcase}
256
+ />
257
+ )}
258
+ {!currentShowcase && (
259
+ <>
260
+ {currentView === SHOWCASE_MANAGER_VIEW.EXPLORER && (
261
+ <ShowcaseManagerExplorer
262
+ showcaseManagerState={showcaseManagerState}
263
+ />
264
+ )}
265
+ {currentView === SHOWCASE_MANAGER_VIEW.SEARCH && <>TODO: Search</>}
266
+ </>
267
+ )}
268
+ </div>
269
+ );
270
+ },
271
+ );
272
+
273
+ export const ShowcaseManager = observer(() => {
274
+ const applicationStore = useApplicationStore();
275
+ const showcaseManagerState =
276
+ ShowcaseManagerState.retrieveNullableState(applicationStore);
277
+
278
+ if (!showcaseManagerState) {
279
+ return null;
280
+ }
281
+
282
+ return (
283
+ <Panel>
284
+ <PanelLoadingIndicator
285
+ isLoading={showcaseManagerState.initState.isInProgress}
286
+ />
287
+ {showcaseManagerState.initState.isInProgress && (
288
+ <BlankPanelContent>Initializing...</BlankPanelContent>
289
+ )}
290
+ {showcaseManagerState.initState.hasFailed && (
291
+ <BlankPanelContent>Failed to initialize</BlankPanelContent>
292
+ )}
293
+ {showcaseManagerState.initState.hasSucceeded && (
294
+ <ShowcaseManagerContent showcaseManagerState={showcaseManagerState} />
295
+ )}
296
+ </Panel>
297
+ );
298
+ });
@@ -47,6 +47,8 @@ import {
47
47
  ActivityBarItemExperimentalBadge,
48
48
  type ActivityBarItemConfig,
49
49
  } from '@finos/legend-lego/application';
50
+ import { ShowcaseManagerState } from '../../stores/ShowcaseManagerState.js';
51
+ import { SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY } from '../extensions/Core_LegendStudioApplicationPlugin.js';
50
52
 
51
53
  const SettingsMenu = observer(
52
54
  forwardRef<HTMLDivElement, unknown>(function SettingsMenu(props, ref) {
@@ -98,6 +100,19 @@ export const ActivityBarMenu: React.FC = () => {
98
100
  VIRTUAL_ASSISTANT_TAB.SEARCH,
99
101
  );
100
102
  };
103
+ // showcases
104
+ const showcaseManagerState =
105
+ 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
+ };
101
116
 
102
117
  return (
103
118
  <>
@@ -112,7 +127,11 @@ export const ActivityBarMenu: React.FC = () => {
112
127
  content={
113
128
  <MenuContent>
114
129
  <MenuContentItem onClick={showAppInfo}>About</MenuContentItem>
115
- <MenuContentItem onClick={openHelp}>Help...</MenuContentItem>
130
+ {showcaseManagerState?.isEnabled && (
131
+ <MenuContentItem onClick={openShowcaseManager}>
132
+ See Showcases
133
+ </MenuContentItem>
134
+ )}
116
135
  <MenuContentItem
117
136
  disabled={!appDocUrl}
118
137
  onClick={goToDocumentation}
@@ -127,6 +146,7 @@ export const ActivityBarMenu: React.FC = () => {
127
146
  {entry.label}
128
147
  </MenuContentItem>
129
148
  ))}
149
+ <MenuContentItem onClick={openHelp}>Help...</MenuContentItem>
130
150
  <MenuContentDivider />
131
151
  <MenuContentItem onClick={goToWorkspaceSetup}>
132
152
  Back to workspace setup
@@ -50,7 +50,7 @@ import { useParams } from '@finos/legend-application/browser';
50
50
  import { WorkspaceType } from '@finos/legend-server-sdlc';
51
51
  import { WorkspaceSyncConflictResolver } from './side-bar/WorkspaceSyncConflictResolver.js';
52
52
  import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js';
53
- import { EmbeddedQueryBuilder } from '../EmbeddedQueryBuilder.js';
53
+ import { EmbeddedQueryBuilder } from './EmbeddedQueryBuilder.js';
54
54
  import { GRAPH_EDITOR_MODE } from '../../stores/editor/EditorConfig.js';
55
55
  import { QuickInput } from './QuickInput.js';
56
56
 
@@ -34,9 +34,9 @@ import {
34
34
  QueryBuilder,
35
35
  type QueryBuilderState,
36
36
  } from '@finos/legend-query-builder';
37
- import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../__lib__/LegendStudioApplicationNavigationContext.js';
38
- import { useEditorStore } from './editor/EditorStoreProvider.js';
39
- import type { EmbeddedQueryBuilderState } from '../stores/editor/EmbeddedQueryBuilderState.js';
37
+ import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js';
38
+ import { useEditorStore } from './EditorStoreProvider.js';
39
+ import type { EmbeddedQueryBuilderState } from '../../stores/editor/EmbeddedQueryBuilderState.js';
40
40
 
41
41
  /**
42
42
  * NOTE: Query builder is by right a mini-app so we have it hosted in a full-screen modal dialog
@@ -94,6 +94,7 @@ const QueryBuilderDialog = observer(
94
94
  className="query-builder__dialog__header__action"
95
95
  tabIndex={-1}
96
96
  onClick={toggleMaximize}
97
+ title={isMaximized ? 'Minimize' : 'Maximize'}
97
98
  >
98
99
  {isMaximized ? (
99
100
  <EmptyWindowRestoreIcon />
@@ -105,6 +106,7 @@ const QueryBuilderDialog = observer(
105
106
  className="query-builder__dialog__header__action"
106
107
  tabIndex={-1}
107
108
  onClick={confirmCloseQueryBuilder}
109
+ title="Close"
108
110
  >
109
111
  <TimesIcon />
110
112
  </button>
@@ -65,7 +65,7 @@ import {
65
65
  createMemoryHistory,
66
66
  TEST__BrowserEnvironmentProvider,
67
67
  } from '@finos/legend-application/test';
68
- import type { LegendStudioApplicationStore } from '../../../stores/LegendStudioBaseStore.js';
68
+ import { type LegendStudioApplicationStore } from '../../../stores/LegendStudioBaseStore.js';
69
69
  import { TEST__getLegendStudioApplicationConfig } from '../../../stores/__test-utils__/LegendStudioApplicationTestUtils.js';
70
70
  import { Route } from '@finos/legend-application/browser';
71
71
 
@@ -153,7 +153,7 @@ export const TEST__provideMockedEditorStore = (customization?: {
153
153
  new SDLCServerClient({
154
154
  env: applicationStore.config.env,
155
155
  serverUrl: applicationStore.config.sdlcServerUrl,
156
- baseHeaders: applicationStore.config.SDLCServerBaseHeaders,
156
+ baseHeaders: applicationStore.config.sdlcServerBaseHeaders,
157
157
  }),
158
158
  new DepotServerClient({
159
159
  serverUrl: applicationStore.config.depotServerUrl,
@@ -79,7 +79,7 @@ export const ExternalFormatGeneratioConfigEditor = observer(
79
79
  debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
80
80
  };
81
81
 
82
- const getConfigValue = (name: string): unknown | undefined =>
82
+ const getConfigValue = (name: string): unknown =>
83
83
  xtState.xtGenerationState.configSpecification.configurationProperties.find(
84
84
  (e) => e.name === name,
85
85
  )?.value;
@@ -319,7 +319,7 @@ const GenerationStringPropertyEditor = observer(
319
319
  property: GenerationProperty;
320
320
  isReadOnly: boolean;
321
321
  update: (property: GenerationProperty, newValue: PlainObject) => void;
322
- getConfigValue: (name: string) => unknown | undefined;
322
+ getConfigValue: (name: string) => unknown;
323
323
  }) => {
324
324
  const { property, getConfigValue, isReadOnly, update } = props;
325
325
  // If there is no default value the string will be 'null'. We will treat it as an empty string
@@ -354,7 +354,7 @@ const GenerationIntegerPropertyEditor = observer(
354
354
  property: GenerationProperty;
355
355
  isReadOnly: boolean;
356
356
  update: (property: GenerationProperty, newValue: PlainObject) => void;
357
- getConfigValue: (name: string) => unknown | undefined;
357
+ getConfigValue: (name: string) => unknown;
358
358
  }) => {
359
359
  const { property, getConfigValue, isReadOnly, update } = props;
360
360
  const defaultValue = JSON.parse(property.defaultValue) as
@@ -390,7 +390,7 @@ const GenerationBooleanPropertyEditor = observer(
390
390
  property: GenerationProperty;
391
391
  isReadOnly: boolean;
392
392
  update: (property: GenerationProperty, newValue: PlainObject) => void;
393
- getConfigValue: (name: string) => unknown | undefined;
393
+ getConfigValue: (name: string) => unknown;
394
394
  }) => {
395
395
  const { property, getConfigValue, isReadOnly, update } = props;
396
396
  const defaultValue = JSON.parse(property.defaultValue) as
@@ -417,7 +417,7 @@ const GenerationEnumPropertyEditor = observer(
417
417
  property: GenerationProperty;
418
418
  isReadOnly: boolean;
419
419
  update: (property: GenerationProperty, newValue: PlainObject) => void;
420
- getConfigValue: (name: string) => unknown | undefined;
420
+ getConfigValue: (name: string) => unknown;
421
421
  }) => {
422
422
  const { property, getConfigValue, isReadOnly, update } = props;
423
423
  const getEnumLabel = (_enum: string): string =>
@@ -464,7 +464,7 @@ const GenerationArrayPropertyEditor = observer(
464
464
  property: GenerationProperty;
465
465
  isReadOnly: boolean;
466
466
  update: (property: GenerationProperty, newValue: object) => void;
467
- getConfigValue: (name: string) => unknown | undefined;
467
+ getConfigValue: (name: string) => unknown;
468
468
  }) => {
469
469
  const { property, getConfigValue, isReadOnly, update } = props;
470
470
  let defaultValue: string[] = [];
@@ -654,7 +654,7 @@ const GenerationMapPropertyEditor = observer(
654
654
  property: GenerationProperty;
655
655
  isReadOnly: boolean;
656
656
  update: (property: GenerationProperty, newValue: object) => void;
657
- getConfigValue: (name: string) => unknown | undefined;
657
+ getConfigValue: (name: string) => unknown;
658
658
  }) => {
659
659
  const { property, getConfigValue, isReadOnly, update } = props;
660
660
  // Right now, always assume this is a map between STRING and STRING (might need to support STRING - INTEGER and STRING - BOOLEAN)
@@ -884,7 +884,7 @@ const GenerationMapPropertyEditor = observer(
884
884
  export const GenerationPropertyEditor = observer(
885
885
  (props: {
886
886
  property: GenerationProperty;
887
- getConfigValue: (name: string) => unknown | undefined;
887
+ getConfigValue: (name: string) => unknown;
888
888
  isReadOnly: boolean;
889
889
  update: (property: GenerationProperty, newValue: object) => void;
890
890
  }) => {
@@ -1039,7 +1039,7 @@ export const FileGenerationConfigurationEditor = observer(
1039
1039
  [handleDrop],
1040
1040
  );
1041
1041
 
1042
- const getConfigValue = (name: string): unknown | undefined =>
1042
+ const getConfigValue = (name: string): unknown =>
1043
1043
  getNullableFileGenerationConfig(fileGeneration, name)?.value;
1044
1044
 
1045
1045
  return (
@@ -77,7 +77,7 @@ export const SchemaSetModelGenerationEditor = observer(
77
77
  const resetProperties = (): void => {
78
78
  modelGenerationState.setConfigurationProperty([]);
79
79
  };
80
- const getConfigValue = (name: string): unknown | undefined =>
80
+ const getConfigValue = (name: string): unknown =>
81
81
  modelGenerationState.getConfigValue(name);
82
82
  const targetBindingPathValidationMessage =
83
83
  Boolean(modelGenerationState.targetBinding) &&
@@ -118,7 +118,7 @@ export const InstanceSetImplementationSourceExplorer = observer(
118
118
  const [
119
119
  sourceElementForSourceSelectorModal,
120
120
  setSourceElementForSourceSelectorModal,
121
- ] = useState<MappingElementSource | undefined | null>();
121
+ ] = useState<MappingElementSource>();
122
122
  const CHANGING_SOURCE_ON_EMBEDDED =
123
123
  'Changing source on mapping with embedded children will delete all its children';
124
124
  const showSourceSelectorModal = (): void => {
@@ -70,9 +70,7 @@ export interface MappingElementSourceSelectOption {
70
70
  value: unknown;
71
71
  }
72
72
 
73
- export const getSourceElementLabel = (
74
- srcElement: unknown | undefined,
75
- ): string => {
73
+ export const getSourceElementLabel = (srcElement: unknown): string => {
76
74
  let sourceLabel = '(none)';
77
75
  if (srcElement instanceof Class) {
78
76
  sourceLabel = srcElement.name;
@@ -90,7 +88,7 @@ export const getSourceElementLabel = (
90
88
 
91
89
  // TODO: add more visual cue to the type of source (class vs. flat-data vs. db)
92
90
  export const buildMappingElementSourceOption = (
93
- source: MappingElementSource | undefined,
91
+ source: MappingElementSource,
94
92
  ): MappingElementSourceSelectOption | null => {
95
93
  if (source instanceof Class) {
96
94
  return buildElementOption(source) as MappingElementSourceSelectOption;
@@ -120,7 +118,7 @@ export const InstanceSetImplementationSourceSelectorModal = observer(
120
118
  * Pass in `null` when we want to open the modal using the existing source.
121
119
  * Pass any other to open the source modal using that value as the initial state of the modal.
122
120
  */
123
- sourceElementToSelect: MappingElementSource | null;
121
+ sourceElementToSelect: MappingElementSource;
124
122
  closeModal: () => void;
125
123
  }) => {
126
124
  const {
@@ -662,13 +662,11 @@ export const ProjectConfigurationEditor = observer(() => {
662
662
  const dependencyToAdd = new ProjectDependency(
663
663
  projectToAdd.coordinates,
664
664
  );
665
- const versions = (await flowResult(
666
- editorStore.depotServerClient.getVersions(
667
- projectToAdd.groupId,
668
- projectToAdd.artifactId,
669
- true,
670
- ),
671
- )) as string[];
665
+ const versions = await editorStore.depotServerClient.getVersions(
666
+ projectToAdd.groupId,
667
+ projectToAdd.artifactId,
668
+ true,
669
+ );
672
670
  configState.versions.set(dependencyToAdd.projectId, versions);
673
671
  dependencyToAdd.setVersionId(versions[0] ?? '');
674
672
  currentProjectConfiguration.addProjectDependency(dependencyToAdd);
@@ -785,17 +785,15 @@ const ProjectVersionDependencyEditor = observer(
785
785
  if (val) {
786
786
  try {
787
787
  fetchSelectedProjectVersionsStatus.inProgress();
788
- const v = (await flowResult(
789
- editorStore.depotServerClient.getVersions(
790
- guaranteeNonNullable(projectDependency.groupId),
791
- guaranteeNonNullable(projectDependency.artifactId),
792
- true,
793
- ),
794
- )) as string[];
795
- configState.versions.set(val.value.coordinates, v);
796
- if (v.length) {
788
+ const _versions = await editorStore.depotServerClient.getVersions(
789
+ guaranteeNonNullable(projectDependency.groupId),
790
+ guaranteeNonNullable(projectDependency.artifactId),
791
+ true,
792
+ );
793
+ configState.versions.set(val.value.coordinates, _versions);
794
+ if (_versions.length) {
797
795
  projectDependency.setVersionId(
798
- guaranteeNonNullable(v[v.length - 1]),
796
+ guaranteeNonNullable(_versions[_versions.length - 1]),
799
797
  );
800
798
  flowResult(dependencyEditorState.fetchDependencyReport()).catch(
801
799
  applicationStore.alertUnhandledError,
@@ -435,7 +435,9 @@ export const GlobalTestRunner = observer(
435
435
 
436
436
  const extractTestRunnerTabConfigurations = editorStore.pluginManager
437
437
  .getApplicationPlugins()
438
- .flatMap((plugin) => plugin.getExtraTestRunnerTabConfigurations?.() ?? [])
438
+ .flatMap(
439
+ (plugin) => plugin.getExtraTestRunnerViewConfigurations?.() ?? [],
440
+ )
439
441
  .filter((configuration) => configuration.renderer(editorStore));
440
442
 
441
443
  const testRunnerTabs = (Object.values(TEST_RUNNER_TABS) as string[])
@@ -22,6 +22,8 @@ import {
22
22
  type SettingConfigurationEntry,
23
23
  collectSettingConfigurationEntriesFromConfig,
24
24
  type LegendApplicationSetup,
25
+ type VirtualAssistantViewConfiguration,
26
+ type ApplicationExtensionStateBuilder,
25
27
  } from '@finos/legend-application';
26
28
  import packageJson from '../../../package.json' assert { type: 'json' };
27
29
  import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js';
@@ -40,6 +42,12 @@ import {
40
42
  setupPureLanguageService,
41
43
  } from '@finos/legend-lego/code-editor';
42
44
  import { STO_RELATIONAL_LEGEND_STUDIO_COMMAND_CONFIG } from '../../__lib__/STO_Relational_LegendStudioCommand.js';
45
+ import { ShowcaseManager } from '../ShowcaseManager.js';
46
+ import { CabinetIcon } from '@finos/legend-art';
47
+ import { ShowcaseManagerState } from '../../stores/ShowcaseManagerState.js';
48
+ import type { LegendStudioApplicationStore } from '../../stores/LegendStudioBaseStore.js';
49
+
50
+ export const SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY = 'showcase-manager';
43
51
 
44
52
  export class Core_LegendStudioApplicationPlugin extends LegendStudioApplicationPlugin {
45
53
  static NAME = packageJson.extensions.applicationStudioPlugin;
@@ -48,6 +56,15 @@ export class Core_LegendStudioApplicationPlugin extends LegendStudioApplicationP
48
56
  super(Core_LegendStudioApplicationPlugin.NAME, packageJson.version);
49
57
  }
50
58
 
59
+ override getExtraApplicationExtensionStateBuilders(): ApplicationExtensionStateBuilder[] {
60
+ return [
61
+ (applicationStore) =>
62
+ new ShowcaseManagerState(
63
+ applicationStore as LegendStudioApplicationStore,
64
+ ),
65
+ ];
66
+ }
67
+
51
68
  override getExtraApplicationSetups(): LegendApplicationSetup[] {
52
69
  return [
53
70
  async (applicationStore) => {
@@ -151,4 +168,16 @@ export class Core_LegendStudioApplicationPlugin extends LegendStudioApplicationP
151
168
  LEGEND_STUDIO_SETTING_CONFIG,
152
169
  );
153
170
  }
171
+
172
+ override getExtraVirtualAssistantViewConfigurations(): VirtualAssistantViewConfiguration[] {
173
+ return [
174
+ {
175
+ key: SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY,
176
+ title: 'Showcases',
177
+ icon: <CabinetIcon />,
178
+ autoExpandOnOpen: true,
179
+ renderer: () => <ShowcaseManager />,
180
+ },
181
+ ];
182
+ }
154
183
  }
@@ -62,7 +62,7 @@ import {
62
62
  useLegendStudioApplicationStore,
63
63
  useLegendStudioBaseStore,
64
64
  } from '../LegendStudioFrameworkProvider.js';
65
- import { EmbeddedQueryBuilder } from '../EmbeddedQueryBuilder.js';
65
+ import { EmbeddedQueryBuilder } from '../editor/EmbeddedQueryBuilder.js';
66
66
  import type { ActivityBarItemConfig } from '@finos/legend-lego/application';
67
67
  import { ActivityBarMenu } from '../editor/ActivityBar.js';
68
68
 
package/src/index.ts CHANGED
@@ -29,7 +29,7 @@ export {
29
29
  useLegendStudioApplicationStore,
30
30
  useLegendStudioBaseStore,
31
31
  } from './components/LegendStudioFrameworkProvider.js';
32
- export type { LegendStudioApplicationStore } from './stores/LegendStudioBaseStore.js';
32
+ export { type LegendStudioApplicationStore } from './stores/LegendStudioBaseStore.js';
33
33
 
34
34
  // stores
35
35
  export * from './stores/LegendStudioApplicationPlugin.js';