@finos/legend-application-studio 27.1.2 → 27.1.4

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 (141) 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 +6 -3
  18. package/lib/components/editor/editor-group/FunctionEditor.js.map +1 -1
  19. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.d.ts.map +1 -1
  20. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js +2 -2
  21. package/lib/components/editor/editor-group/mapping-editor/MappingEditor.js.map +1 -1
  22. package/lib/components/editor/editor-group/mapping-editor/MappingExplorer.js +1 -1
  23. package/lib/components/editor/editor-group/mapping-editor/MappingExplorer.js.map +1 -1
  24. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.d.ts.map +1 -1
  25. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.js +47 -12
  26. package/lib/components/editor/editor-group/mapping-editor/MappingTestableEditor.js.map +1 -1
  27. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.d.ts.map +1 -1
  28. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js +61 -11
  29. package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js.map +1 -1
  30. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
  31. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +1 -1
  32. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
  33. package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js +1 -1
  34. package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js.map +1 -1
  35. package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.d.ts.map +1 -1
  36. package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js +9 -5
  37. package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js.map +1 -1
  38. package/lib/components/editor/editor-group/uml-editor/ClassEditor.d.ts.map +1 -1
  39. package/lib/components/editor/editor-group/uml-editor/ClassEditor.js +26 -27
  40. package/lib/components/editor/editor-group/uml-editor/ClassEditor.js.map +1 -1
  41. package/lib/components/editor/editor-group/uml-editor/EnumerationEditor.js +2 -2
  42. package/lib/components/editor/editor-group/uml-editor/EnumerationEditor.js.map +1 -1
  43. package/lib/components/editor/editor-group/uml-editor/ProfileEditor.js +3 -3
  44. package/lib/components/editor/editor-group/uml-editor/ProfileEditor.js.map +1 -1
  45. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js +2 -2
  46. package/lib/components/editor/editor-group/uml-editor/StereotypeSelector.js.map +1 -1
  47. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js +2 -2
  48. package/lib/components/editor/editor-group/uml-editor/TaggedValueEditor.js.map +1 -1
  49. package/lib/components/editor/side-bar/ProjectOverview.d.ts.map +1 -1
  50. package/lib/components/editor/side-bar/ProjectOverview.js +7 -1
  51. package/lib/components/editor/side-bar/ProjectOverview.js.map +1 -1
  52. package/lib/index.css +2 -2
  53. package/lib/index.css.map +1 -1
  54. package/lib/package.json +4 -4
  55. package/lib/stores/editor/editor-state/element-editor-state/ClassState.d.ts +8 -2
  56. package/lib/stores/editor/editor-state/element-editor-state/ClassState.d.ts.map +1 -1
  57. package/lib/stores/editor/editor-state/element-editor-state/ClassState.js +10 -6
  58. package/lib/stores/editor/editor-state/element-editor-state/ClassState.js.map +1 -1
  59. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +5 -1
  60. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
  61. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +7 -5
  62. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
  63. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.d.ts +4 -1
  64. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.d.ts.map +1 -1
  65. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.js +7 -5
  66. package/lib/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.js.map +1 -1
  67. package/lib/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.d.ts +10 -3
  68. package/lib/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.d.ts.map +1 -1
  69. package/lib/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.js +7 -5
  70. package/lib/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.js.map +1 -1
  71. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts +1 -1
  72. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
  73. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js +2 -2
  74. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
  75. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.d.ts +3 -1
  76. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.d.ts.map +1 -1
  77. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js +4 -4
  78. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js.map +1 -1
  79. package/lib/stores/editor/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.d.ts +8 -2
  80. package/lib/stores/editor/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.d.ts.map +1 -1
  81. package/lib/stores/editor/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.js +10 -6
  82. package/lib/stores/editor/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.js.map +1 -1
  83. package/lib/stores/editor/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.d.ts +11 -3
  84. package/lib/stores/editor/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.d.ts.map +1 -1
  85. package/lib/stores/editor/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.js +6 -4
  86. package/lib/stores/editor/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.js.map +1 -1
  87. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts +3 -1
  88. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts.map +1 -1
  89. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js +3 -3
  90. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js.map +1 -1
  91. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts +3 -1
  92. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts.map +1 -1
  93. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js +4 -4
  94. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
  95. package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.d.ts +8 -2
  96. package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.d.ts.map +1 -1
  97. package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.js +12 -8
  98. package/lib/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.js.map +1 -1
  99. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.d.ts +1 -1
  100. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.d.ts.map +1 -1
  101. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.js +13 -8
  102. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.js.map +1 -1
  103. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts +6 -2
  104. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts.map +1 -1
  105. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js +39 -3
  106. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js.map +1 -1
  107. package/lib/stores/editor/utils/TestableUtils.js +2 -2
  108. package/lib/stores/editor/utils/TestableUtils.js.map +1 -1
  109. package/package.json +14 -14
  110. package/src/__lib__/LegendStudioApplicationNavigationContext.ts +1 -1
  111. package/src/__lib__/LegendStudioDocumentation.ts +4 -0
  112. package/src/__lib__/LegendStudioTesting.ts +1 -0
  113. package/src/application/LegendStudioApplicationConfig.ts +1 -1
  114. package/src/components/editor/editor-group/FunctionEditor.tsx +8 -6
  115. package/src/components/editor/editor-group/mapping-editor/MappingEditor.tsx +5 -2
  116. package/src/components/editor/editor-group/mapping-editor/MappingExplorer.tsx +1 -1
  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/service-editor/ServiceExecutionQueryEditor.tsx +3 -3
  121. package/src/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.tsx +53 -18
  122. package/src/components/editor/editor-group/uml-editor/ClassEditor.tsx +358 -364
  123. package/src/components/editor/editor-group/uml-editor/EnumerationEditor.tsx +4 -4
  124. package/src/components/editor/editor-group/uml-editor/ProfileEditor.tsx +7 -7
  125. package/src/components/editor/editor-group/uml-editor/StereotypeSelector.tsx +4 -4
  126. package/src/components/editor/editor-group/uml-editor/TaggedValueEditor.tsx +4 -4
  127. package/src/components/editor/side-bar/ProjectOverview.tsx +14 -3
  128. package/src/stores/editor/editor-state/element-editor-state/ClassState.ts +16 -6
  129. package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +11 -8
  130. package/src/stores/editor/editor-state/element-editor-state/mapping/DEPRECATED__MappingTestState.ts +10 -5
  131. package/src/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts +14 -5
  132. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +2 -2
  133. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.ts +6 -4
  134. package/src/stores/editor/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.ts +16 -6
  135. package/src/stores/editor/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.ts +14 -4
  136. package/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts +5 -3
  137. package/src/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.ts +6 -4
  138. package/src/stores/editor/editor-state/element-editor-state/service/ServicePostValidationState.ts +22 -10
  139. package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.ts +21 -8
  140. package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.ts +59 -2
  141. package/src/stores/editor/utils/TestableUtils.ts +2 -2
