@finos/legend-application-studio 27.1.1 → 27.1.3

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 (145) hide show
  1. package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts +1 -1
  2. package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioApplicationNavigationContext.js +1 -1
  4. package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
  5. package/lib/__lib__/LegendStudioDocumentation.d.ts +3 -1
  6. package/lib/__lib__/LegendStudioDocumentation.d.ts.map +1 -1
  7. package/lib/__lib__/LegendStudioDocumentation.js +3 -0
  8. package/lib/__lib__/LegendStudioDocumentation.js.map +1 -1
  9. package/lib/__lib__/LegendStudioTesting.d.ts +1 -0
  10. package/lib/__lib__/LegendStudioTesting.d.ts.map +1 -1
  11. package/lib/__lib__/LegendStudioTesting.js +1 -0
  12. package/lib/__lib__/LegendStudioTesting.js.map +1 -1
  13. package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
  14. package/lib/application/LegendStudioApplicationConfig.js +1 -1
  15. package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
  16. package/lib/components/editor/editor-group/FunctionEditor.d.ts.map +1 -1
  17. package/lib/components/editor/editor-group/FunctionEditor.js +29 -25
  18. package/lib/components/editor/editor-group/FunctionEditor.js.map +1 -1
  19. package/lib/components/editor/editor-group/connection-editor/{DatabaseBuilder.d.ts → DatabaseBuilderWizard.d.ts} +4 -11
  20. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.d.ts.map +1 -0
  21. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js +48 -0
  22. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.js.map +1 -0
  23. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.d.ts +32 -0
  24. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.d.ts.map +1 -0
  25. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.js +99 -0
  26. package/lib/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.js.map +1 -0
  27. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +1 -1
  28. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  29. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.d.ts.map +1 -1
  30. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js +2 -2
  31. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js.map +1 -1
  32. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.d.ts.map +1 -1
  33. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.js +47 -12
  34. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.js.map +1 -1
  35. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.d.ts.map +1 -1
  36. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js +61 -11
  37. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js.map +1 -1
  38. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
  39. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +1 -1
  40. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
  41. package/lib/components/editor/editor-group/uml-editor/ClassEditor.d.ts.map +1 -1
  42. package/lib/components/editor/editor-group/uml-editor/ClassEditor.js +24 -25
  43. package/lib/components/editor/editor-group/uml-editor/ClassEditor.js.map +1 -1
  44. package/lib/components/editor/editor-group/uml-editor/EnumerationEditor.js +2 -2
  45. package/lib/components/editor/editor-group/uml-editor/EnumerationEditor.js.map +1 -1
  46. package/lib/components/editor/editor-group/uml-editor/ProfileEditor.js +3 -3
  47. package/lib/components/editor/editor-group/uml-editor/ProfileEditor.js.map +1 -1
  48. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js +2 -2
  49. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js.map +1 -1
  50. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js +2 -2
  51. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js.map +1 -1
  52. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts +0 -7
  53. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts.map +1 -1
  54. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js +20 -77
  55. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js.map +1 -1
  56. package/lib/components/editor/side-bar/Explorer.js +3 -3
  57. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  58. package/lib/components/editor/side-bar/ProjectOverview.d.ts.map +1 -1
  59. package/lib/components/editor/side-bar/ProjectOverview.js +7 -1
  60. package/lib/components/editor/side-bar/ProjectOverview.js.map +1 -1
  61. package/lib/components/editor/side-bar/WorkflowManager.d.ts.map +1 -1
  62. package/lib/components/editor/side-bar/WorkflowManager.js +6 -1
  63. package/lib/components/editor/side-bar/WorkflowManager.js.map +1 -1
  64. package/lib/index.css +2 -2
  65. package/lib/index.css.map +1 -1
  66. package/lib/package.json +3 -3
  67. package/lib/stores/editor/ExplorerTreeState.d.ts +4 -4
  68. package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
  69. package/lib/stores/editor/ExplorerTreeState.js +4 -4
  70. package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
  71. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +12 -12
  72. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
  73. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +46 -47
  74. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
  75. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts +20 -29
  76. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.d.ts.map +1 -1
  77. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js +60 -141
  78. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.js.map +1 -1
  79. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts +33 -0
  80. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.d.ts.map +1 -0
  81. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js +71 -0
  82. package/lib/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js.map +1 -0
  83. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.js +1 -1
  84. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.js.map +1 -1
  85. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts +1 -1
  86. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
  87. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js +2 -2
  88. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
  89. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js +1 -1
  90. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js.map +1 -1
  91. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js +1 -1
  92. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
  93. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts +6 -2
  94. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts.map +1 -1
  95. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js +39 -3
  96. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js.map +1 -1
  97. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts +3 -48
  98. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts.map +1 -1
  99. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js +12 -350
  100. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js.map +1 -1
  101. package/lib/stores/editor/sidebar-state/WorkflowManagerState.d.ts +5 -0
  102. package/lib/stores/editor/sidebar-state/WorkflowManagerState.d.ts.map +1 -1
  103. package/lib/stores/editor/sidebar-state/WorkflowManagerState.js +26 -0
  104. package/lib/stores/editor/sidebar-state/WorkflowManagerState.js.map +1 -1
  105. package/lib/stores/editor/utils/TestableUtils.js +2 -2
  106. package/lib/stores/editor/utils/TestableUtils.js.map +1 -1
  107. package/package.json +10 -10
  108. package/src/__lib__/LegendStudioApplicationNavigationContext.ts +1 -1
  109. package/src/__lib__/LegendStudioDocumentation.ts +4 -0
  110. package/src/__lib__/LegendStudioTesting.ts +1 -0
  111. package/src/application/LegendStudioApplicationConfig.ts +1 -1
  112. package/src/components/editor/editor-group/FunctionEditor.tsx +137 -122
  113. package/src/components/editor/editor-group/connection-editor/DatabaseBuilderWizard.tsx +191 -0
  114. package/src/components/editor/editor-group/connection-editor/DatabaseSchemaExplorer.tsx +227 -0
  115. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +1 -1
  116. package/src/components/editor/editor-group/mapping-editor/MappingEditor.tsx +5 -2
  117. package/src/components/editor/editor-group/mapping-editor/MappingTestableEditor.tsx +68 -17
  118. package/src/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.tsx +137 -12
  119. package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +0 -1
  120. package/src/components/editor/editor-group/uml-editor/ClassEditor.tsx +354 -362
  121. package/src/components/editor/editor-group/uml-editor/EnumerationEditor.tsx +4 -4
  122. package/src/components/editor/editor-group/uml-editor/ProfileEditor.tsx +7 -7
  123. package/src/components/editor/editor-group/uml-editor/StereotypeSelector.tsx +4 -4
  124. package/src/components/editor/editor-group/uml-editor/TaggedValueEditor.tsx +4 -4
  125. package/src/components/editor/panel-group/SQLPlaygroundPanel.tsx +47 -211
  126. package/src/components/editor/side-bar/Explorer.tsx +3 -3
  127. package/src/components/editor/side-bar/ProjectOverview.tsx +14 -3
  128. package/src/components/editor/side-bar/WorkflowManager.tsx +10 -0
  129. package/src/stores/editor/ExplorerTreeState.ts +6 -9
  130. package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +45 -51
  131. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +88 -212
  132. package/src/stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.ts +102 -0
  133. package/src/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.ts +1 -1
  134. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +2 -2
  135. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.ts +1 -1
  136. package/src/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.ts +1 -1
  137. package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.ts +59 -2
  138. package/src/stores/editor/panel-group/SQLPlaygroundPanelState.ts +13 -533
  139. package/src/stores/editor/sidebar-state/WorkflowManagerState.ts +47 -0
  140. package/src/stores/editor/utils/TestableUtils.ts +2 -2
  141. package/tsconfig.json +3 -1
  142. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.d.ts.map +0 -1
  143. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js +0 -133
  144. package/lib/components/editor/editor-group/connection-editor/DatabaseBuilder.js.map +0 -1
  145. package/src/components/editor/editor-group/connection-editor/DatabaseBuilder.tsx +0 -397
