@finos/legend-application-studio 28.19.53 → 28.19.55
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/dataProduct/DataProductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +95 -24
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.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/NewElementState.d.ts.map +1 -1
- package/lib/stores/editor/NewElementState.js +3 -2
- package/lib/stores/editor/NewElementState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +4 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +10 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts +7 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js +18 -0
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js.map +1 -1
- package/package.json +10 -10
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +265 -26
- package/src/stores/editor/NewElementState.ts +3 -0
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +15 -0
- package/src/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.ts +38 -0
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type AccessPointGroupState,
|
|
21
21
|
type AccessPointState,
|
|
22
22
|
DATA_PRODUCT_TAB,
|
|
23
|
+
DATA_PRODUCT_TYPE,
|
|
23
24
|
DataProductEditorState,
|
|
24
25
|
generateUrlToDeployOnOpen,
|
|
25
26
|
LakehouseAccessPointState,
|
|
@@ -116,6 +117,10 @@ import {
|
|
|
116
117
|
V1_PureGraphManager,
|
|
117
118
|
V1_RemoteEngine,
|
|
118
119
|
validate_PureExecutionMapping,
|
|
120
|
+
InternalDataProductType,
|
|
121
|
+
ExternalDataProductType,
|
|
122
|
+
DataProductLink,
|
|
123
|
+
observer_DataProductLink,
|
|
119
124
|
} from '@finos/legend-graph';
|
|
120
125
|
import {
|
|
121
126
|
accessPoint_setClassification,
|
|
@@ -135,10 +140,16 @@ import {
|
|
|
135
140
|
runtimeInfo_setDescription,
|
|
136
141
|
supportInfo_setSupportUrl,
|
|
137
142
|
supportInfo_setWebsite,
|
|
143
|
+
dataProduct_setType,
|
|
138
144
|
expertise_setDescription,
|
|
139
145
|
expertise_addId,
|
|
140
146
|
expertise_deleteId,
|
|
141
147
|
dataProduct_deleteExpertise,
|
|
148
|
+
externalType_setLinkURL,
|
|
149
|
+
externalType_setLinkLabel,
|
|
150
|
+
accessPointGroup_setTitle,
|
|
151
|
+
accessPoint_setDescription,
|
|
152
|
+
accessPoint_setTitle,
|
|
142
153
|
} from '../../../../stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
|
|
143
154
|
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
|
144
155
|
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
|
|
@@ -235,7 +246,7 @@ const AccessPointTitle = observer(
|
|
|
235
246
|
};
|
|
236
247
|
const updateAccessPointName: React.ChangeEventHandler<HTMLTextAreaElement> =
|
|
237
248
|
action((event) => {
|
|
238
|
-
if (event.target.value.match(/^[0-9a-zA-Z_]
|
|
249
|
+
if (event.target.value.match(/^[0-9a-zA-Z_]*$/)) {
|
|
239
250
|
accessPoint.id = event.target.value;
|
|
240
251
|
}
|
|
241
252
|
});
|
|
@@ -259,7 +270,7 @@ const AccessPointTitle = observer(
|
|
|
259
270
|
<div
|
|
260
271
|
className="access-point-editor__name__label"
|
|
261
272
|
onClick={handleNameEdit}
|
|
262
|
-
title="Click to edit access point
|
|
273
|
+
title="Click to edit access point name"
|
|
263
274
|
style={{ flex: '1 1 auto' }}
|
|
264
275
|
>
|
|
265
276
|
{accessPoint.id}
|
|
@@ -451,25 +462,38 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
451
462
|
.filter(filterByType(LakehouseAccessPointState))
|
|
452
463
|
.find((pm) => pm.lambdaState.parserError);
|
|
453
464
|
const [editingDescription, setEditingDescription] = useState(false);
|
|
454
|
-
const [
|
|
465
|
+
const [isHoveringDesc, setIsHoveringDesc] = useState(false);
|
|
466
|
+
const [editingTitle, setEditingTitle] = useState(false);
|
|
467
|
+
const [isHoveringTitle, setIsHoveringTitle] = useState(false);
|
|
455
468
|
const ref = useRef<HTMLDivElement>(null);
|
|
456
469
|
const [debugOutput, setDebugOutput] = useState('');
|
|
457
470
|
|
|
458
471
|
const handleDescriptionEdit = () => setEditingDescription(true);
|
|
459
472
|
const handleDescriptionBlur = () => {
|
|
460
473
|
setEditingDescription(false);
|
|
461
|
-
|
|
474
|
+
setIsHoveringDesc(false);
|
|
462
475
|
};
|
|
463
|
-
const
|
|
464
|
-
|
|
476
|
+
const handleMouseOverDesc: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
477
|
+
setIsHoveringDesc(true);
|
|
465
478
|
};
|
|
466
|
-
const
|
|
467
|
-
|
|
479
|
+
const handleMouseOutDesc: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
480
|
+
setIsHoveringDesc(false);
|
|
468
481
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
482
|
+
|
|
483
|
+
const handleTitleEdit = () => setEditingTitle(true);
|
|
484
|
+
const handleTitleBlur = () => {
|
|
485
|
+
setEditingTitle(false);
|
|
486
|
+
setIsHoveringTitle(false);
|
|
487
|
+
};
|
|
488
|
+
const handleMouseOverTitle: React.MouseEventHandler<
|
|
489
|
+
HTMLDivElement
|
|
490
|
+
> = () => {
|
|
491
|
+
setIsHoveringTitle(true);
|
|
492
|
+
};
|
|
493
|
+
const handleMouseOutTitle: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
494
|
+
setIsHoveringTitle(false);
|
|
495
|
+
};
|
|
496
|
+
|
|
473
497
|
const updateAccessPointTargetEnvironment = action(
|
|
474
498
|
(targetEnvironment: LakehouseTargetEnv) => {
|
|
475
499
|
accessPoint.targetEnvironment = targetEnvironment;
|
|
@@ -758,12 +782,56 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
758
782
|
</ControlledDropdownMenu>
|
|
759
783
|
</div>
|
|
760
784
|
</div>
|
|
785
|
+
{editingTitle ? (
|
|
786
|
+
<textarea
|
|
787
|
+
className="access-point-editor__name"
|
|
788
|
+
spellCheck={false}
|
|
789
|
+
value={accessPoint.title}
|
|
790
|
+
onChange={(event) =>
|
|
791
|
+
accessPoint_setTitle(accessPoint, event.target.value)
|
|
792
|
+
}
|
|
793
|
+
placeholder={'Access Point Title'}
|
|
794
|
+
onBlur={handleTitleBlur}
|
|
795
|
+
style={{
|
|
796
|
+
borderColor: 'transparent',
|
|
797
|
+
margin: '0.5rem',
|
|
798
|
+
}}
|
|
799
|
+
/>
|
|
800
|
+
) : (
|
|
801
|
+
<div
|
|
802
|
+
onClick={handleTitleEdit}
|
|
803
|
+
title="Click to edit access point title"
|
|
804
|
+
className="access-point-editor__description-container"
|
|
805
|
+
>
|
|
806
|
+
{accessPoint.title ? (
|
|
807
|
+
<HoverTextArea
|
|
808
|
+
text={accessPoint.title}
|
|
809
|
+
handleMouseOver={handleMouseOverTitle}
|
|
810
|
+
handleMouseOut={handleMouseOutTitle}
|
|
811
|
+
className="access-point-editor__title"
|
|
812
|
+
/>
|
|
813
|
+
) : (
|
|
814
|
+
<div
|
|
815
|
+
className="access-point-editor__group-container__description--warning"
|
|
816
|
+
onMouseOver={handleMouseOverTitle}
|
|
817
|
+
onMouseOut={handleMouseOutTitle}
|
|
818
|
+
style={{ fontSize: '15px' }}
|
|
819
|
+
>
|
|
820
|
+
<ErrorWarnIcon />
|
|
821
|
+
Provide a title for this Access Point
|
|
822
|
+
</div>
|
|
823
|
+
)}
|
|
824
|
+
{isHoveringTitle && hoverIcon()}
|
|
825
|
+
</div>
|
|
826
|
+
)}
|
|
761
827
|
{editingDescription ? (
|
|
762
828
|
<textarea
|
|
763
829
|
className="panel__content__form__section__input"
|
|
764
830
|
spellCheck={false}
|
|
765
831
|
value={accessPoint.description ?? ''}
|
|
766
|
-
onChange={
|
|
832
|
+
onChange={(event) =>
|
|
833
|
+
accessPoint_setDescription(accessPoint, event.target.value)
|
|
834
|
+
}
|
|
767
835
|
placeholder="Access Point description"
|
|
768
836
|
onBlur={handleDescriptionBlur}
|
|
769
837
|
style={{
|
|
@@ -783,20 +851,20 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
783
851
|
{accessPoint.description ? (
|
|
784
852
|
<HoverTextArea
|
|
785
853
|
text={accessPoint.description}
|
|
786
|
-
handleMouseOver={
|
|
787
|
-
handleMouseOut={
|
|
854
|
+
handleMouseOver={handleMouseOverDesc}
|
|
855
|
+
handleMouseOut={handleMouseOutDesc}
|
|
788
856
|
/>
|
|
789
857
|
) : (
|
|
790
858
|
<div
|
|
791
859
|
className="access-point-editor__group-container__description--warning"
|
|
792
|
-
onMouseOver={
|
|
793
|
-
onMouseOut={
|
|
860
|
+
onMouseOver={handleMouseOverDesc}
|
|
861
|
+
onMouseOut={handleMouseOutDesc}
|
|
794
862
|
>
|
|
795
|
-
<
|
|
863
|
+
<ErrorWarnIcon />
|
|
796
864
|
{AP_EMPTY_DESC_WARNING}
|
|
797
865
|
</div>
|
|
798
866
|
)}
|
|
799
|
-
{
|
|
867
|
+
{isHoveringDesc && hoverIcon()}
|
|
800
868
|
</div>
|
|
801
869
|
)}
|
|
802
870
|
<div className="access-point-editor__content">
|
|
@@ -1242,6 +1310,8 @@ const AccessPointGroupEditor = observer(
|
|
|
1242
1310
|
groupState.value.id === newNamePlaceholder,
|
|
1243
1311
|
);
|
|
1244
1312
|
const [isHoveringName, setIsHoveringName] = useState(false);
|
|
1313
|
+
const [editingTitle, setEditingTitle] = useState(false);
|
|
1314
|
+
const [isHoveringTitle, setIsHoveringTitle] = useState(false);
|
|
1245
1315
|
const handleDescriptionEdit = () => setEditingDescription(true);
|
|
1246
1316
|
const handleDescriptionBlur = () => {
|
|
1247
1317
|
setEditingDescription(false);
|
|
@@ -1280,6 +1350,23 @@ const AccessPointGroupEditor = observer(
|
|
|
1280
1350
|
}
|
|
1281
1351
|
};
|
|
1282
1352
|
|
|
1353
|
+
const handleTitleEdit = () => setEditingTitle(true);
|
|
1354
|
+
const handleTitleBlur = () => {
|
|
1355
|
+
setEditingTitle(false);
|
|
1356
|
+
setIsHoveringTitle(false);
|
|
1357
|
+
};
|
|
1358
|
+
const handleMouseOverTitle: React.MouseEventHandler<
|
|
1359
|
+
HTMLDivElement
|
|
1360
|
+
> = () => {
|
|
1361
|
+
setIsHoveringTitle(true);
|
|
1362
|
+
};
|
|
1363
|
+
const handleMouseOutTitle: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
1364
|
+
setIsHoveringTitle(false);
|
|
1365
|
+
};
|
|
1366
|
+
const updateGroupTitle = (val: string | undefined): void => {
|
|
1367
|
+
accessPointGroup_setTitle(groupState.value, val);
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1283
1370
|
const handleRemoveAccessPointGroup = (): void => {
|
|
1284
1371
|
editorStore.applicationStore.alertService.setActionAlertInfo({
|
|
1285
1372
|
message: `Are you sure you want to delete Access Point Group ${groupState.value.id} and all of its Access Points?`,
|
|
@@ -1314,7 +1401,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1314
1401
|
className="access-point-editor__group-container"
|
|
1315
1402
|
data-testid={LEGEND_STUDIO_TEST_ID.ACCESS_POINT_GROUP_EDITOR}
|
|
1316
1403
|
>
|
|
1317
|
-
<div className="access-point-editor__group-
|
|
1404
|
+
<div className="access-point-editor__group-container__name-editor">
|
|
1318
1405
|
{editingName ? (
|
|
1319
1406
|
<textarea
|
|
1320
1407
|
className="panel__content__form__section__input"
|
|
@@ -1338,13 +1425,13 @@ const AccessPointGroupEditor = observer(
|
|
|
1338
1425
|
<div
|
|
1339
1426
|
onClick={handleNameEdit}
|
|
1340
1427
|
title="Click to edit group name"
|
|
1341
|
-
className="access-point-editor__group-
|
|
1428
|
+
className="access-point-editor__group-container__name"
|
|
1342
1429
|
>
|
|
1343
1430
|
<HoverTextArea
|
|
1344
1431
|
text={groupState.value.id}
|
|
1345
1432
|
handleMouseOver={handleMouseOverName}
|
|
1346
1433
|
handleMouseOut={handleMouseOutName}
|
|
1347
|
-
className="access-point-editor__group-
|
|
1434
|
+
className="access-point-editor__group-container__name"
|
|
1348
1435
|
/>
|
|
1349
1436
|
|
|
1350
1437
|
{isHoveringName && hoverIcon()}
|
|
@@ -1363,6 +1450,50 @@ const AccessPointGroupEditor = observer(
|
|
|
1363
1450
|
</button>
|
|
1364
1451
|
)}
|
|
1365
1452
|
</div>
|
|
1453
|
+
<div className="access-point-editor__group-container__name-editor">
|
|
1454
|
+
{editingTitle ? (
|
|
1455
|
+
<textarea
|
|
1456
|
+
className="panel__content__form__section__input"
|
|
1457
|
+
spellCheck={false}
|
|
1458
|
+
value={groupState.value.title}
|
|
1459
|
+
onChange={(event) => updateGroupTitle(event.target.value)}
|
|
1460
|
+
placeholder="Access Point Group Title"
|
|
1461
|
+
onBlur={handleTitleBlur}
|
|
1462
|
+
style={{
|
|
1463
|
+
overflow: 'hidden',
|
|
1464
|
+
resize: 'none',
|
|
1465
|
+
padding: '0.25rem',
|
|
1466
|
+
margin: '0.5rem 0.5rem 0.5rem 0rem',
|
|
1467
|
+
}}
|
|
1468
|
+
/>
|
|
1469
|
+
) : (
|
|
1470
|
+
<div
|
|
1471
|
+
onClick={handleTitleEdit}
|
|
1472
|
+
title="Click to edit group title"
|
|
1473
|
+
className="access-point-editor__group-container__description"
|
|
1474
|
+
>
|
|
1475
|
+
{groupState.value.title ? (
|
|
1476
|
+
<HoverTextArea
|
|
1477
|
+
text={groupState.value.title}
|
|
1478
|
+
handleMouseOver={handleMouseOverTitle}
|
|
1479
|
+
handleMouseOut={handleMouseOutTitle}
|
|
1480
|
+
className="access-point-editor__group-container__title"
|
|
1481
|
+
/>
|
|
1482
|
+
) : (
|
|
1483
|
+
<div
|
|
1484
|
+
className="access-point-editor__group-container__description--warning"
|
|
1485
|
+
onMouseOver={handleMouseOverTitle}
|
|
1486
|
+
onMouseOut={handleMouseOutTitle}
|
|
1487
|
+
style={{ fontSize: '15px' }}
|
|
1488
|
+
>
|
|
1489
|
+
<ErrorWarnIcon />
|
|
1490
|
+
Provide a title for this Access Point Group
|
|
1491
|
+
</div>
|
|
1492
|
+
)}
|
|
1493
|
+
{isHoveringTitle && hoverIcon()}
|
|
1494
|
+
</div>
|
|
1495
|
+
)}
|
|
1496
|
+
</div>
|
|
1366
1497
|
<div className="access-point-editor__group-container__description-editor">
|
|
1367
1498
|
{editingDescription ? (
|
|
1368
1499
|
<textarea
|
|
@@ -1397,7 +1528,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1397
1528
|
onMouseOver={handleMouseOverDescription}
|
|
1398
1529
|
onMouseOut={handleMouseOutDescription}
|
|
1399
1530
|
>
|
|
1400
|
-
<
|
|
1531
|
+
<ErrorWarnIcon />
|
|
1401
1532
|
Users request access at the access point group level. Click
|
|
1402
1533
|
here to add a meaningful description to guide users.
|
|
1403
1534
|
</div>
|
|
@@ -1867,8 +1998,12 @@ const DataProductIconEditor = observer(
|
|
|
1867
1998
|
);
|
|
1868
1999
|
|
|
1869
2000
|
const HomeTab = observer(
|
|
1870
|
-
(props: {
|
|
1871
|
-
|
|
2001
|
+
(props: {
|
|
2002
|
+
dataProductEditorState: DataProductEditorState;
|
|
2003
|
+
isReadOnly: boolean;
|
|
2004
|
+
}) => {
|
|
2005
|
+
const { dataProductEditorState, isReadOnly } = props;
|
|
2006
|
+
const product = dataProductEditorState.product;
|
|
1872
2007
|
|
|
1873
2008
|
const updateDataProductTitle = (val: string | undefined): void => {
|
|
1874
2009
|
dataProduct_setTitle(product, val ?? '');
|
|
@@ -1879,6 +2014,42 @@ const HomeTab = observer(
|
|
|
1879
2014
|
dataProduct_setDescription(product, event.target.value);
|
|
1880
2015
|
};
|
|
1881
2016
|
|
|
2017
|
+
const DATA_PRODUCT_TYPE_OPTIONS = [
|
|
2018
|
+
{ label: DATA_PRODUCT_TYPE.INTERNAL, value: DATA_PRODUCT_TYPE.INTERNAL },
|
|
2019
|
+
{ label: DATA_PRODUCT_TYPE.EXTERNAL, value: DATA_PRODUCT_TYPE.EXTERNAL },
|
|
2020
|
+
];
|
|
2021
|
+
const handleDataProductTypeChange = action(
|
|
2022
|
+
(val: { label: string; value: string } | null): void => {
|
|
2023
|
+
if (val?.value === DATA_PRODUCT_TYPE.INTERNAL) {
|
|
2024
|
+
dataProduct_setType(product, new InternalDataProductType());
|
|
2025
|
+
} else if (val?.value === DATA_PRODUCT_TYPE.EXTERNAL) {
|
|
2026
|
+
const externalType = new ExternalDataProductType();
|
|
2027
|
+
const externalLink = observer_DataProductLink(
|
|
2028
|
+
new DataProductLink(''),
|
|
2029
|
+
);
|
|
2030
|
+
externalType.link = externalLink;
|
|
2031
|
+
dataProduct_setType(product, externalType);
|
|
2032
|
+
}
|
|
2033
|
+
},
|
|
2034
|
+
);
|
|
2035
|
+
const handleExternalURLChange: ChangeEventHandler<HTMLTextAreaElement> = (
|
|
2036
|
+
event,
|
|
2037
|
+
) => {
|
|
2038
|
+
if (
|
|
2039
|
+
product.type instanceof ExternalDataProductType &&
|
|
2040
|
+
event.target.value
|
|
2041
|
+
) {
|
|
2042
|
+
externalType_setLinkURL(product.type, event.target.value);
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
const handleExternalLabelChange: ChangeEventHandler<HTMLTextAreaElement> = (
|
|
2046
|
+
event,
|
|
2047
|
+
) => {
|
|
2048
|
+
if (product.type instanceof ExternalDataProductType) {
|
|
2049
|
+
externalType_setLinkLabel(product.type, event.target.value);
|
|
2050
|
+
}
|
|
2051
|
+
};
|
|
2052
|
+
|
|
1882
2053
|
return (
|
|
1883
2054
|
<div className="panel__content">
|
|
1884
2055
|
<div className="data-product-editor__home-tab">
|
|
@@ -1888,6 +2059,8 @@ const HomeTab = observer(
|
|
|
1888
2059
|
prompt="Provide a descriptive name for the Data Product to appear in Marketplace."
|
|
1889
2060
|
update={updateDataProductTitle}
|
|
1890
2061
|
placeholder="Enter title"
|
|
2062
|
+
hasError={product.title === '' || product.title === undefined}
|
|
2063
|
+
errorClassName="data-product-editor__textbox-error"
|
|
1891
2064
|
/>
|
|
1892
2065
|
<div className="panel__content__form__section">
|
|
1893
2066
|
<div
|
|
@@ -1931,6 +2104,67 @@ const HomeTab = observer(
|
|
|
1931
2104
|
}}
|
|
1932
2105
|
/>
|
|
1933
2106
|
</div>
|
|
2107
|
+
<div className="panel__content__form__section">
|
|
2108
|
+
<div
|
|
2109
|
+
className="panel__content__form__section__header__label"
|
|
2110
|
+
style={{ justifyContent: 'space-between', width: '45rem' }}
|
|
2111
|
+
>
|
|
2112
|
+
Data Product Type
|
|
2113
|
+
</div>
|
|
2114
|
+
<div className="panel__content__form__section__header__prompt">
|
|
2115
|
+
Select if this Data Product is Internal or External
|
|
2116
|
+
</div>
|
|
2117
|
+
<div className="panel__content__form__section__list__new-item__input">
|
|
2118
|
+
<CustomSelectorInput
|
|
2119
|
+
options={DATA_PRODUCT_TYPE_OPTIONS}
|
|
2120
|
+
onChange={handleDataProductTypeChange}
|
|
2121
|
+
value={
|
|
2122
|
+
product.type instanceof InternalDataProductType
|
|
2123
|
+
? DATA_PRODUCT_TYPE_OPTIONS.find(
|
|
2124
|
+
(option) => option.value === DATA_PRODUCT_TYPE.INTERNAL,
|
|
2125
|
+
)
|
|
2126
|
+
: product.type instanceof ExternalDataProductType
|
|
2127
|
+
? DATA_PRODUCT_TYPE_OPTIONS.find(
|
|
2128
|
+
(option) =>
|
|
2129
|
+
option.value === DATA_PRODUCT_TYPE.EXTERNAL,
|
|
2130
|
+
)
|
|
2131
|
+
: null
|
|
2132
|
+
}
|
|
2133
|
+
darkMode={true}
|
|
2134
|
+
/>
|
|
2135
|
+
</div>
|
|
2136
|
+
{product.type instanceof ExternalDataProductType && (
|
|
2137
|
+
<div className="data-product-editor__external-link">
|
|
2138
|
+
<div className="panel__content__form__section__header__prompt">
|
|
2139
|
+
External Link
|
|
2140
|
+
</div>
|
|
2141
|
+
<textarea
|
|
2142
|
+
className="input input-group__input panel__content__form__section__input input--dark input--small"
|
|
2143
|
+
spellCheck={false}
|
|
2144
|
+
disabled={isReadOnly}
|
|
2145
|
+
placeholder="External URL"
|
|
2146
|
+
value={product.type.link.url}
|
|
2147
|
+
onChange={handleExternalURLChange}
|
|
2148
|
+
style={{
|
|
2149
|
+
resize: 'none',
|
|
2150
|
+
padding: '0.25rem 0.5rem',
|
|
2151
|
+
}}
|
|
2152
|
+
/>
|
|
2153
|
+
<textarea
|
|
2154
|
+
className="input input-group__input panel__content__form__section__input input--dark input--small"
|
|
2155
|
+
spellCheck={false}
|
|
2156
|
+
disabled={isReadOnly}
|
|
2157
|
+
placeholder="External Link Label"
|
|
2158
|
+
value={product.type.link.label ?? ''}
|
|
2159
|
+
onChange={handleExternalLabelChange}
|
|
2160
|
+
style={{
|
|
2161
|
+
resize: 'none',
|
|
2162
|
+
padding: '0.25rem 0.5rem',
|
|
2163
|
+
}}
|
|
2164
|
+
/>
|
|
2165
|
+
</div>
|
|
2166
|
+
)}
|
|
2167
|
+
</div>
|
|
1934
2168
|
<DataProductIconEditor product={product} isReadOnly={isReadOnly} />
|
|
1935
2169
|
</div>
|
|
1936
2170
|
</div>
|
|
@@ -2411,7 +2645,12 @@ export const DataProductEditor = observer(() => {
|
|
|
2411
2645
|
const renderActivivtyBarTab = (): React.ReactNode => {
|
|
2412
2646
|
switch (selectedActivity) {
|
|
2413
2647
|
case DATA_PRODUCT_TAB.HOME:
|
|
2414
|
-
return
|
|
2648
|
+
return (
|
|
2649
|
+
<HomeTab
|
|
2650
|
+
dataProductEditorState={dataProductEditorState}
|
|
2651
|
+
isReadOnly={isReadOnly}
|
|
2652
|
+
/>
|
|
2653
|
+
);
|
|
2415
2654
|
case DATA_PRODUCT_TAB.SUPPORT:
|
|
2416
2655
|
return (
|
|
2417
2656
|
<SupportTab
|
|
@@ -90,6 +90,7 @@ import {
|
|
|
90
90
|
ModelAccessPointGroup,
|
|
91
91
|
stub_Mapping,
|
|
92
92
|
DataProductRuntimeInfo,
|
|
93
|
+
InternalDataProductType,
|
|
93
94
|
} from '@finos/legend-graph';
|
|
94
95
|
import type { DSL_Mapping_LegendStudioApplicationPlugin_Extension } from '../extensions/DSL_Mapping_LegendStudioApplicationPlugin_Extension.js';
|
|
95
96
|
import {
|
|
@@ -117,6 +118,7 @@ import { createEmbeddedData } from './editor-state/element-editor-state/data/Emb
|
|
|
117
118
|
import {
|
|
118
119
|
dataProduct_addAccessPointGroup,
|
|
119
120
|
dataProduct_setTitle,
|
|
121
|
+
dataProduct_setType,
|
|
120
122
|
} from '../graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
|
|
121
123
|
|
|
122
124
|
export const CUSTOM_LABEL = '(custom)';
|
|
@@ -547,6 +549,7 @@ export class NewLakehouseDataProductDriver extends NewElementDriver<DataProduct>
|
|
|
547
549
|
override createElement(name: string): DataProduct {
|
|
548
550
|
const dataProduct = new DataProduct(name);
|
|
549
551
|
dataProduct_setTitle(dataProduct, this.title);
|
|
552
|
+
dataProduct_setType(dataProduct, new InternalDataProductType());
|
|
550
553
|
|
|
551
554
|
if (this.type === DataProductType.LAKEHOUSE) {
|
|
552
555
|
const defaultGroup = new AccessPointGroup();
|
package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts
CHANGED
|
@@ -108,6 +108,11 @@ export enum DATA_PRODUCT_TAB {
|
|
|
108
108
|
APG = 'APG',
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
export enum DATA_PRODUCT_TYPE {
|
|
112
|
+
INTERNAL = 'Internal',
|
|
113
|
+
EXTERNAL = 'External',
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
export class AccessPointState {
|
|
112
117
|
readonly uuid = uuid();
|
|
113
118
|
state: AccessPointGroupState;
|
|
@@ -356,8 +361,18 @@ export class AccessPointGroupState {
|
|
|
356
361
|
return (
|
|
357
362
|
this.accessPointStates.length === 0 ||
|
|
358
363
|
this.value.id === '' ||
|
|
364
|
+
!this.value.description ||
|
|
365
|
+
!this.value.title ||
|
|
359
366
|
Boolean(
|
|
360
367
|
this.accessPointStates.find((apState) => apState.accessPoint.id === ''),
|
|
368
|
+
) ||
|
|
369
|
+
Boolean(
|
|
370
|
+
this.accessPointStates.find((apState) => !apState.accessPoint.title),
|
|
371
|
+
) ||
|
|
372
|
+
Boolean(
|
|
373
|
+
this.accessPointStates.find(
|
|
374
|
+
(apState) => !apState.accessPoint.description,
|
|
375
|
+
),
|
|
361
376
|
)
|
|
362
377
|
);
|
|
363
378
|
}
|
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
type DataProductDiagram,
|
|
35
35
|
type DataProductElementScope,
|
|
36
36
|
observe_APG,
|
|
37
|
+
type DataProductType,
|
|
38
|
+
type ExternalDataProductType,
|
|
37
39
|
observe_Expertise,
|
|
38
40
|
type Expertise,
|
|
39
41
|
} from '@finos/legend-graph';
|
|
@@ -64,6 +66,18 @@ export const accessPoint_setReproducible = action(
|
|
|
64
66
|
},
|
|
65
67
|
);
|
|
66
68
|
|
|
69
|
+
export const accessPoint_setDescription = action(
|
|
70
|
+
(accessPoint: AccessPoint, description: string | undefined) => {
|
|
71
|
+
accessPoint.description = description;
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
export const accessPoint_setTitle = action(
|
|
76
|
+
(accessPoint: AccessPoint, title: string | undefined) => {
|
|
77
|
+
accessPoint.title = title;
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
67
81
|
export const accessPointGroup_setDescription = action(
|
|
68
82
|
(group: AccessPointGroup, description: string) => {
|
|
69
83
|
group.description = description;
|
|
@@ -76,6 +90,12 @@ export const accessPointGroup_setName = action(
|
|
|
76
90
|
},
|
|
77
91
|
);
|
|
78
92
|
|
|
93
|
+
export const accessPointGroup_setTitle = action(
|
|
94
|
+
(group: AccessPointGroup, title: string | undefined) => {
|
|
95
|
+
group.title = title;
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
|
|
79
99
|
export const modelAccessPointGroup_setDefaultRuntime = action(
|
|
80
100
|
(group: ModelAccessPointGroup, runtime: DataProductRuntimeInfo) => {
|
|
81
101
|
group.defaultRuntime = runtime;
|
|
@@ -241,6 +261,24 @@ export const dataProduct_setDescription = action(
|
|
|
241
261
|
},
|
|
242
262
|
);
|
|
243
263
|
|
|
264
|
+
export const dataProduct_setType = action(
|
|
265
|
+
(product: DataProduct, type: DataProductType) => {
|
|
266
|
+
product.type = type;
|
|
267
|
+
},
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
export const externalType_setLinkURL = action(
|
|
271
|
+
(external: ExternalDataProductType, url: string) => {
|
|
272
|
+
external.link.url = url;
|
|
273
|
+
},
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
export const externalType_setLinkLabel = action(
|
|
277
|
+
(external: ExternalDataProductType, label: string | undefined) => {
|
|
278
|
+
external.link.label = label;
|
|
279
|
+
},
|
|
280
|
+
);
|
|
281
|
+
|
|
244
282
|
export const dataProduct_setIcon = action(
|
|
245
283
|
(product: DataProduct, icon: DataProductIcon | undefined) => {
|
|
246
284
|
product.icon = icon;
|