@@ -40,7 +40,7 @@ import {
40
40
  PlusIcon,
41
41
  TimesIcon,
42
42
  ArrowCircleRightIcon,
43
- PanelDnDEntryDragHandle,
43
+ PanelEntryDragHandle,
44
44
  DragPreviewLayer,
45
45
  useDragPreviewLayer,
46
46
  Panel,
@@ -332,9 +332,9 @@ const ParameterBasicEditor = observer(
332
332
  className="property-basic-editor__container"
333
333
  showPlaceholder={isBeingDragged}
334
334
  >
335
- <PanelDnDEntryDragHandle
336
- dropTargetConnector={handleRef}
337
- isBeingDragged={isBeingDragged}
335
+ <PanelEntryDragHandle
336
+ dragSourceConnector={handleRef}
337
+ isDragging={isBeingDragged}
338
338
  />
339
339
  <div className="property-basic-editor">
340
340
  {isReadOnly && (
@@ -1059,8 +1059,10 @@ export const FunctionEditor = observer(() => {
1059
1059
  useEffect(() => {
1060
1060
  flowResult(
1061
1061
  functionEditorState.functionDefinitionEditorState.convertLambdaObjectToGrammarString(
1062
- true,
1063
- true,
1062
+ {
1063
+ pretty: true,
1064
+ firstLoad: true,
1065
+ },
1064
1066
  ),
1065
1067
  ).catch(applicationStore.alertUnhandledError);
1066
1068
  }, [applicationStore, functionEditorState]);
@@ -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
  />
@@ -151,7 +151,7 @@ export const MappingExplorerContextMenu = observer(
151
151
  ) {
152
152
  await flowResult(
153
153
  mappingEditorState.currentTabState.mappingFilterState?.convertLambdaObjectToGrammarString(
154
- false,
154
+ { pretty: false },
155
155
  ),
156
156
  );
157
157
  mappingEditorState.currentTabState.mappingFilterState = undefined;
@@ -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
@@ -272,9 +272,9 @@ export const ServiceExecutionQueryEditor = observer(
272
272
 
273
273
  // convert to string
274
274
  useEffect(() => {
275
- flowResult(queryState.convertLambdaObjectToGrammarString(true)).catch(
276
- applicationStore.alertUnhandledError,
277
- );
275
+ flowResult(
276
+ queryState.convertLambdaObjectToGrammarString({ pretty: true }),
277
+ ).catch(applicationStore.alertUnhandledError);
278
278
  }, [applicationStore, queryState]);
279
279
 
280
280
  return (
@@ -40,6 +40,7 @@ import {
40
40
  ModalFooter,
41
41
  ModalBody,
42
42
  ModalTitle,
43
+ PlayIcon,
43
44
  } from '@finos/legend-art';
44
45
  import {
45
46
  type Binding,
@@ -717,8 +718,21 @@ const ServiceTestDataContextMenu = observer(
717
718
  const remove = (): void => suiteState.deleteTest(serviceTestState);
718
719
  const rename = (): void =>
719
720
  suiteState.setTestToRename(serviceTestState.test);
721
+ const runTest =
722
+ serviceTestState.editorStore.applicationStore.guardUnhandledError(() =>
723
+ flowResult(serviceTestState.runTest()),
724
+ );
720
725
  return (
721
726
  <MenuContent ref={ref}>
727
+ <MenuContentItem
728
+ disabled={
729
+ suiteState.runningTestState.isInProgress ||
730
+ serviceTestState.runningTestAction.isInProgress
731
+ }
732
+ onClick={runTest}
733
+ >
734
+ Run test
735
+ </MenuContentItem>
722
736
  <MenuContentItem onClick={rename}>Rename</MenuContentItem>
723
737
  <MenuContentItem onClick={remove}>Delete</MenuContentItem>
724
738
  <MenuContentItem onClick={addTest}>Add test</MenuContentItem>
@@ -750,16 +764,12 @@ const ServiceTestItem = observer(
750
764
  const resultIcon = getTestableResultIcon(testableResult);
751
765
  const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
752
766
  const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
767
+ const runTest =
768
+ serviceTestState.editorStore.applicationStore.guardUnhandledError(() =>
769
+ flowResult(serviceTestState.runTest()),
770
+ );
753
771
  return (
754
772
  <ContextMenu
755
- className={clsx(
756
- 'testable-test-explorer__item',
757
- {
758
- 'testable-test-explorer__item--selected-from-context-menu':
759
- !isActive && isSelectedFromContextMenu,
760
- },
761
- { 'testable-test-explorer__item--active': isActive },
762
- )}
763
773
  disabled={isReadOnly}
764
774
  content={
765
775
  <ServiceTestDataContextMenu
@@ -771,18 +781,43 @@ const ServiceTestItem = observer(
771
781
  onOpen={onContextMenuOpen}
772
782
  onClose={onContextMenuClose}
773
783
  >
774
- <button
775
- className={clsx('testable-test-explorer__item__label')}
776
- onClick={openTest}
777
- tabIndex={-1}
784
+ <div
785
+ className={clsx(
786
+ 'testable-test-explorer__item',
787
+ {
788
+ 'testable-test-explorer__item--selected-from-context-menu':
789
+ !isActive && isSelectedFromContextMenu,
790
+ },
791
+ { 'testable-test-explorer__item--active': isActive },
792
+ )}
778
793
  >
779
- <div className="testable-test-explorer__item__label__icon">
780
- {resultIcon}
781
- </div>
782
- <div className="testable-test-explorer__item__label__text">
783
- {serviceTest.id}
794
+ <button
795
+ className={clsx('testable-test-explorer__item__label')}
796
+ onClick={openTest}
797
+ tabIndex={-1}
798
+ >
799
+ <div className="testable-test-explorer__item__label__icon">
800
+ {resultIcon}
801
+ </div>
802
+ <div className="testable-test-explorer__item__label__text">
803
+ {serviceTest.id}
804
+ </div>
805
+ </button>
806
+ <div className="mapping-test-explorer__item__actions">
807
+ <button
808
+ className="mapping-test-explorer__item__action mapping-test-explorer__run-test-btn"
809
+ onClick={runTest}
810
+ disabled={
811
+ suiteState.runningTestState.isInProgress ||
812
+ serviceTestState.runningTestAction.isInProgress
813
+ }
814
+ tabIndex={-1}
815
+ title={`Run ${serviceTest.id}`}
816
+ >
817
+ {<PlayIcon />}
818
+ </button>
784
819
  </div>
785
- </button>
820
+ </div>
786
821
  </ContextMenu>
787
822
  );
788
823
  },