@finos/legend-application-studio 28.19.59 → 28.19.61
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 +7 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +7 -7
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +150 -6
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +20 -1
- 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 +186 -2
- 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 +2 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js +9 -0
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js.map +1 -1
- package/package.json +11 -11
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +7 -7
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +310 -4
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +277 -0
- package/src/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.ts +19 -0
|
@@ -171,6 +171,7 @@ import {
|
|
|
171
171
|
} from '@finos/legend-extension-dsl-data-product';
|
|
172
172
|
import type { LegendStudioApplicationStore } from '../../../../stores/LegendStudioBaseStore.js';
|
|
173
173
|
import type { DepotServerClient } from '@finos/legend-server-depot';
|
|
174
|
+
import { RelationElementEditor } from '../data-editor/RelationElementsDataEditor.js';
|
|
174
175
|
|
|
175
176
|
export enum AP_GROUP_MODAL_ERRORS {
|
|
176
177
|
GROUP_NAME_EMPTY = 'Group Name is empty',
|
|
@@ -231,8 +232,9 @@ const hoverIcon = () => {
|
|
|
231
232
|
};
|
|
232
233
|
|
|
233
234
|
const AccessPointTitle = observer(
|
|
234
|
-
(props: {
|
|
235
|
-
const {
|
|
235
|
+
(props: { accessPointState: LakehouseAccessPointState }) => {
|
|
236
|
+
const { accessPointState } = props;
|
|
237
|
+
const accessPoint = accessPointState.accessPoint;
|
|
236
238
|
const [editingName, setEditingName] = useState(
|
|
237
239
|
accessPoint.id === newNamePlaceholder,
|
|
238
240
|
);
|
|
@@ -240,6 +242,11 @@ const AccessPointTitle = observer(
|
|
|
240
242
|
const handleNameBlur = () => {
|
|
241
243
|
if (accessPoint.id !== newNamePlaceholder) {
|
|
242
244
|
setEditingName(false);
|
|
245
|
+
const relationElement =
|
|
246
|
+
accessPointState.relationElementState?.relationElement;
|
|
247
|
+
if (relationElement) {
|
|
248
|
+
relationElement.paths[0] = accessPoint.id;
|
|
249
|
+
}
|
|
243
250
|
}
|
|
244
251
|
};
|
|
245
252
|
const updateAccessPointName: React.ChangeEventHandler<HTMLTextAreaElement> =
|
|
@@ -446,6 +453,212 @@ const AccessPointGenerationViewer = observer(
|
|
|
446
453
|
},
|
|
447
454
|
);
|
|
448
455
|
|
|
456
|
+
const SampleValuesEditorModal = observer(
|
|
457
|
+
(props: {
|
|
458
|
+
accessPointState: LakehouseAccessPointState;
|
|
459
|
+
isReadOnly: boolean;
|
|
460
|
+
}) => {
|
|
461
|
+
const { accessPointState, isReadOnly } = props;
|
|
462
|
+
const editorStore = accessPointState.state.state.editorStore;
|
|
463
|
+
const dataElementPath =
|
|
464
|
+
accessPointState.relationElementExistsinDataElementReference();
|
|
465
|
+
const closeModal = (): void => {
|
|
466
|
+
accessPointState.setShowSampleValuesModal(false);
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
const handleDeleteSampleValues = (): void => {
|
|
470
|
+
editorStore.applicationStore.alertService.setActionAlertInfo({
|
|
471
|
+
message: `Are you sure you want to delete sample values for Access Point ${accessPointState.accessPoint.id}?`,
|
|
472
|
+
type: ActionAlertType.CAUTION,
|
|
473
|
+
actions: [
|
|
474
|
+
{
|
|
475
|
+
label: 'Confirm',
|
|
476
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
477
|
+
handler: (): void => {
|
|
478
|
+
accessPointState.deleteRelationElement();
|
|
479
|
+
closeModal();
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
label: 'Cancel',
|
|
484
|
+
type: ActionAlertActionType.PROCEED,
|
|
485
|
+
default: true,
|
|
486
|
+
},
|
|
487
|
+
],
|
|
488
|
+
});
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
const handleNavigateToDataElement = (): void => {
|
|
492
|
+
if (dataElementPath) {
|
|
493
|
+
const dataElement =
|
|
494
|
+
editorStore.graphManagerState.graph.getNullableElement(
|
|
495
|
+
dataElementPath,
|
|
496
|
+
);
|
|
497
|
+
if (dataElement) {
|
|
498
|
+
editorStore.graphEditorMode.openElement(dataElement);
|
|
499
|
+
closeModal();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
return (
|
|
505
|
+
<Dialog
|
|
506
|
+
open={accessPointState.showSampleValuesModal}
|
|
507
|
+
onClose={closeModal}
|
|
508
|
+
classes={{
|
|
509
|
+
root: 'editor-modal__root-container',
|
|
510
|
+
container: 'editor-modal__container',
|
|
511
|
+
paper: 'editor-modal__content',
|
|
512
|
+
}}
|
|
513
|
+
>
|
|
514
|
+
<Modal
|
|
515
|
+
className="editor-modal"
|
|
516
|
+
darkMode={
|
|
517
|
+
!editorStore.applicationStore.layoutService
|
|
518
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
519
|
+
}
|
|
520
|
+
>
|
|
521
|
+
<ModalHeader
|
|
522
|
+
title={`${accessPointState.accessPoint.title ?? accessPointState.accessPoint.id} Sample Values`}
|
|
523
|
+
/>
|
|
524
|
+
<ModalBody>
|
|
525
|
+
<div
|
|
526
|
+
style={{
|
|
527
|
+
padding: 0,
|
|
528
|
+
minHeight: 'auto',
|
|
529
|
+
}}
|
|
530
|
+
>
|
|
531
|
+
{dataElementPath !== undefined ? (
|
|
532
|
+
<div
|
|
533
|
+
style={{
|
|
534
|
+
padding: '1.5rem',
|
|
535
|
+
display: 'flex',
|
|
536
|
+
alignItems: 'center',
|
|
537
|
+
justifyContent: 'center',
|
|
538
|
+
gap: '1rem',
|
|
539
|
+
}}
|
|
540
|
+
>
|
|
541
|
+
<span
|
|
542
|
+
style={{
|
|
543
|
+
color: 'var(--color-light-grey-200)',
|
|
544
|
+
whiteSpace: 'nowrap',
|
|
545
|
+
fontSize: '1.3rem',
|
|
546
|
+
fontWeight: 600,
|
|
547
|
+
}}
|
|
548
|
+
>
|
|
549
|
+
Sample Values already in Data Element
|
|
550
|
+
</span>
|
|
551
|
+
<div
|
|
552
|
+
style={{
|
|
553
|
+
display: 'flex',
|
|
554
|
+
alignItems: 'center',
|
|
555
|
+
gap: '0.5rem',
|
|
556
|
+
padding: '0.5rem 1rem',
|
|
557
|
+
background: 'var(--color-dark-grey-100)',
|
|
558
|
+
border: '1px solid var(--color-dark-grey-300)',
|
|
559
|
+
borderRadius: '0.2rem',
|
|
560
|
+
}}
|
|
561
|
+
>
|
|
562
|
+
<span
|
|
563
|
+
style={{
|
|
564
|
+
fontSize: '1.3rem',
|
|
565
|
+
fontWeight: 600,
|
|
566
|
+
color: 'var(--color-light-grey-200)',
|
|
567
|
+
}}
|
|
568
|
+
>
|
|
569
|
+
{dataElementPath}
|
|
570
|
+
</span>
|
|
571
|
+
<button
|
|
572
|
+
className="btn--sm btn--dark"
|
|
573
|
+
onClick={handleNavigateToDataElement}
|
|
574
|
+
tabIndex={-1}
|
|
575
|
+
title="Navigate to data element"
|
|
576
|
+
style={{
|
|
577
|
+
padding: '0.3rem 0.5rem',
|
|
578
|
+
display: 'flex',
|
|
579
|
+
alignItems: 'center',
|
|
580
|
+
}}
|
|
581
|
+
>
|
|
582
|
+
<LongArrowRightIcon />
|
|
583
|
+
</button>
|
|
584
|
+
</div>
|
|
585
|
+
</div>
|
|
586
|
+
) : (
|
|
587
|
+
<>
|
|
588
|
+
<div
|
|
589
|
+
style={{
|
|
590
|
+
color: 'var(--color-orange-200)',
|
|
591
|
+
fontWeight: 'bold',
|
|
592
|
+
fontSize: '14px',
|
|
593
|
+
padding: '0.5rem',
|
|
594
|
+
marginBottom: '1rem',
|
|
595
|
+
textAlign: 'center',
|
|
596
|
+
backgroundColor: 'var(--color-orange-50)',
|
|
597
|
+
border: '2px solid var(--color-orange-200)',
|
|
598
|
+
borderRadius: '4px',
|
|
599
|
+
}}
|
|
600
|
+
>
|
|
601
|
+
DO NOT ADD SENSITIVE DATA
|
|
602
|
+
</div>
|
|
603
|
+
{accessPointState.relationElementState && (
|
|
604
|
+
<Tooltip
|
|
605
|
+
title={
|
|
606
|
+
accessPointState.getRelationElementMismatchMessage() ??
|
|
607
|
+
''
|
|
608
|
+
}
|
|
609
|
+
arrow={true}
|
|
610
|
+
placement="top"
|
|
611
|
+
disableHoverListener={
|
|
612
|
+
!accessPointState.hasRelationElementMismatch
|
|
613
|
+
}
|
|
614
|
+
>
|
|
615
|
+
<div
|
|
616
|
+
style={{
|
|
617
|
+
border: accessPointState.hasRelationElementMismatch
|
|
618
|
+
? '2px solid var(--color-red-300)'
|
|
619
|
+
: 'none',
|
|
620
|
+
borderRadius: '4px',
|
|
621
|
+
padding: accessPointState.hasRelationElementMismatch
|
|
622
|
+
? '0.5rem'
|
|
623
|
+
: '0',
|
|
624
|
+
}}
|
|
625
|
+
>
|
|
626
|
+
<RelationElementEditor
|
|
627
|
+
relationElementState={
|
|
628
|
+
accessPointState.relationElementState
|
|
629
|
+
}
|
|
630
|
+
isReadOnly={isReadOnly}
|
|
631
|
+
/>
|
|
632
|
+
</div>
|
|
633
|
+
</Tooltip>
|
|
634
|
+
)}
|
|
635
|
+
</>
|
|
636
|
+
)}
|
|
637
|
+
</div>
|
|
638
|
+
</ModalBody>
|
|
639
|
+
<ModalFooter>
|
|
640
|
+
{dataElementPath === undefined && (
|
|
641
|
+
<ModalFooterButton
|
|
642
|
+
title="Delete sample values"
|
|
643
|
+
onClick={handleDeleteSampleValues}
|
|
644
|
+
text="Delete"
|
|
645
|
+
type="secondary"
|
|
646
|
+
disabled={isReadOnly}
|
|
647
|
+
/>
|
|
648
|
+
)}
|
|
649
|
+
<ModalFooterButton
|
|
650
|
+
title="Close sample values editor"
|
|
651
|
+
onClick={closeModal}
|
|
652
|
+
text="Close"
|
|
653
|
+
type="secondary"
|
|
654
|
+
/>
|
|
655
|
+
</ModalFooter>
|
|
656
|
+
</Modal>
|
|
657
|
+
</Dialog>
|
|
658
|
+
);
|
|
659
|
+
},
|
|
660
|
+
);
|
|
661
|
+
|
|
449
662
|
export const LakehouseDataProductAccessPointEditor = observer(
|
|
450
663
|
(props: {
|
|
451
664
|
accessPointState: LakehouseAccessPointState;
|
|
@@ -465,6 +678,12 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
465
678
|
const [isHoveringTitle, setIsHoveringTitle] = useState(false);
|
|
466
679
|
const ref = useRef<HTMLDivElement>(null);
|
|
467
680
|
|
|
681
|
+
const handleEditorBlur = useCallback(() => {
|
|
682
|
+
flowResult(lambdaEditorState.updateLambdaRelationColumns()).catch(
|
|
683
|
+
editorStore.applicationStore.alertUnhandledError,
|
|
684
|
+
);
|
|
685
|
+
}, [lambdaEditorState, editorStore.applicationStore]);
|
|
686
|
+
|
|
468
687
|
const handleDescriptionEdit = () => setEditingDescription(true);
|
|
469
688
|
const handleDescriptionBlur = () => {
|
|
470
689
|
setEditingDescription(false);
|
|
@@ -588,7 +807,7 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
588
807
|
/>
|
|
589
808
|
<div style={{ flex: 1 }}>
|
|
590
809
|
<div className="access-point-editor__metadata">
|
|
591
|
-
<AccessPointTitle
|
|
810
|
+
<AccessPointTitle accessPointState={accessPointState} />
|
|
592
811
|
<div className="access-point-editor__info">
|
|
593
812
|
<div className="access-point-editor__reproducible">
|
|
594
813
|
<Checkbox
|
|
@@ -623,6 +842,85 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
623
842
|
<div>Reproducible</div>
|
|
624
843
|
</Tooltip>
|
|
625
844
|
</div>
|
|
845
|
+
{accessPointState.relationElementExistsinDataElementReference() !==
|
|
846
|
+
undefined ? (
|
|
847
|
+
<button
|
|
848
|
+
className="access-point-editor__sample-values-btn"
|
|
849
|
+
onClick={() =>
|
|
850
|
+
accessPointState.setShowSampleValuesModal(true)
|
|
851
|
+
}
|
|
852
|
+
disabled={props.isReadOnly}
|
|
853
|
+
title="Edit sample values"
|
|
854
|
+
style={{
|
|
855
|
+
border: '1px solid var(--color-blue-200)',
|
|
856
|
+
borderRadius: '4px',
|
|
857
|
+
padding: '0.5rem 0.75rem',
|
|
858
|
+
background: 'var(--color-blue-200)',
|
|
859
|
+
cursor: props.isReadOnly ? 'not-allowed' : 'pointer',
|
|
860
|
+
display: 'flex',
|
|
861
|
+
alignItems: 'center',
|
|
862
|
+
gap: '0.5rem',
|
|
863
|
+
color: 'white',
|
|
864
|
+
fontSize: '1.2rem',
|
|
865
|
+
whiteSpace: 'nowrap',
|
|
866
|
+
}}
|
|
867
|
+
>
|
|
868
|
+
<PencilEditIcon />
|
|
869
|
+
<span>Sample Values</span>
|
|
870
|
+
</button>
|
|
871
|
+
) : accessPointState.relationElementState !== undefined ? (
|
|
872
|
+
<button
|
|
873
|
+
className="access-point-editor__sample-values-btn"
|
|
874
|
+
onClick={() =>
|
|
875
|
+
accessPointState.setShowSampleValuesModal(true)
|
|
876
|
+
}
|
|
877
|
+
disabled={props.isReadOnly}
|
|
878
|
+
title="Edit sample values"
|
|
879
|
+
style={{
|
|
880
|
+
border: accessPointState.hasRelationElementMismatch
|
|
881
|
+
? '2px solid var(--color-red-300)'
|
|
882
|
+
: '1px solid var(--color-blue-200)',
|
|
883
|
+
borderRadius: '4px',
|
|
884
|
+
padding: '0.5rem 0.75rem',
|
|
885
|
+
background: 'var(--color-blue-200)',
|
|
886
|
+
cursor: props.isReadOnly ? 'not-allowed' : 'pointer',
|
|
887
|
+
display: 'flex',
|
|
888
|
+
alignItems: 'center',
|
|
889
|
+
gap: '0.5rem',
|
|
890
|
+
color: 'white',
|
|
891
|
+
fontSize: '1.2rem',
|
|
892
|
+
whiteSpace: 'nowrap',
|
|
893
|
+
}}
|
|
894
|
+
>
|
|
895
|
+
<PencilEditIcon />
|
|
896
|
+
<span>Sample Values</span>
|
|
897
|
+
</button>
|
|
898
|
+
) : (
|
|
899
|
+
<button
|
|
900
|
+
className="access-point-editor__sample-values-btn"
|
|
901
|
+
onClick={() => {
|
|
902
|
+
accessPointState.createAndaddRelationElement();
|
|
903
|
+
}}
|
|
904
|
+
disabled={props.isReadOnly}
|
|
905
|
+
title="Add sample values"
|
|
906
|
+
style={{
|
|
907
|
+
border: '1px solid var(--color-blue-200)',
|
|
908
|
+
borderRadius: '4px',
|
|
909
|
+
padding: '0.5rem 0.75rem',
|
|
910
|
+
background: 'var(--color-blue-200)',
|
|
911
|
+
cursor: props.isReadOnly ? 'not-allowed' : 'pointer',
|
|
912
|
+
display: 'flex',
|
|
913
|
+
alignItems: 'center',
|
|
914
|
+
gap: '0.5rem',
|
|
915
|
+
color: 'white',
|
|
916
|
+
fontSize: '1.2rem',
|
|
917
|
+
whiteSpace: 'nowrap',
|
|
918
|
+
}}
|
|
919
|
+
>
|
|
920
|
+
<PlusIcon />
|
|
921
|
+
<span>Sample Values</span>
|
|
922
|
+
</button>
|
|
923
|
+
)}
|
|
626
924
|
{editorStore.applicationStore.config.options
|
|
627
925
|
.dataProductConfig && (
|
|
628
926
|
<AccessPointClassification
|
|
@@ -725,10 +1023,11 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
725
1023
|
style={{
|
|
726
1024
|
background: 'var(--color-blue-200)',
|
|
727
1025
|
borderRadius: '4px',
|
|
728
|
-
marginRight: '
|
|
1026
|
+
marginRight: '1.5rem',
|
|
729
1027
|
padding: '0.25rem 0.5rem',
|
|
730
1028
|
display: 'flex',
|
|
731
1029
|
alignItems: 'center',
|
|
1030
|
+
color: 'white',
|
|
732
1031
|
}}
|
|
733
1032
|
>
|
|
734
1033
|
<ListIcon />
|
|
@@ -833,6 +1132,7 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
833
1132
|
}
|
|
834
1133
|
lambdaEditorState={lambdaEditorState}
|
|
835
1134
|
forceBackdrop={Boolean(lambdaEditorState.parserError)}
|
|
1135
|
+
onEditorBlur={handleEditorBlur}
|
|
836
1136
|
/>
|
|
837
1137
|
</div>
|
|
838
1138
|
</div>
|
|
@@ -856,6 +1156,12 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
856
1156
|
generationOutput={accessPointState.artifactGenerationContent}
|
|
857
1157
|
/>
|
|
858
1158
|
)}
|
|
1159
|
+
{accessPointState.showSampleValuesModal && (
|
|
1160
|
+
<SampleValuesEditorModal
|
|
1161
|
+
accessPointState={accessPointState}
|
|
1162
|
+
isReadOnly={props.isReadOnly}
|
|
1163
|
+
/>
|
|
1164
|
+
)}
|
|
859
1165
|
</div>
|
|
860
1166
|
</PanelDnDEntry>
|
|
861
1167
|
);
|