@@ -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
  );
@@ -357,7 +357,10 @@ export const MappingEditorWithTestable = observer(() => {
357
357
  (): void =>
358
358
  mappingEditorState.setSelectedTab(tab);
359
359
  return (
360
- <div className="service-editor">
360
+ <div
361
+ data-testid={LEGEND_STUDIO_TEST_ID.MAPPING_EDITOR}
362
+ className="service-editor"
363
+ >
361
364
  <div className="panel">
362
365
  <div className="panel__header">
363
366
  <div className="panel__header__title">
@@ -389,7 +392,7 @@ export const MappingEditorWithTestable = observer(() => {
389
392
  {selectedTab === MAPPING_EDITOR_TAB.CLASS_MAPPINGS && (
390
393
  <_MappingEditor />
391
394
  )}
392
- {selectedTab === MAPPING_EDITOR_TAB.BETA_TEST_SUITES && (
395
+ {selectedTab === MAPPING_EDITOR_TAB.TEST_SUITES && (
393
396
  <MappingTestableEditor
394
397
  mappingTestableState={mappingEditorState.mappingTestableState}
395
398
  />
@@ -20,6 +20,7 @@ import {
20
20
  type MappingTestSuite,
21
21
  type Store,
22
22
  type DataElement,
23
+ type EmbeddedData,
23
24
  ModelStore,
24
25
  Database,
25
26
  getMappingCompatibleClasses,
@@ -28,6 +29,10 @@ import {
28
29
  MappingTest,
29
30
  PackageableElementExplicitReference,
30
31
  DataElementReference,
32
+ RelationalCSVData,
33
+ ModelStoreData,
34
+ ExternalFormatData,
35
+ ModelEmbeddedData,
31
36
  } from '@finos/legend-graph';
32
37
  import { forwardRef, useEffect, useRef, useState } from 'react';
33
38
  import {
@@ -208,6 +213,7 @@ const CreateTestSuiteModal = observer(
208
213
  name="Test Suite Name"
209
214
  prompt="Unique Identifier for Test suite i.e Person_suite"
210
215
  value={suiteName}
216
+ placeholder="Suite Name"
211
217
  update={(value: string | undefined): void =>
212
218
  setSuiteName(value ?? '')
213
219
  }
@@ -216,6 +222,7 @@ const CreateTestSuiteModal = observer(
216
222
  <PanelFormTextField
217
223
  name="Test Name"
218
224
  prompt="Unique Identifier for first test in suite"
225
+ placeholder="Test Name"
219
226
  value={testName}
220
227
  update={(value: string | undefined): void =>
221
228
  setTestName(value ?? '')
@@ -245,7 +252,11 @@ const CreateTestSuiteModal = observer(
245
252
  disabled={
246
253
  !isValid || creatorState.isCreatingSuiteState.isInProgress
247
254
  }
248
- title={'Create Test'}
255
+ title={
256
+ !isValid
257
+ ? 'Suite Name and Test Name Required'
258
+ : 'Create Test Suite'
259
+ }
249
260
  onClick={create}
250
261
  text="Create"
251
262
  />
@@ -648,30 +659,30 @@ const MappingTestSuiteQueryEditor = observer(
648
659
  <div className="panel__header__title__label">query</div>
649
660
  </div>
650
661
  <div className="panel__header__actions">
651
- <div className="mapping-test-editor__action-btn">
662
+ <div className="btn__dropdown-combo">
652
663
  <button
653
- className="mapping-test-editor__action-btn__label"
664
+ className="btn__dropdown-combo__label"
654
665
  onClick={editWithQueryBuilder()}
655
666
  title="Edit Query"
656
667
  tabIndex={-1}
657
668
  >
658
- <PencilIcon className="mapping-test-editor__action-btn__label__icon" />
659
- <div className="mapping-test-editor__action-btn__label__title">
669
+ <PencilIcon className="btn__dropdown-combo__label__icon" />
670
+ <div className="btn__dropdown-combo__label__title">
660
671
  Edit Query
661
672
  </div>
662
673
  </button>
663
674
  <DropdownMenu
664
- className="mapping-test-editor__action-btn__dropdown-btn"
675
+ className="btn__dropdown-combo__dropdown-btn"
665
676
  content={
666
677
  <MenuContent>
667
678
  <MenuContentItem
668
- className="mapping-test-editor__action-btn__option"
679
+ className="btn__dropdown-combo__option"
669
680
  onClick={editWithQueryBuilder(true)}
670
681
  >
671
682
  Text Mode
672
683
  </MenuContentItem>
673
684
  <MenuContentItem
674
- className="mapping-test-editor__action-btn__option"
685
+ className="btn__dropdown-combo__option"
675
686
  onClick={clearQuery}
676
687
  >
677
688
  Clear Query
@@ -715,14 +726,14 @@ const StoreTestDataEditor = observer(
715
726
  mappingTestState.mappingTestableState.mappingEditorState.isReadOnly;
716
727
  const dataElements =
717
728
  storeTestDataState.editorStore.graphManagerState.graph.dataElements;
718
- const data = storeTestDataState.storeTestData.data;
719
- const isUsingReference = data instanceof DataElementReference;
729
+ const currentData = storeTestDataState.storeTestData.data;
730
+ const isUsingReference = currentData instanceof DataElementReference;
720
731
  const open = (): void => storeTestDataState.setDataElementModal(true);
721
732
  const close = (): void => storeTestDataState.setDataElementModal(false);
722
733
  const changeToUseMyOwn = (): void => {
723
734
  if (isUsingReference) {
724
735
  const newBare = returnUndefOnError(() =>
725
- data.accept_EmbeddedDataVisitor(
736
+ currentData.accept_EmbeddedDataVisitor(
726
737
  new EmbeddedDataCreatorFromEmbeddedData(),
727
738
  ),
728
739
  );
@@ -732,10 +743,49 @@ const StoreTestDataEditor = observer(
732
743
  }
733
744
  };
734
745
 
735
- const handler = (val: DataElement): void => {
736
- const value = new DataElementReference();
737
- value.dataElement = PackageableElementExplicitReference.create(val);
738
- storeTestDataState.changeEmbeddedData(value);
746
+ const sharedDataHandler = (val: DataElement): void => {
747
+ const dataRef = new DataElementReference();
748
+ dataRef.dataElement = PackageableElementExplicitReference.create(val);
749
+ const dataElementValue = val.data;
750
+ let embeddedData: EmbeddedData = dataRef;
751
+ if (
752
+ currentData instanceof ModelStoreData &&
753
+ dataElementValue instanceof ExternalFormatData
754
+ ) {
755
+ const modelStoreVal = currentData.modelData?.[0];
756
+ if (modelStoreVal instanceof ModelEmbeddedData) {
757
+ const newModelEmbeddedData = new ModelEmbeddedData();
758
+ newModelEmbeddedData.model =
759
+ PackageableElementExplicitReference.create(
760
+ modelStoreVal.model.value,
761
+ );
762
+
763
+ newModelEmbeddedData.data = dataRef;
764
+ const modelStoreData = new ModelStoreData();
765
+ modelStoreData.modelData = [newModelEmbeddedData];
766
+ embeddedData = modelStoreData;
767
+ }
768
+ }
769
+ storeTestDataState.changeEmbeddedData(embeddedData);
770
+ };
771
+ const filter = (val: DataElement): boolean => {
772
+ const dataElementData = val.data;
773
+ if (currentData instanceof RelationalCSVData) {
774
+ if (dataElementData instanceof RelationalCSVData) {
775
+ return true;
776
+ }
777
+ return false;
778
+ } else if (currentData instanceof ModelStoreData) {
779
+ if (
780
+ dataElementData instanceof ExternalFormatData ||
781
+ dataElementData instanceof ModelStoreData
782
+ ) {
783
+ return true;
784
+ }
785
+ return false;
786
+ }
787
+ // TODO add extensions
788
+ return true;
739
789
  };
740
790
  return (
741
791
  <div className="service-test-data-editor">
@@ -783,7 +833,8 @@ const StoreTestDataEditor = observer(
783
833
  isReadOnly={false}
784
834
  editorStore={storeTestDataState.editorStore}
785
835
  close={close}
786
- handler={handler}
836
+ filterBy={filter}
837
+ handler={sharedDataHandler}
787
838
  />
788
839
  )}
789
840
  <EmbeddedDataEditor
@@ -1241,7 +1292,7 @@ export const MappingTestableEditor = observer(
1241
1292
  };
1242
1293
 
1243
1294
  useApplicationNavigationContext(
1244
- LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MAPPING_TEST_EDITOR,
1295
+ LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MAPPING_EDITOR_TEST,
1245
1296
  );
1246
1297
  return (
1247
1298
  <div className="service-test-suite-editor panel">
@@ -20,6 +20,7 @@ import { observer } from 'mobx-react-lite';
20
20
  import {
21
21
  ProjectConfigurationEditorState,
22
22
  CONFIGURATION_EDITOR_TAB,
23
+ projectTypeTabFilter,
23
24
  } from '../../../../stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js';
24
25
  import {
25
26
  clsx,
@@ -41,13 +42,16 @@ import {
41
42
  PanelContent,
42
43
  PanelHeader,
43
44
  PanelContentLists,
45
+ PanelLoadingIndicator,
44
46
  } from '@finos/legend-art';
45
47
  import { flowResult } from 'mobx';
46
48
  import {
47
49
  type Platform,
50
+ type ProjectConfiguration,
51
+ type ProjectStructureVersion,
48
52
  PlatformConfiguration,
49
53
  ProjectDependency,
50
- type ProjectConfiguration,
54
+ ProjectType,
51
55
  } from '@finos/legend-server-sdlc';
52
56
  import { useEditorStore } from '../../EditorStoreProvider.js';
53
57
  import {
@@ -64,6 +68,28 @@ import {
64
68
  } from '@finos/legend-lego/application';
65
69
  import type { StoreProjectData } from '@finos/legend-server-depot';
66
70
 
71
+ const isProjectConfigurationVersionOutdated = (
72
+ projectConfig: ProjectConfiguration,
73
+ latestVersion: ProjectStructureVersion | undefined,
74
+ isEmbeddedMode: boolean,
75
+ ): boolean => {
76
+ if (!latestVersion) {
77
+ return false;
78
+ }
79
+ const mainVersionOutdated =
80
+ latestVersion.version > projectConfig.projectStructureVersion.version;
81
+ if (isEmbeddedMode) {
82
+ return mainVersionOutdated;
83
+ }
84
+ const currentProjectExtensionVersion =
85
+ projectConfig.projectStructureVersion.extensionVersion ?? -1;
86
+ const latestProjectExtensionVersion = latestVersion.extensionVersion ?? -1;
87
+ return (
88
+ mainVersionOutdated ||
89
+ latestProjectExtensionVersion > currentProjectExtensionVersion
90
+ );
91
+ };
92
+
67
93
  const ProjectStructureEditor = observer(
68
94
  (props: { projectConfig: ProjectConfiguration; isReadOnly: boolean }) => {
69
95
  const { projectConfig, isReadOnly } = props;
@@ -71,13 +97,12 @@ const ProjectStructureEditor = observer(
71
97
  const applicationStore = useApplicationStore();
72
98
  const latestVersion =
73
99
  editorStore.projectConfigurationEditorState.latestProjectStructureVersion;
74
- const currentProjectExtensionVersion =
75
- projectConfig.projectStructureVersion.extensionVersion ?? -1;
76
- const latestProjectExtensionVersion = latestVersion?.extensionVersion ?? -1;
77
- const isVersionOutdated =
78
- latestVersion &&
79
- (latestVersion.version > projectConfig.projectStructureVersion.version ||
80
- latestProjectExtensionVersion > currentProjectExtensionVersion);
100
+ const isProjectStructureVersionOutdated =
101
+ isProjectConfigurationVersionOutdated(
102
+ projectConfig,
103
+ latestVersion,
104
+ editorStore.projectConfigurationEditorState.isInEmbeddedMode,
105
+ );
81
106
  const isGroupIdChanged =
82
107
  editorStore.projectConfigurationEditorState.isGroupIdChanged;
83
108
  const isArtifactIdChanged =
@@ -108,7 +133,7 @@ const ProjectStructureEditor = observer(
108
133
  <div className="project-configuration-editor__project__structure__version">
109
134
  <div className="project-configuration-editor__project__structure__version__label">
110
135
  <div className="project-configuration-editor__project__structure__version__label__status">
111
- {isVersionOutdated ? (
136
+ {isProjectStructureVersionOutdated ? (
112
137
  <ExclamationCircleIcon
113
138
  className="project-configuration-editor__project__structure__version__label__status--outdated"
114
139
  title="Project structure is outdated"
@@ -124,7 +149,7 @@ const ProjectStructureEditor = observer(
124
149
  {`PROJECT STRUCTURE VERSION ${projectConfig.projectStructureVersion.fullVersion}`}
125
150
  </div>
126
151
  </div>
127
- {isVersionOutdated && (
152
+ {isProjectStructureVersionOutdated && latestVersion && (
128
153
  <button
129
154
  className="project-configuration-editor__project__structure__version__update-btn"
130
155
  disabled={isReadOnly}
@@ -132,7 +157,10 @@ const ProjectStructureEditor = observer(
132
157
  tabIndex={-1}
133
158
  title={`Current project structure is outdated. Click to update to the latest version (v${latestVersion.fullVersion}})`}
134
159
  >
135
- Update to version {latestVersion.fullVersion}
160
+ Update to version{' '}
161
+ {editorStore.projectConfigurationEditorState.isInEmbeddedMode
162
+ ? latestVersion.version
163
+ : latestVersion.fullVersion}
136
164
  </button>
137
165
  )}
138
166
  </div>
@@ -511,20 +539,106 @@ const ProjectPlatformVersionEditor = observer(
511
539
  },
512
540
  );
513
541
 
542
+ const ProjectAdvancedEditor = observer(
543
+ (props: { projectConfig: ProjectConfiguration; isReadOnly: boolean }) => {
544
+ const { projectConfig } = props;
545
+ const editorStore = useEditorStore();
546
+ const applicationStore = useApplicationStore();
547
+ const currentProjectType = projectConfig.projectType ?? ProjectType.MANAGED;
548
+ const isEmbeddedMode = currentProjectType === ProjectType.EMBEDDED;
549
+ const managedModeBlurb =
550
+ 'Managed Projects are managed by our SDLC server, which includes managing the build and deployment of your project.This enables rich features such as releasing and dependency management work within our ecosystem.This is the recommended mode and should not be changed unless your customized build is robust to handle these operations and you are aware of the different features our managed mode provides.';
551
+ const embeddedModeBlurb =
552
+ 'Embedded Projects have their own customized build. The build is managed directly on the underlying version system (gitlab, github etc) and the owners of the projects are responsible for managing their build and incorporating the necessary steps to enable features such as releasing and dependency management. Our SDLC server still manages the file structure of where the elements entities are located and correlate with the project structure version.';
553
+ const managedToEmbedded =
554
+ 'You are about to change from managed to embedded project type. This will cause your build files (pom, ci etc) to no longer be managed by our SDLC process. Your element folder structure will remain managed by us but your build will become your responsibility. Please ensure you understand the risks of changing over before continuing.';
555
+ const embeddedToManaged =
556
+ 'You are about to change from embedded to managed project type. Your build will now be managed by our SDLC sever in addition to your element folder structure. Your current build files will all be deleted and replaces with our own. Please ensure you understand the risks of changing over before continuing.';
557
+ const changeProjectType = (): void => {
558
+ applicationStore.alertService.setActionAlertInfo({
559
+ message: `${isEmbeddedMode ? embeddedToManaged : managedToEmbedded}`,
560
+ prompt: 'Do you want to proceed?',
561
+ type: ActionAlertType.CAUTION,
562
+ actions: [
563
+ {
564
+ label: 'Continue',
565
+ type: ActionAlertActionType.PROCEED_WITH_CAUTION,
566
+ handler: () => {
567
+ flowResult(
568
+ editorStore.projectConfigurationEditorState.changeProjectType(),
569
+ ).catch(applicationStore.alertUnhandledError);
570
+ },
571
+ },
572
+ {
573
+ label: 'Cancel',
574
+ type: ActionAlertActionType.PROCEED,
575
+ default: true,
576
+ },
577
+ ],
578
+ });
579
+ };
580
+
581
+ return (
582
+ <Panel>
583
+ <PanelForm>
584
+ <div className="panel__content__form__section__header__label">
585
+ {`Project Type: ${prettyCONSTName(currentProjectType)} `}
586
+ </div>
587
+ <div className="documentation-preview">
588
+ <div className="documentation-preview__text">
589
+ <div className="project-configuration-editor__advanced__project-type__info">
590
+ {managedModeBlurb}
591
+ </div>
592
+ <div className="project-configuration-editor__advanced__project-type__info">
593
+ {embeddedModeBlurb}
594
+ </div>
595
+ </div>
596
+
597
+ <div className="documentation-preview__hint">
598
+ <DocumentationLink
599
+ documentationKey={
600
+ LEGEND_STUDIO_DOCUMENTATION_KEY.QUESTION_WHAT_IS_EMBEDDED_MODE_PROJECT_TYPE
601
+ }
602
+ />
603
+ </div>
604
+ </div>
605
+ <div className="platform-configurations-editor__dependencies">
606
+ <div className="platform-configurations-editor__dependencies__header">
607
+ <button
608
+ className="btn--dark btn--conflict btn--important project-configuration-editor__advanced__caution__btn"
609
+ onClick={changeProjectType}
610
+ tabIndex={-1}
611
+ >
612
+ {`Change to ${
613
+ isEmbeddedMode ? 'Managed Type' : 'Embedded Type'
614
+ }`}
615
+ </button>
616
+ </div>
617
+ </div>
618
+ </PanelForm>
619
+ </Panel>
620
+ );
621
+ },
622
+ );
623
+
514
624
  export const ProjectConfigurationEditor = observer(() => {
515
625
  const editorStore = useEditorStore();
516
626
  const applicationStore = useApplicationStore();
517
627
  const configState = editorStore.tabManagerState.getCurrentEditorState(
518
628
  ProjectConfigurationEditorState,
519
629
  );
630
+ const projectType =
631
+ configState.originalConfig.projectType ?? ProjectType.MANAGED;
520
632
  const sdlcState = editorStore.sdlcState;
521
633
  const isReadOnly = editorStore.isInViewerMode;
522
634
  const selectedTab = configState.selectedTab;
635
+ const dependencyEditorState = configState.projectDependencyEditorState;
523
636
  const tabs = [
524
637
  CONFIGURATION_EDITOR_TAB.PROJECT_STRUCTURE,
525
638
  CONFIGURATION_EDITOR_TAB.PROJECT_DEPENDENCIES,
526
639
  CONFIGURATION_EDITOR_TAB.PLATFORM_CONFIGURATIONS,
527
- ];
640
+ CONFIGURATION_EDITOR_TAB.ADVANCED,
641
+ ].filter((tab) => projectTypeTabFilter(projectType, tab));
528
642
  const changeTab =
529
643
  (tab: CONFIGURATION_EDITOR_TAB): (() => void) =>
530
644
  (): void =>
@@ -664,6 +778,10 @@ export const ProjectConfigurationEditor = observer(() => {
664
778
  if (!configState.projectConfiguration) {
665
779
  return null;
666
780
  }
781
+ const isLoading =
782
+ configState.updatingConfigurationState.isInProgress ||
783
+ configState.fetchingProjectVersionsState.isInProgress ||
784
+ dependencyEditorState.fetchingDependencyInfoState.isInProgress;
667
785
  return (
668
786
  <div className="project-configuration-editor">
669
787
  <Panel>
@@ -717,6 +835,7 @@ export const ProjectConfigurationEditor = observer(() => {
717
835
  </PanelHeaderActions>
718
836
  </PanelHeader>
719
837
  <PanelContent className="project-configuration-editor__content">
838
+ <PanelLoadingIndicator isLoading={isLoading} />
720
839
  {selectedTab === CONFIGURATION_EDITOR_TAB.PROJECT_STRUCTURE && (
721
840
  <ProjectStructureEditor
722
841
  projectConfig={currentProjectConfiguration}
@@ -732,6 +851,12 @@ export const ProjectConfigurationEditor = observer(() => {
732
851
  isReadOnly={isReadOnly}
733
852
  />
734
853
  )}
854
+ {selectedTab === CONFIGURATION_EDITOR_TAB.ADVANCED && (
855
+ <ProjectAdvancedEditor
856
+ projectConfig={currentProjectConfiguration}
857
+ isReadOnly={isReadOnly}
858
+ />
859
+ )}
735
860
  </PanelContent>
736
861
  </Panel>
737
862
  </div>
@@ -995,7 +995,6 @@ export const ProjectDependencyEditor = observer(() => {
995
995
 
996
996
  return (
997
997
  <PanelContentLists>
998
- <PanelLoadingIndicator isLoading={isLoading} />
999
998
  {isLoading && (
1000
999
  <div className="project-dependency-editor__progress-msg">
1001
1000
  {configState.updatingConfigurationState.isInProgress