@finos/legend-application-studio 28.19.35 → 28.19.36

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 (28) hide show
  1. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts +13 -2
  2. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
  3. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +104 -20
  4. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
  5. package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
  6. package/lib/components/editor/side-bar/CreateNewElementModal.js +15 -2
  7. package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
  8. package/lib/index.css +2 -2
  9. package/lib/index.css.map +1 -1
  10. package/lib/package.json +1 -1
  11. package/lib/stores/editor/NewElementState.d.ts +6 -2
  12. package/lib/stores/editor/NewElementState.d.ts.map +1 -1
  13. package/lib/stores/editor/NewElementState.js +25 -12
  14. package/lib/stores/editor/NewElementState.js.map +1 -1
  15. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +25 -1
  16. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
  17. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +98 -4
  18. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
  19. package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts +14 -1
  20. package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts.map +1 -1
  21. package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js +42 -2
  22. package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js.map +1 -1
  23. package/package.json +9 -9
  24. package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +357 -41
  25. package/src/components/editor/side-bar/CreateNewElementModal.tsx +33 -0
  26. package/src/stores/editor/NewElementState.ts +25 -12
  27. package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +162 -3
  28. package/src/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.ts +90 -5
@@ -23,6 +23,7 @@ import {
23
23
  DataProductEditorState,
24
24
  generateUrlToDeployOnOpen,
25
25
  LakehouseAccessPointState,
26
+ ModelAccessPointGroupState,
26
27
  } from '../../../../stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js';
