@finos/legend-application-studio 28.21.16 → 28.21.18
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.
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +5 -3
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +1 -19
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js +3 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +11 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/ClassEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/ClassEditor.js +14 -5
- package/lib/components/editor/editor-group/uml-editor/ClassEditor.js.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/PropertyEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/PropertyEditor.js +4 -1
- package/lib/components/editor/editor-group/uml-editor/PropertyEditor.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +2 -4
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +98 -64
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js +6 -0
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js.map +1 -1
- package/package.json +9 -9
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +5 -3
- package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +3 -32
- package/src/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.tsx +11 -1
- package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +19 -2
- package/src/components/editor/editor-group/uml-editor/ClassEditor.tsx +24 -0
- package/src/components/editor/editor-group/uml-editor/PropertyEditor.tsx +7 -0
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +145 -85
- package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.ts +17 -0
package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx
CHANGED
|
@@ -861,20 +861,9 @@ const FunctionTestDataPanel = observer(
|
|
|
861
861
|
(props: { functionTestSuiteState: FunctionTestSuiteState }) => {
|
|
862
862
|
const { functionTestSuiteState } = props;
|
|
863
863
|
const dataState = functionTestSuiteState.dataState;
|
|
864
|
-
const hasIngestOrDataProductAccessors =
|
|
865
|
-
functionTestSuiteState.functionTestableState
|
|
866
|
-
.resolvedIngestOrDataProductAccessors.length > 0;
|
|
867
864
|
const hasTestData = Boolean(dataState.dataHolder.testData?.length);
|
|
868
865
|
|
|
869
866
|
const addStoreTestData = (): void => {
|
|
870
|
-
if (!dataState.availableElementsToAdd.length) {
|
|
871
|
-
functionTestSuiteState.editorStore.applicationStore.notificationService.notifyWarning(
|
|
872
|
-
hasIngestOrDataProductAccessors
|
|
873
|
-
? `All referenced elements' data is already present`
|
|
874
|
-
: `No elements available to add`,
|
|
875
|
-
);
|
|
876
|
-
return;
|
|
877
|
-
}
|
|
878
867
|
dataState.setShowAddElementModal(true);
|
|
879
868
|
};
|
|
880
869
|
|
|
@@ -923,7 +912,9 @@ const FunctionTestDataPanel = observer(
|
|
|
923
912
|
tabIndex={-1}
|
|
924
913
|
>
|
|
925
914
|
<div className="testable-test-explorer__item__label__text">
|
|
926
|
-
{td.element.value.path}
|
|
915
|
+
<span title={td.element.value.path}>
|
|
916
|
+
{td.element.value.name}
|
|
917
|
+
</span>
|
|
927
918
|
</div>
|
|
928
919
|
<div className="mapping-test-explorer__item__actions">
|
|
929
920
|
<button
|
|
@@ -1076,26 +1067,6 @@ const FunctionTestsPanel = observer(
|
|
|
1076
1067
|
const FunctionTestSuiteEditor = observer(
|
|
1077
1068
|
(props: { functionTestSuiteState: FunctionTestSuiteState }) => {
|
|
1078
1069
|
const { functionTestSuiteState } = props;
|
|
1079
|
-
const hasTestData = Boolean(
|
|
1080
|
-
functionTestSuiteState.dataState.dataHolder.testData?.length,
|
|
1081
|
-
);
|
|
1082
|
-
const hasIngestOrDataProductAccessors =
|
|
1083
|
-
functionTestSuiteState.functionTestableState
|
|
1084
|
-
.resolvedIngestOrDataProductAccessors.length > 0;
|
|
1085
|
-
const showTestDataPanel =
|
|
1086
|
-
functionTestSuiteState.functionTestableState.containsRuntime ||
|
|
1087
|
-
hasIngestOrDataProductAccessors ||
|
|
1088
|
-
hasTestData;
|
|
1089
|
-
|
|
1090
|
-
if (!showTestDataPanel) {
|
|
1091
|
-
// No test data — just show the tests panel full width
|
|
1092
|
-
return (
|
|
1093
|
-
<div className="service-test-suite-editor">
|
|
1094
|
-
<FunctionTestsPanel functionTestSuiteState={functionTestSuiteState} />
|
|
1095
|
-
</div>
|
|
1096
|
-
);
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
1070
|
return (
|
|
1100
1071
|
<div className="service-test-suite-editor">
|
|
1101
1072
|
<ResizablePanelGroup orientation="horizontal">
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
DocumentationPreview,
|
|
68
68
|
} from '@finos/legend-lego/application';
|
|
69
69
|
import type { StoreProjectData } from '@finos/legend-server-depot';
|
|
70
|
+
import { generateGAVCoordinates } from '@finos/legend-storage';
|
|
70
71
|
|
|
71
72
|
const isProjectConfigurationVersionOutdated = (
|
|
72
73
|
projectConfig: ProjectConfiguration,
|
|
@@ -715,7 +716,16 @@ export const ProjectConfigurationEditor = observer(() => {
|
|
|
715
716
|
async (): Promise<void> => {
|
|
716
717
|
if (!isReadOnly) {
|
|
717
718
|
if (selectedTab === CONFIGURATION_EDITOR_TAB.PROJECT_DEPENDENCIES) {
|
|
718
|
-
const
|
|
719
|
+
const currentProjectCoordinates = generateGAVCoordinates(
|
|
720
|
+
currentProjectConfiguration.groupId,
|
|
721
|
+
currentProjectConfiguration.artifactId,
|
|
722
|
+
undefined,
|
|
723
|
+
);
|
|
724
|
+
const currentProjects = Array.from(
|
|
725
|
+
configState.projects.values(),
|
|
726
|
+
).filter(
|
|
727
|
+
(project) => project.coordinates !== currentProjectCoordinates,
|
|
728
|
+
);
|
|
719
729
|
if (currentProjects.length) {
|
|
720
730
|
const projectToAdd = currentProjects[0] as StoreProjectData;
|
|
721
731
|
const dependencyToAdd = new ProjectDependency(
|
package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx
CHANGED
|
@@ -1068,6 +1068,13 @@ const ProjectDependencyInlineExclusionsSelector = observer(
|
|
|
1068
1068
|
);
|
|
1069
1069
|
|
|
1070
1070
|
const visitedNodes = new Set<string>();
|
|
1071
|
+
const currentProjectCoordinate = generateGAVCoordinates(
|
|
1072
|
+
editorStore.projectConfigurationEditorState
|
|
1073
|
+
.currentProjectConfiguration.groupId,
|
|
1074
|
+
editorStore.projectConfigurationEditorState
|
|
1075
|
+
.currentProjectConfiguration.artifactId,
|
|
1076
|
+
undefined,
|
|
1077
|
+
);
|
|
1071
1078
|
const traverseNode = (nodeId: string) => {
|
|
1072
1079
|
if (visitedNodes.has(nodeId)) {
|
|
1073
1080
|
return;
|
|
@@ -1090,7 +1097,8 @@ const ProjectDependencyInlineExclusionsSelector = observer(
|
|
|
1090
1097
|
if (
|
|
1091
1098
|
existingExclusionCoordinates.indexOf(coordinate) === -1 &&
|
|
1092
1099
|
coordinate !==
|
|
1093
|
-
`${projectDependency.groupId}:${projectDependency.artifactId}`
|
|
1100
|
+
`${projectDependency.groupId}:${projectDependency.artifactId}` &&
|
|
1101
|
+
coordinate !== currentProjectCoordinate
|
|
1094
1102
|
) {
|
|
1095
1103
|
transitiveDeps.set(coordinate, {
|
|
1096
1104
|
label: generateGAVCoordinates(
|
|
@@ -1125,6 +1133,10 @@ const ProjectDependencyInlineExclusionsSelector = observer(
|
|
|
1125
1133
|
projectDependency.groupId,
|
|
1126
1134
|
projectDependency.artifactId,
|
|
1127
1135
|
projectDependency.versionId,
|
|
1136
|
+
editorStore.projectConfigurationEditorState.currentProjectConfiguration
|
|
1137
|
+
.groupId,
|
|
1138
|
+
editorStore.projectConfigurationEditorState.currentProjectConfiguration
|
|
1139
|
+
.artifactId,
|
|
1128
1140
|
]);
|
|
1129
1141
|
|
|
1130
1142
|
useEffect(() => {
|
|
@@ -1141,7 +1153,6 @@ const ProjectDependencyInlineExclusionsSelector = observer(
|
|
|
1141
1153
|
if (!option) {
|
|
1142
1154
|
return;
|
|
1143
1155
|
}
|
|
1144
|
-
|
|
1145
1156
|
try {
|
|
1146
1157
|
dependencyEditorState.addExclusionByCoordinate(
|
|
1147
1158
|
projectDependency.projectId,
|
|
@@ -1310,7 +1321,13 @@ const ProjectVersionDependencyEditor = observer(
|
|
|
1310
1321
|
const projectDisabled =
|
|
1311
1322
|
!configState.associatedProjectsAndVersionsFetched ||
|
|
1312
1323
|
configState.isReadOnly;
|
|
1324
|
+
const currentProjectCoordinates = generateGAVCoordinates(
|
|
1325
|
+
configState.currentProjectConfiguration.groupId,
|
|
1326
|
+
configState.currentProjectConfiguration.artifactId,
|
|
1327
|
+
undefined,
|
|
1328
|
+
);
|
|
1313
1329
|
const projectsOptions = Array.from(configState.projects.values())
|
|
1330
|
+
.filter((project) => project.coordinates !== currentProjectCoordinates)
|
|
1314
1331
|
.map(buildProjectOption)
|
|
1315
1332
|
.sort(compareLabelFn);
|
|
1316
1333
|
const onProjectSelectionChange = async (
|
|
@@ -159,6 +159,7 @@ const PropertyBasicEditor = observer(
|
|
|
159
159
|
const { property, _class, editorState, deleteProperty, isReadOnly } = props;
|
|
160
160
|
|
|
161
161
|
const editorStore = useEditorStore();
|
|
162
|
+
const applicationStore = useApplicationStore();
|
|
162
163
|
const isInheritedProperty =
|
|
163
164
|
property._OWNER instanceof Class && property._OWNER !== _class;
|
|
164
165
|
const isPropertyFromAssociation = property._OWNER instanceof Association;
|
|
@@ -340,6 +341,10 @@ const PropertyBasicEditor = observer(
|
|
|
340
341
|
placeholder="Choose a type..."
|
|
341
342
|
filterOption={filterOption}
|
|
342
343
|
formatOptionLabel={getPackageableElementOptionFormatter({})}
|
|
344
|
+
darkMode={
|
|
345
|
+
!applicationStore.layoutService
|
|
346
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
347
|
+
}
|
|
343
348
|
/>
|
|
344
349
|
)}
|
|
345
350
|
{!isIndirectProperty && !isReadOnly && !isEditingType && (
|
|
@@ -713,6 +718,10 @@ const DerivedPropertyBasicEditor = observer(
|
|
|
713
718
|
placeholder="Choose a type..."
|
|
714
719
|
filterOption={filterOption}
|
|
715
720
|
formatOptionLabel={getPackageableElementOptionFormatter({})}
|
|
721
|
+
darkMode={
|
|
722
|
+
!applicationStore.layoutService
|
|
723
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
724
|
+
}
|
|
716
725
|
/>
|
|
717
726
|
)}
|
|
718
727
|
{!isInheritedProperty && !isReadOnly && !isEditingType && (
|
|
@@ -1044,6 +1053,7 @@ const SuperTypeEditor = observer(
|
|
|
1044
1053
|
|
|
1045
1054
|
const { superType, _class, deleteSuperType, isReadOnly } = props;
|
|
1046
1055
|
const editorStore = useEditorStore();
|
|
1056
|
+
const applicationStore = useApplicationStore();
|
|
1047
1057
|
// Type
|
|
1048
1058
|
const superTypeOptions = editorStore.graphManagerState.usableClasses
|
|
1049
1059
|
.filter(
|
|
@@ -1136,6 +1146,10 @@ const SuperTypeEditor = observer(
|
|
|
1136
1146
|
placeholder="Choose a class"
|
|
1137
1147
|
filterOption={filterOption}
|
|
1138
1148
|
formatOptionLabel={getPackageableElementOptionFormatter({})}
|
|
1149
|
+
darkMode={
|
|
1150
|
+
!applicationStore.layoutService
|
|
1151
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
1152
|
+
}
|
|
1139
1153
|
/>
|
|
1140
1154
|
<button
|
|
1141
1155
|
className="uml-element-editor__basic__detail-btn"
|
|
@@ -1472,6 +1486,7 @@ const SupertypesEditor = observer(
|
|
|
1472
1486
|
const TaggedValuesEditor = observer(
|
|
1473
1487
|
(props: { _class: Class; editorState: ClassEditorState }) => {
|
|
1474
1488
|
const { _class, editorState } = props;
|
|
1489
|
+
const applicationStore = useApplicationStore();
|
|
1475
1490
|
const isReadOnly = editorState.isReadOnly;
|
|
1476
1491
|
|
|
1477
1492
|
const deleteTaggedValue =
|
|
@@ -1519,6 +1534,10 @@ const TaggedValuesEditor = observer(
|
|
|
1519
1534
|
taggedValue={taggedValue}
|
|
1520
1535
|
deleteValue={deleteTaggedValue(taggedValue)}
|
|
1521
1536
|
isReadOnly={isReadOnly}
|
|
1537
|
+
darkTheme={
|
|
1538
|
+
!applicationStore.layoutService
|
|
1539
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
1540
|
+
}
|
|
1522
1541
|
/>
|
|
1523
1542
|
))}
|
|
1524
1543
|
</PanelContentLists>
|
|
@@ -1530,6 +1549,7 @@ const TaggedValuesEditor = observer(
|
|
|
1530
1549
|
const StereotypesEditor = observer(
|
|
1531
1550
|
(props: { _class: Class; editorState: ClassEditorState }) => {
|
|
1532
1551
|
const { _class, editorState } = props;
|
|
1552
|
+
const applicationStore = useApplicationStore();
|
|
1533
1553
|
const isReadOnly = editorState.isReadOnly;
|
|
1534
1554
|
|
|
1535
1555
|
const deleteStereotype =
|
|
@@ -1579,6 +1599,10 @@ const StereotypesEditor = observer(
|
|
|
1579
1599
|
stereotype={stereotype}
|
|
1580
1600
|
deleteStereotype={deleteStereotype(stereotype)}
|
|
1581
1601
|
isReadOnly={isReadOnly}
|
|
1602
|
+
darkTheme={
|
|
1603
|
+
!applicationStore.layoutService
|
|
1604
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
1605
|
+
}
|
|
1582
1606
|
/>
|
|
1583
1607
|
))}
|
|
1584
1608
|
</PanelContentLists>
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
|
46
46
|
import { isNonNullable, prettyCONSTName } from '@finos/legend-shared';
|
|
47
47
|
import { UML_EDITOR_TAB } from '../../../../stores/editor/editor-state/element-editor-state/UMLEditorState.js';
|
|
48
|
+
import { useApplicationStore } from '@finos/legend-application';
|
|
48
49
|
import {
|
|
49
50
|
type AbstractProperty,
|
|
50
51
|
type StereotypeReference,
|
|
@@ -81,6 +82,9 @@ export const PropertyEditor = observer(
|
|
|
81
82
|
isReadOnly: boolean;
|
|
82
83
|
}) => {
|
|
83
84
|
const { property, deselectProperty, isReadOnly } = props;
|
|
85
|
+
const applicationStore = useApplicationStore();
|
|
86
|
+
const darkMode =
|
|
87
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
|
|
84
88
|
// Tab
|
|
85
89
|
const [selectedTab, setSelectedTab] = useState<UML_EDITOR_TAB>(
|
|
86
90
|
property instanceof Property
|
|
@@ -272,6 +276,7 @@ export const PropertyEditor = observer(
|
|
|
272
276
|
escapeClearsValue={true}
|
|
273
277
|
isClearable={true}
|
|
274
278
|
disabled={isReadOnly}
|
|
279
|
+
darkMode={darkMode}
|
|
275
280
|
/>
|
|
276
281
|
</PanelFormSection>
|
|
277
282
|
</PanelForm>
|
|
@@ -290,6 +295,7 @@ export const PropertyEditor = observer(
|
|
|
290
295
|
taggedValue={taggedValue}
|
|
291
296
|
deleteValue={_deleteTaggedValue(taggedValue)}
|
|
292
297
|
isReadOnly={isReadOnly}
|
|
298
|
+
darkTheme={darkMode}
|
|
293
299
|
/>
|
|
294
300
|
))}
|
|
295
301
|
</PanelContentLists>
|
|
@@ -309,6 +315,7 @@ export const PropertyEditor = observer(
|
|
|
309
315
|
stereotype={stereotype}
|
|
310
316
|
deleteStereotype={_deleteStereotype(stereotype)}
|
|
311
317
|
isReadOnly={isReadOnly}
|
|
318
|
+
darkTheme={darkMode}
|
|
312
319
|
/>
|
|
313
320
|
))}
|
|
314
321
|
</PanelContentLists>
|
|
@@ -14,7 +14,14 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
action,
|
|
19
|
+
flow,
|
|
20
|
+
flowResult,
|
|
21
|
+
makeObservable,
|
|
22
|
+
observable,
|
|
23
|
+
runInAction,
|
|
24
|
+
} from 'mobx';
|
|
18
25
|
import type { EditorStore } from '../../../../EditorStore.js';
|
|
19
26
|
import type { FunctionEditorState } from '../../FunctionEditorState.js';
|
|
20
27
|
import {
|
|
@@ -43,6 +50,8 @@ import {
|
|
|
43
50
|
type ValueSpecification,
|
|
44
51
|
type TestAssertion,
|
|
45
52
|
type AccessorOwner,
|
|
53
|
+
type AbstractPureGraphManager,
|
|
54
|
+
type PackageableElement,
|
|
46
55
|
FunctionParameterValue,
|
|
47
56
|
VariableExpression,
|
|
48
57
|
FunctionTest,
|
|
@@ -57,8 +66,11 @@ import {
|
|
|
57
66
|
InstanceValue,
|
|
58
67
|
PackageableElementReference,
|
|
59
68
|
Database,
|
|
69
|
+
DataProduct,
|
|
70
|
+
IngestDefinition,
|
|
60
71
|
PackageableElementExplicitReference,
|
|
61
72
|
observe_ValueSpecification,
|
|
73
|
+
observe_RelationElementsData,
|
|
62
74
|
buildLambdaVariableExpressions,
|
|
63
75
|
EqualTo,
|
|
64
76
|
EqualToRelation,
|
|
@@ -72,7 +84,7 @@ import {
|
|
|
72
84
|
type Accessor,
|
|
73
85
|
DataProductAccessor,
|
|
74
86
|
IngestionAccessor,
|
|
75
|
-
|
|
87
|
+
getAccessorItemLabelForElement,
|
|
76
88
|
V1_buildRelationElementsDataFromAccessors,
|
|
77
89
|
} from '@finos/legend-graph';
|
|
78
90
|
import {
|
|
@@ -191,6 +203,28 @@ const resolveRuntimesFromQuery = (
|
|
|
191
203
|
}
|
|
192
204
|
};
|
|
193
205
|
|
|
206
|
+
interface ElementDataItem {
|
|
207
|
+
id: string;
|
|
208
|
+
label: string;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const getElementDataItems = (
|
|
212
|
+
element: PackageableElement,
|
|
213
|
+
graphManager: AbstractPureGraphManager,
|
|
214
|
+
): ElementDataItem[] => {
|
|
215
|
+
if (element instanceof DataProduct) {
|
|
216
|
+
return element.accessPointGroups
|
|
217
|
+
.flatMap((g) => g.accessPoints)
|
|
218
|
+
.map((ap) => ({ id: ap.id, label: ap.id }));
|
|
219
|
+
}
|
|
220
|
+
if (element instanceof IngestDefinition) {
|
|
221
|
+
return graphManager
|
|
222
|
+
.getIngestDefinitionDatasetNames(element)
|
|
223
|
+
.map((name) => ({ id: name, label: name }));
|
|
224
|
+
}
|
|
225
|
+
return [];
|
|
226
|
+
};
|
|
227
|
+
|
|
194
228
|
export class FunctionStoreTestDataState {
|
|
195
229
|
readonly editorStore: EditorStore;
|
|
196
230
|
readonly testDataState: FunctionTestDataState;
|
|
@@ -239,51 +273,69 @@ export class FunctionStoreTestDataState {
|
|
|
239
273
|
embeddedDataState: RelationElementsDataState,
|
|
240
274
|
): Promise<void> {
|
|
241
275
|
const parentElement = this.storeTestData.element.value;
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
);
|
|
248
|
-
if (!parentAccessors.length) {
|
|
276
|
+
const graphManager = this.editorStore.graphManagerState.graphManager;
|
|
277
|
+
const graph = this.editorStore.graphManagerState.graph;
|
|
278
|
+
|
|
279
|
+
// For Database parents, fall back to the schema+table form
|
|
280
|
+
if (parentElement instanceof Database) {
|
|
249
281
|
embeddedDataState.setAccessorOptions(undefined, undefined);
|
|
250
282
|
return;
|
|
251
283
|
}
|
|
252
|
-
|
|
253
|
-
|
|
284
|
+
|
|
285
|
+
const items = getElementDataItems(parentElement, graphManager);
|
|
286
|
+
if (items.length === 0) {
|
|
254
287
|
embeddedDataState.setAccessorOptions(undefined, undefined);
|
|
255
288
|
return;
|
|
256
289
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
290
|
+
const typeLabel = getAccessorItemLabelForElement(
|
|
291
|
+
parentElement as AccessorOwner,
|
|
292
|
+
);
|
|
293
|
+
const options = await Promise.all(
|
|
294
|
+
items.map(async (item) => {
|
|
295
|
+
let columns: string[] = [];
|
|
296
|
+
try {
|
|
297
|
+
if (parentElement instanceof IngestDefinition) {
|
|
298
|
+
const accessor =
|
|
299
|
+
await graphManager.createAccessorFromPackageableElement(
|
|
300
|
+
parentElement,
|
|
301
|
+
graph,
|
|
302
|
+
{ schemaName: undefined, tableName: item.id },
|
|
303
|
+
);
|
|
304
|
+
if (accessor) {
|
|
305
|
+
columns = accessor.relationType.columns.map((c) => c.name);
|
|
306
|
+
}
|
|
307
|
+
} else if (parentElement instanceof DataProduct) {
|
|
308
|
+
const accessor = await graphManager.buildDataProductAccessor(
|
|
309
|
+
parentElement,
|
|
310
|
+
graph,
|
|
311
|
+
{ tableName: item.id },
|
|
312
|
+
);
|
|
313
|
+
if (accessor) {
|
|
314
|
+
columns = accessor.relationType.columns.map((c) => c.name);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
} catch {}
|
|
318
|
+
return { label: item.label, value: item.id, columns };
|
|
319
|
+
}),
|
|
320
|
+
);
|
|
321
|
+
runInAction(() => {
|
|
322
|
+
embeddedDataState.setAccessorOptions(options, typeLabel);
|
|
323
|
+
const columnsByItem = new Map(
|
|
324
|
+
options
|
|
325
|
+
.filter((o) => o.columns.length > 0)
|
|
326
|
+
.map((o) => [o.value, o.columns]),
|
|
327
|
+
);
|
|
274
328
|
for (const relState of embeddedDataState.relationElementStates) {
|
|
275
329
|
const rel = relState.relationElement;
|
|
276
330
|
if (rel.columns.length === 0) {
|
|
277
331
|
const key = rel.paths[rel.paths.length - 1];
|
|
278
|
-
const cols = key ?
|
|
332
|
+
const cols = key ? columnsByItem.get(key) : undefined;
|
|
279
333
|
if (cols) {
|
|
280
334
|
rel.columns = cols;
|
|
281
335
|
}
|
|
282
336
|
}
|
|
283
337
|
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
embeddedDataState.setAccessorOptions(options, typeLabel);
|
|
338
|
+
});
|
|
287
339
|
}
|
|
288
340
|
|
|
289
341
|
setDataElementModal(val: boolean): void {
|
|
@@ -655,34 +707,38 @@ class FunctionTestDataState {
|
|
|
655
707
|
return (this.dataHolder.testData ?? []).map((td) => td.element.value.path);
|
|
656
708
|
}
|
|
657
709
|
|
|
658
|
-
get availableElementsToAdd():
|
|
659
|
-
const
|
|
660
|
-
this.functionTestableState.resolvedIngestOrDataProductAccessors;
|
|
710
|
+
get availableElementsToAdd(): PackageableElement[] {
|
|
711
|
+
const graph = this.editorStore.graphManagerState.graph;
|
|
661
712
|
const existingPaths = new Set(this.existingElementPaths);
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
}
|
|
669
|
-
return Array.from(parentPaths).map((path) => ({ path }));
|
|
713
|
+
const candidates: PackageableElement[] = [
|
|
714
|
+
...graph.ingests,
|
|
715
|
+
...graph.dataProducts,
|
|
716
|
+
...graph.databases,
|
|
717
|
+
];
|
|
718
|
+
return candidates.filter((e) => !existingPaths.has(e.path));
|
|
670
719
|
}
|
|
671
720
|
|
|
672
721
|
addDataElement(elementPath: string): void {
|
|
673
|
-
const
|
|
674
|
-
this.
|
|
675
|
-
|
|
676
|
-
if (!group.length) {
|
|
722
|
+
const element =
|
|
723
|
+
this.editorStore.graphManagerState.graph.getNullableElement(elementPath);
|
|
724
|
+
if (!element) {
|
|
677
725
|
return;
|
|
678
726
|
}
|
|
679
|
-
const element =
|
|
680
|
-
this.editorStore.graphManagerState.graph.getElement(elementPath);
|
|
681
727
|
const data = new FunctionTestData();
|
|
682
728
|
data.element = PackageableElementExplicitReference.create(
|
|
683
729
|
element as AccessorOwner,
|
|
684
730
|
);
|
|
685
|
-
|
|
731
|
+
const matchingAccessors = this.functionTestableState.cachedAccessors.filter(
|
|
732
|
+
(a) => a.accessorOwner === elementPath,
|
|
733
|
+
);
|
|
734
|
+
if (matchingAccessors.length) {
|
|
735
|
+
data.data = V1_buildRelationElementsDataFromAccessors(matchingAccessors);
|
|
736
|
+
} else {
|
|
737
|
+
const relData = new RelationElementsData();
|
|
738
|
+
relData.relationElements = [];
|
|
739
|
+
data.data = relData;
|
|
740
|
+
}
|
|
741
|
+
observe_RelationElementsData(data.data as RelationElementsData);
|
|
686
742
|
if (!this.dataHolder.testData) {
|
|
687
743
|
this.dataHolder.testData = [];
|
|
688
744
|
}
|
|
@@ -966,36 +1022,9 @@ export class FunctionTestableState extends TestablePackageableElementEditorState
|
|
|
966
1022
|
|
|
967
1023
|
const ingestOrDataProductAccessors =
|
|
968
1024
|
this.resolvedIngestOrDataProductAccessors;
|
|
969
|
-
const databaseAccessors = this.cachedAccessors.filter(
|
|
970
|
-
(a) => a instanceof RelationalStoreAccessor,
|
|
971
|
-
);
|
|
972
1025
|
|
|
973
1026
|
try {
|
|
974
|
-
if (ingestOrDataProductAccessors.length) {
|
|
975
|
-
// Group by parent element path and create test data per parent
|
|
976
|
-
const parentElementMap = new Map<string, Accessor[]>();
|
|
977
|
-
for (const accessor of ingestOrDataProductAccessors) {
|
|
978
|
-
const key = accessor.accessorOwner;
|
|
979
|
-
if (key) {
|
|
980
|
-
const group = parentElementMap.get(key) ?? [];
|
|
981
|
-
group.push(accessor);
|
|
982
|
-
parentElementMap.set(key, group);
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
functionSuite.testData = Array.from(parentElementMap.entries()).map(
|
|
986
|
-
([parentPath, group]) => {
|
|
987
|
-
const data = new FunctionTestData();
|
|
988
|
-
const element =
|
|
989
|
-
this.editorStore.graphManagerState.graph.getElement(parentPath);
|
|
990
|
-
data.element = PackageableElementExplicitReference.create(
|
|
991
|
-
element as AccessorOwner,
|
|
992
|
-
);
|
|
993
|
-
data.data = V1_buildRelationElementsDataFromAccessors(group);
|
|
994
|
-
return data;
|
|
995
|
-
},
|
|
996
|
-
);
|
|
997
|
-
} else {
|
|
998
|
-
// No ingest/data product accessors found — try runtime-based approach
|
|
1027
|
+
if (!ingestOrDataProductAccessors.length) {
|
|
999
1028
|
const engineRuntimes = this.associatedRuntimes;
|
|
1000
1029
|
if (engineRuntimes?.length) {
|
|
1001
1030
|
assertTrue(
|
|
@@ -1047,10 +1076,44 @@ export class FunctionTestableState extends TestablePackageableElementEditorState
|
|
|
1047
1076
|
type.path === CORE_PURE_PATH.RELATION ||
|
|
1048
1077
|
type.path === CORE_PURE_PATH.TABULAR_DATASET
|
|
1049
1078
|
) {
|
|
1050
|
-
this.editorStore.applicationStore.notificationService.
|
|
1051
|
-
`
|
|
1079
|
+
this.editorStore.applicationStore.notificationService.notifyWarning(
|
|
1080
|
+
`No runtime or accessors found, or they could not be resolved. For Relational (non-Lakehouse) function testing, please ensure that your query is bound to a runtime`,
|
|
1081
|
+
);
|
|
1082
|
+
// continue: still allow the user to create the suite/test and
|
|
1083
|
+
// add test data manually
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (this.cachedAccessors.length) {
|
|
1089
|
+
const accessorsByOwner = new Map<string, Accessor[]>();
|
|
1090
|
+
for (const accessor of this.cachedAccessors) {
|
|
1091
|
+
const key = accessor.accessorOwner;
|
|
1092
|
+
if (key) {
|
|
1093
|
+
const group = accessorsByOwner.get(key) ?? [];
|
|
1094
|
+
group.push(accessor);
|
|
1095
|
+
accessorsByOwner.set(key, group);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
if (!functionSuite.testData) {
|
|
1099
|
+
functionSuite.testData = [];
|
|
1100
|
+
}
|
|
1101
|
+
for (const [parentPath, group] of accessorsByOwner.entries()) {
|
|
1102
|
+
const builtData = V1_buildRelationElementsDataFromAccessors(group);
|
|
1103
|
+
const existing = functionSuite.testData.find(
|
|
1104
|
+
(td) => td.element.value.path === parentPath,
|
|
1105
|
+
);
|
|
1106
|
+
if (existing) {
|
|
1107
|
+
existing.data = builtData;
|
|
1108
|
+
} else {
|
|
1109
|
+
const element =
|
|
1110
|
+
this.editorStore.graphManagerState.graph.getElement(parentPath);
|
|
1111
|
+
const data = new FunctionTestData();
|
|
1112
|
+
data.element = PackageableElementExplicitReference.create(
|
|
1113
|
+
element as AccessorOwner,
|
|
1052
1114
|
);
|
|
1053
|
-
|
|
1115
|
+
data.data = builtData;
|
|
1116
|
+
functionSuite.testData.push(data);
|
|
1054
1117
|
}
|
|
1055
1118
|
}
|
|
1056
1119
|
}
|
|
@@ -1062,10 +1125,7 @@ export class FunctionTestableState extends TestablePackageableElementEditorState
|
|
|
1062
1125
|
return;
|
|
1063
1126
|
}
|
|
1064
1127
|
|
|
1065
|
-
const hasTestData =
|
|
1066
|
-
this.containsRuntime ||
|
|
1067
|
-
ingestOrDataProductAccessors.length > 0 ||
|
|
1068
|
-
databaseAccessors.length > 0;
|
|
1128
|
+
const hasTestData = this.containsRuntime || this.cachedAccessors.length > 0;
|
|
1069
1129
|
yield createFunctionTest(
|
|
1070
1130
|
testName,
|
|
1071
1131
|
this.editorStore.changeDetectionState.observerContext,
|
|
@@ -444,6 +444,23 @@ export class ProjectDependencyEditorState {
|
|
|
444
444
|
return;
|
|
445
445
|
}
|
|
446
446
|
|
|
447
|
+
const currentProjectCoordinate = generateGAVCoordinates(
|
|
448
|
+
this.configState.currentProjectConfiguration.groupId,
|
|
449
|
+
this.configState.currentProjectConfiguration.artifactId,
|
|
450
|
+
undefined,
|
|
451
|
+
);
|
|
452
|
+
const exclusionCoordinate = generateGAVCoordinates(
|
|
453
|
+
guaranteeNonNullable(exclusion.groupId),
|
|
454
|
+
guaranteeNonNullable(exclusion.artifactId),
|
|
455
|
+
undefined,
|
|
456
|
+
);
|
|
457
|
+
if (exclusionCoordinate === currentProjectCoordinate) {
|
|
458
|
+
this.editorStore.applicationStore.notificationService.notifyWarning(
|
|
459
|
+
'You cannot exclude your own project from a dependency',
|
|
460
|
+
);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
447
464
|
const existingExclusion = this.findExistingExclusion(
|
|
448
465
|
dependencyId,
|
|
449
466
|
generateGAVCoordinates(
|