27
28
  import {
28
29
  BugIcon,
@@ -74,6 +75,8 @@ import {
74
75
  UploadIcon,
75
76
  useDragPreviewLayer,
76
77
  WarningIcon,
78
+ LongArrowRightIcon,
79
+ PURE_MappingIcon,
77
80
  } from '@finos/legend-art';
78
81
  import {
79
82
  type ChangeEventHandler,
@@ -94,12 +97,19 @@ import {
94
97
  type V1_DataProductArtifactAccessPointGroup,
95
98
  type V1_DataProductArtifactAccessPointImplementation,
96
99
  type V1_DataProductArtifactGeneration,
100
+ type Mapping,
101
+ type PackageableRuntime,
102
+ type DataProductRuntimeInfo,
103
+ type PackageableElement,
104
+ type DataProductElementScope,
105
+ type DataProductElement,
97
106
  DataProductEmbeddedImageIcon,
98
107
  DataProductLibraryIcon,
99
108
  Email,
100
109
  LakehouseTargetEnv,
101
110
  StereotypeExplicitReference,
102
111
  V1_DataProductIconLibraryId,
112
+ validate_PureExecutionMapping,
103
113
  } from '@finos/legend-graph';
104
114
  import {
105
115
  accessPoint_setClassification,
@@ -115,6 +125,8 @@ import {
115
125
  supportInfo_setDocumentationUrl,
116
126
  supportInfo_setFaqUrl,
117
127
  supportInfo_setLinkLabel,
128
+ runtimeInfo_setId,
129
+ runtimeInfo_setDescription,
118
130
  supportInfo_setSupportUrl,
119
131
  supportInfo_setWebsite,
120
132
  } from '../../../../stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
@@ -130,6 +142,10 @@ import {
130
142
  annotatedElement_addStereotype,
131
143
  annotatedElement_deleteStereotype,
132
144
  } from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
145
+ import {
146
+ buildElementOption,
147
+ type PackageableElementOption,
148
+ } from '@finos/legend-lego/graph-editor';
133
149
 
134
150
  export enum AP_GROUP_MODAL_ERRORS {
135
151
  GROUP_NAME_EMPTY = 'Group Name is empty',
@@ -405,7 +421,7 @@ const AccessPointGenerationViewer = observer(
405
421
  },
406
422
  );
407
423
 
408
- export const LakehouseDataProductAcccessPointEditor = observer(
424
+ export const LakehouseDataProductAccessPointEditor = observer(
409
425
  (props: {
410
426
  accessPointState: LakehouseAccessPointState;
411
427
  isReadOnly: boolean;
@@ -838,6 +854,309 @@ const AccessPointGroupPublicToggle = observer(
838
854
  },
839
855
  );
840
856
 
857
+ export const CompatibleRuntimesEditor = observer(
858
+ (props: { groupState: ModelAccessPointGroupState }) => {
859
+ const { groupState } = props;
860
+ const group = groupState.value;
861
+
862
+ const handleSelectRuntime = (runtime: DataProductRuntimeInfo) => {
863
+ groupState.setDefaultRuntime(runtime);
864
+ };
865
+
866
+ // Event handlers
867
+ const handleAddRuntime = (option: {
868
+ label: string;
869
+ value: PackageableRuntime;
870
+ }): void => {
871
+ if (typeof option.value === 'object') {
872
+ groupState.addCompatibleRuntime(option.value);
873
+ }
874
+ };
875
+
876
+ const handleRemoveRuntime = (runtime: DataProductRuntimeInfo): void => {
877
+ groupState.removeCompatibleRuntime(runtime);
878
+ };
879
+
880
+ const handleRuntimeTitleChange = (
881
+ runtimeInfo: DataProductRuntimeInfo,
882
+ value: string | undefined,
883
+ ): void => {
884
+ runtimeInfo_setId(runtimeInfo, value ?? '');
885
+ };
886
+
887
+ const handleRuntimeDescriptionChange = (
888
+ runtimeInfo: DataProductRuntimeInfo,
889
+ value: string | undefined,
890
+ ): void => {
891
+ runtimeInfo_setDescription(runtimeInfo, value);
892
+ };
893
+
894
+ // ListEditor component renderers
895
+ const RuntimeComponent = observer(
896
+ (runtimeComponentProps: {
897
+ item: DataProductRuntimeInfo;
898
+ }): React.ReactElement => {
899
+ const { item } = runtimeComponentProps;
900
+
901
+ return (
902
+ <>
903
+ <div className="panel__content__form__section__list__item__content">
904
+ <div className="panel__content__form__section__header__label">
905
+ Default?
906
+ </div>
907
+ <input
908
+ type="radio"
909
+ name="defaultRuntimeRadio"
910
+ value={item.id}
911
+ checked={group.defaultRuntime === item}
912
+ onChange={() => handleSelectRuntime(item)}
913
+ />
914
+ </div>
915
+ <div className="panel__content__form__section__list__item__content">
916
+ <div className="panel__content__form__section__header__label">
917
+ Runtime
918
+ </div>
919
+ <div className="panel__content__form__section__list__item__content__title">
920
+ {item.runtime.value.path}
921
+ </div>
922
+ </div>
923
+ <div className="panel__content__form__section__list__item__form">
924
+ <PanelFormTextField
925
+ name="Title"
926
+ value={item.id}
927
+ update={(value) => handleRuntimeTitleChange(item, value)}
928
+ placeholder="Enter title"
929
+ className="dataSpace-editor__general__diagrams__title"
930
+ />
931
+ <PanelFormTextField
932
+ name="Description"
933
+ value={item.description ?? ''}
934
+ update={(value) => handleRuntimeDescriptionChange(item, value)}
935
+ placeholder="Enter description"
936
+ className="dataSpace-editor__general__diagrams__description"
937
+ />
938
+ </div>
939
+ </>
940
+ );
941
+ },
942
+ );
943
+
944
+ const NewRuntimeComponent = observer(
945
+ (newRuntimeProps: {
946
+ onFinishEditing: () => void;
947
+ }): React.ReactElement => {
948
+ const { onFinishEditing } = newRuntimeProps;
949
+
950
+ return (
951
+ <div className="panel__content__form__section__list__new-item__input">
952
+ <CustomSelectorInput
953
+ options={groupState.getCompatibleRuntimeOptions()}
954
+ onChange={(event: {
955
+ label: string;
956
+ value: PackageableRuntime;
957
+ }) => {
958
+ onFinishEditing();
959
+ handleAddRuntime(event);
960
+ }}
961
+ placeholder="Select a runtime to add..."
962
+ darkMode={true}
963
+ />
964
+ </div>
965
+ );
966
+ },
967
+ );
968
+
969
+ return (
970
+ <ListEditor
971
+ title="Compatible Runtimes"
972
+ prompt="Add compatible runtimes to include in this Data Product. Set a title and description for each runtime."
973
+ items={group.compatibleRuntimes}
974
+ keySelector={(element: DataProductRuntimeInfo) =>
975
+ element.runtime.value.path
976
+ }
977
+ ItemComponent={RuntimeComponent}
978
+ NewItemComponent={NewRuntimeComponent}
979
+ handleRemoveItem={handleRemoveRuntime}
980
+ isReadOnly={groupState.state.isReadOnly}
981
+ emptyMessage="No runtimes specified"
982
+ emptyClassName="data-product-editor__empty-runtime"
983
+ />
984
+ );
985
+ },
986
+ );
987
+
988
+ export const FeaturedElementsEditor = observer(
989
+ (props: { groupState: ModelAccessPointGroupState; isReadOnly: boolean }) => {
990
+ const { groupState, isReadOnly } = props;
991
+ const group = groupState.value;
992
+
993
+ // Event handlers
994
+ const handleAddElement = (option: {
995
+ label: string;
996
+ value: DataProductElement;
997
+ }): void => {
998
+ if (typeof option.value === 'object') {
999
+ groupState.addFeaturedElement(option.value);
1000
+ }
1001
+ };
1002
+
1003
+ const handleRemoveElement = (element: DataProductElementScope): void => {
1004
+ groupState.removeFeaturedElement(element);
1005
+ };
1006
+
1007
+ const handleElementExcludeChange = (
1008
+ element: DataProductElementScope,
1009
+ event: React.ChangeEvent<HTMLInputElement>,
1010
+ ): void => {
1011
+ groupState.excludeFeaturedElement(element, event.target.checked);
1012
+ };
1013
+
1014
+ // ListEditor component renderers
1015
+ const ElementComponent = observer(
1016
+ (elementComponentProps: {
1017
+ item: DataProductElementScope;
1018
+ }): React.ReactElement => {
1019
+ const { item } = elementComponentProps;
1020
+
1021
+ return (
1022
+ <div className="data-product-editor__element-item">
1023
+ <div className="panel__content__form__section__list__item__content__label">
1024
+ {item.element.value.path}
1025
+ </div>
1026
+ <div className="panel__content__form__section__list__item__content__actions">
1027
+ <div className="panel__content__form__section__list__item__content__actions-exclude">
1028
+ <Checkbox
1029
+ disabled={isReadOnly}
1030
+ checked={item.exclude ?? false}
1031
+ onChange={(event) => handleElementExcludeChange(item, event)}
1032
+ size="small"
1033
+ className="panel__content__form__section__list__item__content__actions-exclude__btn"
1034
+ />
1035
+ <span className="panel__content__form__section__list__item__content__actions__label">
1036
+ Exclude
1037
+ </span>
1038
+ </div>
1039
+ </div>
1040
+ </div>
1041
+ );
1042
+ },
1043
+ );
1044
+
1045
+ const NewElementComponent = observer(
1046
+ (newElementProps: { onFinishEditing: () => void }) => {
1047
+ const { onFinishEditing } = newElementProps;
1048
+
1049
+ return (
1050
+ <div className="panel__content__form__section__list__new-item__input">
1051
+ <CustomSelectorInput
1052
+ options={groupState.getFeaturedElementOptions()}
1053
+ onChange={(event: {
1054
+ label: string;
1055
+ value: DataProductElement;
1056
+ }) => {
1057
+ onFinishEditing();
1058
+ handleAddElement(event);
1059
+ }}
1060
+ placeholder="Select an element to add..."
1061
+ darkMode={true}
1062
+ />
1063
+ </div>
1064
+ );
1065
+ },
1066
+ );
1067
+
1068
+ return (
1069
+ <ListEditor
1070
+ title="Featured Elements"
1071
+ prompt="Add classes and associations to display under Models Documentation. Use the exclude checkbox to exclude certain elements from this Data Product entirely."
1072
+ items={group.featuredElements}
1073
+ keySelector={(element: DataProductElementScope) =>
1074
+ element.element.value.path
1075
+ }
1076
+ ItemComponent={ElementComponent}
1077
+ NewItemComponent={NewElementComponent}
1078
+ handleRemoveItem={handleRemoveElement}
1079
+ isReadOnly={isReadOnly}
1080
+ emptyMessage="No elements specified"
1081
+ />
1082
+ );
1083
+ },
1084
+ );
1085
+
1086
+ const ModelAccessPointGroupEditor = observer(
1087
+ (props: { groupState: ModelAccessPointGroupState; isReadOnly: boolean }) => {
1088
+ const { groupState, isReadOnly } = props;
1089
+ const editorStore = useEditorStore();
1090
+
1091
+ // mapping
1092
+ const mapping = groupState.value.mapping;
1093
+ const isMappingEmpty = validate_PureExecutionMapping(
1094
+ groupState.value.mapping.value,
1095
+ );
1096
+ const mappingOptions =
1097
+ groupState.state.editorStore.graphManagerState.usableMappings.map(
1098
+ buildElementOption,
1099
+ );
1100
+ const selectedMappingOption = {
1101
+ value: mapping.value,
1102
+ label: mapping.value.path === '' ? '(none)' : mapping.value.path,
1103
+ } as PackageableElementOption<Mapping>;
1104
+ const onMappingChange = (val: PackageableElementOption<Mapping>): void => {
1105
+ if (val.value !== mapping.value) {
1106
+ groupState.setMapping(val.value);
1107
+ }
1108
+ };
1109
+
1110
+ const visitElement = (element: PackageableElement): void => {
1111
+ editorStore.graphEditorMode.openElement(element);
1112
+ };
1113
+
1114
+ return (
1115
+ <div className="data-product-editor__model-apg-editor">
1116
+ <div className="data-product-editor__model-apg-editor__label">
1117
+ Mapping
1118
+ </div>
1119
+ <div
1120
+ className="service-execution-editor__configuration__item"
1121
+ style={{ padding: '0 1rem' }}
1122
+ >
1123
+ <div className="btn--sm service-execution-editor__configuration__item__label">
1124
+ <PURE_MappingIcon />
1125
+ </div>
1126
+ <CustomSelectorInput
1127
+ className="panel__content__form__section__dropdown service-execution-editor__configuration__item__dropdown"
1128
+ disabled={isReadOnly}
1129
+ options={mappingOptions}
1130
+ onChange={onMappingChange}
1131
+ value={selectedMappingOption}
1132
+ darkMode={
1133
+ !groupState.state.editorStore.applicationStore.layoutService
1134
+ .TEMPORARY__isLightColorThemeEnabled
1135
+ }
1136
+ hasError={Boolean(isMappingEmpty)}
1137
+ />
1138
+ <button
1139
+ className="btn--dark btn--sm service-execution-editor__configuration__item__btn"
1140
+ onClick={() => {
1141
+ visitElement(groupState.value.mapping.value);
1142
+ }}
1143
+ tabIndex={-1}
1144
+ title="See mapping"
1145
+ disabled={Boolean(isMappingEmpty)}
1146
+ >
1147
+ <LongArrowRightIcon />
1148
+ </button>
1149
+ </div>
1150
+ <CompatibleRuntimesEditor groupState={groupState} />
1151
+ <FeaturedElementsEditor
1152
+ groupState={groupState}
1153
+ isReadOnly={isReadOnly}
1154
+ />
1155
+ </div>
1156
+ );
1157
+ },
1158
+ );
1159
+
841
1160
  const AccessPointGroupEditor = observer(
842
1161
  (props: { groupState: AccessPointGroupState; isReadOnly: boolean }) => {
843
1162
  const { groupState, isReadOnly } = props;
@@ -849,7 +1168,6 @@ const AccessPointGroupEditor = observer(
849
1168
  groupState.value.id === newNamePlaceholder,
850
1169
  );
851
1170
  const [isHoveringName, setIsHoveringName] = useState(false);
852
-
853
1171
  const handleDescriptionEdit = () => setEditingDescription(true);
854
1172
  const handleDescriptionBlur = () => {
855
1173
  setEditingDescription(false);
@@ -958,16 +1276,18 @@ const AccessPointGroupEditor = observer(
958
1276
  {isHoveringName && hoverIcon()}
959
1277
  </div>
960
1278
  )}
961
- <button
962
- className="access-point-editor__generic-entry__remove-btn--group"
963
- onClick={() => {
964
- handleRemoveAccessPointGroup();
965
- }}
966
- tabIndex={-1}
967
- title="Remove Access Point Group"
968
- >
969
- <TimesIcon />
970
- </button>
1279
+ {!groupState.state.modelledDataProduct && (
1280
+ <button
1281
+ className="access-point-editor__generic-entry__remove-btn--group"
1282
+ onClick={() => {
1283
+ handleRemoveAccessPointGroup();
1284
+ }}
1285
+ tabIndex={-1}
1286
+ title="Remove Access Point Group"
1287
+ >
1288
+ <TimesIcon />
1289
+ </button>
1290
+ )}
971
1291
  </div>
972
1292
  <div className="access-point-editor__group-container__description-editor">
973
1293
  {editingDescription ? (
@@ -1015,13 +1335,20 @@ const AccessPointGroupEditor = observer(
1015
1335
  {editorStore.applicationStore.config.options.dataProductConfig && (
1016
1336
  <AccessPointGroupPublicToggle groupState={groupState} />
1017
1337
  )}
1338
+ {groupState instanceof ModelAccessPointGroupState && (
1339
+ <ModelAccessPointGroupEditor
1340
+ groupState={groupState}
1341
+ isReadOnly={isReadOnly}
1342
+ />
1343
+ )}
1018
1344
  <PanelHeader className="panel__header--access-point">
1019
1345
  <div className="panel__header__title">Access Points</div>
1020
1346
  <PanelHeaderActions>
1347
+ {/* TODO: remove disabling this button for MAPG when Function Access Points are ready */}
1021
1348
  <PanelHeaderActionItem
1022
1349
  className="panel__header__action"
1023
1350
  onClick={handleAddAccessPoint}
1024
- disabled={isReadOnly}
1351
+ disabled={isReadOnly || productEditorState.modelledDataProduct}
1025
1352
  title="Create new access point"
1026
1353
  >
1027
1354
  <PlusIcon />
@@ -1041,7 +1368,7 @@ const AccessPointGroupEditor = observer(
1041
1368
  {groupState.accessPointStates
1042
1369
  .filter(filterByType(LakehouseAccessPointState))
1043
1370
  .map((apState) => (
1044
- <LakehouseDataProductAcccessPointEditor
1371
+ <LakehouseDataProductAccessPointEditor
1045
1372
  key={apState.uuid}
1046
1373
  isReadOnly={isReadOnly}
1047
1374
  accessPointState={apState}
@@ -1065,18 +1392,6 @@ const GroupTabRenderer = observer(
1065
1392
  const selectedGroupState = dataProductEditorState.selectedGroupState;
1066
1393
  const ref = useRef<HTMLDivElement>(null);
1067
1394
 
1068
- const groupError = (): boolean => {
1069
- return (
1070
- group.accessPointStates.length === 0 ||
1071
- group.value.id === newNamePlaceholder ||
1072
- Boolean(
1073
- group.accessPointStates.find(
1074
- (apState) => apState.accessPoint.id === newNamePlaceholder,
1075
- ),
1076
- )
1077
- );
1078
- };
1079
-
1080
1395
  //Drag and Drop - reorder groups and accept access points from other groups
1081
1396
  const handleHover = useCallback(
1082
1397
  (item: APGDragSource): void => {
@@ -1162,10 +1477,11 @@ const GroupTabRenderer = observer(
1162
1477
  ? 'var(--color-dark-grey-100)'
1163
1478
  : 'var(--color-dark-grey-50)',
1164
1479
  }}
1480
+ role="tab"
1165
1481
  >
1166
1482
  {group.value.id}
1167
1483
  &nbsp;
1168
- {groupError() && (
1484
+ {group.hasErrors() && (
1169
1485
  <ErrorWarnIcon
1170
1486
  title="Resolve Access Point Group error(s)"
1171
1487
  style={{ color: 'var(--color-red-300)' }}
@@ -1225,21 +1541,21 @@ const AccessPointGroupTab = observer(
1225
1541
  />
1226
1542
  );
1227
1543
  })}
1228
- <PanelHeaderActionItem
1229
- className="panel__header__action"
1230
- onClick={handleAddAccessPointGroup}
1231
- disabled={isReadOnly || disableAddGroup}
1232
- title={
1233
- disableAddGroup
1234
- ? 'Provide all group names'
1235
- : 'Create new access point group'
1236
- }
1237
- >
1238
- <PlusIcon />
1239
- </PanelHeaderActionItem>
1544
+ {!dataProductEditorState.modelledDataProduct && (
1545
+ <PanelHeaderActionItem
1546
+ className="panel__header__action"
1547
+ onClick={handleAddAccessPointGroup}
1548
+ disabled={isReadOnly || disableAddGroup}
1549
+ title={
1550
+ disableAddGroup
1551
+ ? 'Provide all group names'
1552
+ : 'Create new access point group'
1553
+ }
1554
+ >
1555
+ <PlusIcon />
1556
+ </PanelHeaderActionItem>
1557
+ )}
1240
1558
  </div>
1241
-
1242
- <PanelHeaderActions></PanelHeaderActions>
1243
1559
  </PanelHeader>
1244
1560
  <PanelContent>
1245
1561
  {selectedGroupState && (
@@ -29,6 +29,7 @@ import {
29
29
  type RuntimeOption,
30
30
  NewLakehouseDataProductDriver,
31
31
  NewRuntimeType,
32
+ DataProductType,
32
33
  } from '../../../stores/editor/NewElementState.js';
33
34
  import { Dialog, compareLabelFn, CustomSelectorInput } from '@finos/legend-art';
34
35
  import type { EditorStore } from '../../../stores/editor/EditorStore.js';
@@ -488,6 +489,23 @@ const NewLakehouseDataProductEditor = observer(() => {
488
489
  const handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (
489
490
  event,
490
491
  ) => newProductDriver.setTitle(event.target.value);
492
+
493
+ const type = newProductDriver.type;
494
+ const typeOptions = Object.values(DataProductType).map((typeOption) => ({
495
+ label: prettyCONSTName(typeOption),
496
+ value: typeOption,
497
+ }));
498
+ const typeOption = {
499
+ value: type,
500
+ label: prettyCONSTName(type),
501
+ };
502
+ const onTypeChange = (val: {
503
+ value: DataProductType;
504
+ label: string;
505
+ }): void => {
506
+ newProductDriver.setType(val.value);
507
+ };
508
+
491
509
  return (
492
510
  <>
493
511
  <div className="panel__content__form__section__header__label">Title</div>
@@ -500,6 +518,21 @@ const NewLakehouseDataProductEditor = observer(() => {
500
518
  placeholder={`Choose a title for this Data Product to display in Marketplace`}
501
519
  />
502
520
  </div>
521
+ <div className="panel__content__form__section__header__label">
522
+ Data Product Type
523
+ </div>
524
+ <div className="explorer__new-element-modal__driver">
525
+ <CustomSelectorInput
526
+ className="explorer__new-element-modal__driver__dropdown"
527
+ options={typeOptions}
528
+ onChange={onTypeChange}
529
+ value={typeOption}
530
+ darkMode={
531
+ !editorStore.applicationStore.layoutService
532
+ .TEMPORARY__isLightColorThemeEnabled
533
+ }
534
+ />
535
+ </div>
503
536
  </>
504
537
  );
505
538
  });
@@ -87,6 +87,9 @@ import {
87
87
  LakehouseRuntime,
88
88
  type Runtime,
89
89
  AccessPointGroup,
90
+ ModelAccessPointGroup,
91
+ stub_Mapping,
92
+ DataProductRuntimeInfo,
90
93
  } from '@finos/legend-graph';
91
94
  import type { DSL_Mapping_LegendStudioApplicationPlugin_Extension } from '../extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.js';
92
95
  import {
@@ -113,7 +116,6 @@ import { EmbeddedDataType } from './editor-state/ExternalFormatState.js';
113
116
  import { createEmbeddedData } from './editor-state/element-editor-state/data/EmbeddedDataState.js';
114
117
  import {
115
118
  dataProduct_addAccessPointGroup,
116
- dataProduct_setDescription,
117
119
  dataProduct_setTitle,
118
120
  } from '../graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
119
121
 
@@ -512,19 +514,23 @@ export class NewPackageableConnectionDriver extends NewElementDriver<Packageable
512
514
  }
513
515
  }
514
516
 
517
+ export enum DataProductType {
518
+ LAKEHOUSE = 'LAKEHOUSE',
519
+ MODELLED = 'MODELLED',
520
+ }
521
+
515
522
  export class NewLakehouseDataProductDriver extends NewElementDriver<DataProduct> {
516
523
  title: string;
517
- description: string;
524
+ type = DataProductType.LAKEHOUSE;
518
525
 
519
526
  constructor(editorStore: EditorStore) {
520
527
  super(editorStore);
521
528
  this.title = '';
522
- this.description = '';
523
529
  makeObservable(this, {
524
530
  title: observable,
525
- description: observable,
531
+ type: observable,
532
+ setType: action,
526
533
  setTitle: action,
527
- setDescription: action,
528
534
  isValid: computed,
529
535
  });
530
536
  }
@@ -532,21 +538,28 @@ export class NewLakehouseDataProductDriver extends NewElementDriver<DataProduct>
532
538
  override get isValid(): boolean {
533
539
  return Boolean(this.title);
534
540
  }
535
-
536
541
  setTitle(val: string) {
537
542
  this.title = val;
538
543
  }
539
- setDescription(val: string) {
540
- this.description = val;
544
+ setType(val: DataProductType) {
545
+ this.type = val;
541
546
  }
542
547
  override createElement(name: string): DataProduct {
543
548
  const dataProduct = new DataProduct(name);
544
549
  dataProduct_setTitle(dataProduct, this.title);
545
- dataProduct_setDescription(dataProduct, this.description);
546
550
 
547
- const defaultGroup = new AccessPointGroup();
548
- defaultGroup.id = 'default';
549
- dataProduct_addAccessPointGroup(dataProduct, defaultGroup);
551
+ if (this.type === DataProductType.LAKEHOUSE) {
552
+ const defaultGroup = new AccessPointGroup();
553
+ defaultGroup.id = 'default';
554
+ dataProduct_addAccessPointGroup(dataProduct, defaultGroup);
555
+ } else {
556
+ const defaultGroup = new ModelAccessPointGroup();
557
+ defaultGroup.id = 'default';
558
+ defaultGroup.mapping =
559
+ PackageableElementExplicitReference.create(stub_Mapping());
560
+ defaultGroup.defaultRuntime = new DataProductRuntimeInfo();
561
+ dataProduct_addAccessPointGroup(dataProduct, defaultGroup);
562
+ }
550
563
 
551
564
  return dataProduct;
552
565
  }