@finos/legend-application-studio 28.21.42 → 28.21.44
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/__lib__/LegendStudioEvent.d.ts +18 -4
- package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioEvent.js +20 -5
- package/lib/__lib__/LegendStudioEvent.js.map +1 -1
- package/lib/__lib__/LegendStudioTelemetryHelper.d.ts +177 -31
- package/lib/__lib__/LegendStudioTelemetryHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioTelemetryHelper.js +229 -72
- package/lib/__lib__/LegendStudioTelemetryHelper.js.map +1 -1
- package/lib/__lib__/LegendStudioUserDataHelper.d.ts +18 -1
- package/lib/__lib__/LegendStudioUserDataHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioUserDataHelper.js +71 -0
- package/lib/__lib__/LegendStudioUserDataHelper.js.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.d.ts +12 -0
- package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.js +6 -0
- package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
- package/lib/components/LegendStudioWebApplication.d.ts.map +1 -1
- package/lib/components/LegendStudioWebApplication.js +5 -2
- package/lib/components/LegendStudioWebApplication.js.map +1 -1
- package/lib/components/ShowcaseManager.d.ts.map +1 -1
- package/lib/components/ShowcaseManager.js +6 -4
- package/lib/components/ShowcaseManager.js.map +1 -1
- package/lib/components/editor/ActivityBar.d.ts.map +1 -1
- package/lib/components/editor/ActivityBar.js +2 -1
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.js +7 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.d.ts +37 -0
- package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.js +126 -0
- package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.js.map +1 -0
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +22 -127
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceEditor.js +4 -4
- package/lib/components/editor/editor-group/service-editor/ServiceEditor.js.map +1 -1
- package/lib/components/showcase/ShowcaseFeedback.d.ts +36 -0
- package/lib/components/showcase/ShowcaseFeedback.d.ts.map +1 -0
- package/lib/components/showcase/ShowcaseFeedback.js +70 -0
- package/lib/components/showcase/ShowcaseFeedback.js.map +1 -0
- package/lib/components/showcase/ShowcaseViewer.d.ts.map +1 -1
- package/lib/components/showcase/ShowcaseViewer.js +3 -1
- package/lib/components/showcase/ShowcaseViewer.js.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.js +2 -1
- package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/LegendStudioBaseStore.d.ts.map +1 -1
- package/lib/stores/LegendStudioBaseStore.js +1 -0
- package/lib/stores/LegendStudioBaseStore.js.map +1 -1
- package/lib/stores/ShowcaseManagerState.d.ts +5 -3
- package/lib/stores/ShowcaseManagerState.d.ts.map +1 -1
- package/lib/stores/ShowcaseManagerState.js +44 -11
- package/lib/stores/ShowcaseManagerState.js.map +1 -1
- package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
- package/lib/stores/editor/EditorGraphState.js +1 -1
- package/lib/stores/editor/EditorGraphState.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts +2 -1
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +8 -2
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.js +2 -2
- package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.d.ts +19 -0
- package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.js +92 -4
- package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
- package/lib/stores/editor/GraphEditorMode.d.ts +1 -0
- package/lib/stores/editor/GraphEditorMode.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditorMode.js.map +1 -1
- package/lib/stores/editor/StandardEditorMode.d.ts +16 -5
- package/lib/stores/editor/StandardEditorMode.d.ts.map +1 -1
- package/lib/stores/editor/StandardEditorMode.js +4 -2
- package/lib/stores/editor/StandardEditorMode.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +2 -14
- 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 +5 -75
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +0 -11
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +2 -77
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js +4 -4
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/LocalChangesState.d.ts +1 -0
- package/lib/stores/editor/sidebar-state/LocalChangesState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/LocalChangesState.js +27 -0
- package/lib/stores/editor/sidebar-state/LocalChangesState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js +7 -0
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js +7 -2
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js.map +1 -1
- package/lib/stores/lazy-text-editor/LazyTextEditorStore.d.ts +1 -0
- package/lib/stores/lazy-text-editor/LazyTextEditorStore.d.ts.map +1 -1
- package/lib/stores/lazy-text-editor/LazyTextEditorStore.js +3 -0
- package/lib/stores/lazy-text-editor/LazyTextEditorStore.js.map +1 -1
- package/lib/stores/project-reviewer/ProjectReviewerStore.d.ts.map +1 -1
- package/lib/stores/project-reviewer/ProjectReviewerStore.js +2 -0
- package/lib/stores/project-reviewer/ProjectReviewerStore.js.map +1 -1
- package/lib/stores/project-view/ProjectViewerEditorMode.d.ts +2 -2
- package/lib/stores/project-view/ProjectViewerEditorMode.d.ts.map +1 -1
- package/lib/stores/project-view/ProjectViewerEditorMode.js +12 -0
- package/lib/stores/project-view/ProjectViewerEditorMode.js.map +1 -1
- package/lib/stores/project-view/ProjectViewerStore.d.ts.map +1 -1
- package/lib/stores/project-view/ProjectViewerStore.js +3 -1
- package/lib/stores/project-view/ProjectViewerStore.js.map +1 -1
- package/lib/stores/showcase/ShowcaseViewerEditorMode.d.ts.map +1 -1
- package/lib/stores/showcase/ShowcaseViewerEditorMode.js.map +1 -1
- package/lib/stores/showcase/ShowcaseViewerStore.d.ts.map +1 -1
- package/lib/stores/showcase/ShowcaseViewerStore.js +7 -3
- package/lib/stores/showcase/ShowcaseViewerStore.js.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js +1 -0
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
- package/package.json +16 -16
- package/src/__lib__/LegendStudioEvent.ts +22 -6
- package/src/__lib__/LegendStudioTelemetryHelper.ts +425 -104
- package/src/__lib__/LegendStudioUserDataHelper.ts +115 -0
- package/src/application/LegendStudioApplicationConfig.ts +19 -0
- package/src/components/LegendStudioWebApplication.tsx +18 -2
- package/src/components/ShowcaseManager.tsx +24 -4
- package/src/components/editor/ActivityBar.tsx +5 -1
- package/src/components/editor/editor-group/GrammarTextEditor.tsx +18 -1
- package/src/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.tsx +285 -0
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +38 -323
- package/src/components/editor/editor-group/service-editor/ServiceEditor.tsx +4 -0
- package/src/components/showcase/ShowcaseFeedback.tsx +136 -0
- package/src/components/showcase/ShowcaseViewer.tsx +10 -0
- package/src/components/workspace-setup/WorkspaceSetup.tsx +6 -1
- package/src/index.ts +2 -0
- package/src/stores/LegendStudioBaseStore.ts +1 -0
- package/src/stores/ShowcaseManagerState.ts +67 -8
- package/src/stores/editor/EditorGraphState.ts +1 -0
- package/src/stores/editor/EditorStore.ts +26 -4
- package/src/stores/editor/GraphEditFormModeState.ts +2 -0
- package/src/stores/editor/GraphEditGrammarModeState.ts +139 -1
- package/src/stores/editor/GraphEditorMode.ts +1 -0
- package/src/stores/editor/StandardEditorMode.ts +21 -7
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +3 -119
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +1 -136
- package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts +4 -0
- package/src/stores/editor/sidebar-state/LocalChangesState.ts +47 -0
- package/src/stores/editor/sidebar-state/WorkspaceUpdaterState.ts +18 -0
- package/src/stores/editor/sidebar-state/dev-metadata/DevMetadataState.ts +7 -0
- package/src/stores/lazy-text-editor/LazyTextEditorStore.ts +4 -0
- package/src/stores/project-reviewer/ProjectReviewerStore.ts +4 -0
- package/src/stores/project-view/ProjectViewerEditorMode.ts +17 -4
- package/src/stores/project-view/ProjectViewerStore.ts +5 -0
- package/src/stores/showcase/ShowcaseViewerEditorMode.ts +4 -5
- package/src/stores/showcase/ShowcaseViewerStore.ts +12 -2
- package/src/stores/workspace-setup/WorkspaceSetupStore.ts +2 -0
- package/tsconfig.json +2 -0
|
@@ -53,7 +53,6 @@ import {
|
|
|
53
53
|
ModalFooter,
|
|
54
54
|
ModalFooterButton,
|
|
55
55
|
ModalHeader,
|
|
56
|
-
ModalTitle,
|
|
57
56
|
PanelContent,
|
|
58
57
|
PanelDnDEntry,
|
|
59
58
|
PanelEntryDragHandle,
|
|
@@ -198,7 +197,7 @@ import {
|
|
|
198
197
|
} from '@finos/legend-extension-dsl-data-product';
|
|
199
198
|
import type { LegendStudioApplicationStore } from '../../../../stores/LegendStudioBaseStore.js';
|
|
200
199
|
import type { DepotServerClient } from '@finos/legend-server-depot';
|
|
201
|
-
import {
|
|
200
|
+
import { RelationElementSampleValuesEditor } from '../data-editor/RelationElementSampleValuesEditor.js';
|
|
202
201
|
import type {
|
|
203
202
|
AccessPointMeta,
|
|
204
203
|
DataProductDocResponse,
|
|
@@ -492,216 +491,6 @@ const AccessPointGenerationViewer = observer(
|
|
|
492
491
|
},
|
|
493
492
|
);
|
|
494
493
|
|
|
495
|
-
const SampleValuesEditorModal = observer(
|
|
496
|
-
(props: {
|
|
497
|
-
accessPointState: LakehouseAccessPointState;
|
|
498
|
-
isReadOnly: boolean;
|
|
499
|
-
}) => {
|
|
500
|
-
const { accessPointState, isReadOnly } = props;
|
|
501
|
-
const editorStore = accessPointState.state.state.editorStore;
|
|
502
|
-
const dataElementPath =
|
|
503
|
-
accessPointState.relationElementExistsinDataElementReference();
|
|
504
|
-
const closeModal = (): void => {
|
|
505
|
-
accessPointState.setShowSampleValuesModal(false);
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
const handleDeleteSampleValues = (): void => {
|
|
509
|
-
editorStore.applicationStore.alertService.setActionAlertInfo({
|
|
510
|
-
message: `Are you sure you want to delete sample values for Access Point ${accessPointState.accessPoint.id}?`,
|
|
511
|
-
type: ActionAlertType.CAUTION,
|
|
512
|
-
actions: [
|
|
513
|
-
{
|
|
514
|
-
label: 'Confirm',
|
|
515
|
-
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
516
|
-
handler: (): void => {
|
|
517
|
-
accessPointState.deleteRelationElement();
|
|
518
|
-
closeModal();
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
label: 'Cancel',
|
|
523
|
-
type: ActionAlertActionType.PROCEED,
|
|
524
|
-
default: true,
|
|
525
|
-
},
|
|
526
|
-
],
|
|
527
|
-
});
|
|
528
|
-
};
|
|
529
|
-
|
|
530
|
-
const handleNavigateToDataElement = (): void => {
|
|
531
|
-
if (dataElementPath) {
|
|
532
|
-
const dataElement =
|
|
533
|
-
editorStore.graphManagerState.graph.getNullableElement(
|
|
534
|
-
dataElementPath,
|
|
535
|
-
);
|
|
536
|
-
if (dataElement) {
|
|
537
|
-
editorStore.graphEditorMode.openElement(dataElement);
|
|
538
|
-
closeModal();
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
|
-
|
|
543
|
-
return (
|
|
544
|
-
<Dialog
|
|
545
|
-
open={accessPointState.showSampleValuesModal}
|
|
546
|
-
onClose={closeModal}
|
|
547
|
-
classes={{
|
|
548
|
-
root: 'editor-modal__root-container',
|
|
549
|
-
container: 'editor-modal__container',
|
|
550
|
-
paper: 'editor-modal__content',
|
|
551
|
-
}}
|
|
552
|
-
>
|
|
553
|
-
<Modal
|
|
554
|
-
className="editor-modal"
|
|
555
|
-
darkMode={
|
|
556
|
-
!editorStore.applicationStore.layoutService
|
|
557
|
-
.TEMPORARY__isLightColorThemeEnabled
|
|
558
|
-
}
|
|
559
|
-
>
|
|
560
|
-
<ModalHeader
|
|
561
|
-
title={`${accessPointState.accessPoint.title ?? accessPointState.accessPoint.id} Sample Values`}
|
|
562
|
-
/>
|
|
563
|
-
<ModalBody>
|
|
564
|
-
<div
|
|
565
|
-
style={{
|
|
566
|
-
padding: 0,
|
|
567
|
-
height: '100%',
|
|
568
|
-
flex: 1,
|
|
569
|
-
overflowY: 'auto',
|
|
570
|
-
overflowX: 'hidden',
|
|
571
|
-
}}
|
|
572
|
-
>
|
|
573
|
-
{dataElementPath !== undefined ? (
|
|
574
|
-
<div
|
|
575
|
-
style={{
|
|
576
|
-
padding: '1.5rem',
|
|
577
|
-
display: 'flex',
|
|
578
|
-
alignItems: 'center',
|
|
579
|
-
justifyContent: 'center',
|
|
580
|
-
gap: '1rem',
|
|
581
|
-
}}
|
|
582
|
-
>
|
|
583
|
-
<span
|
|
584
|
-
style={{
|
|
585
|
-
color: 'var(--color-light-grey-200)',
|
|
586
|
-
whiteSpace: 'nowrap',
|
|
587
|
-
fontSize: '1.3rem',
|
|
588
|
-
fontWeight: 600,
|
|
589
|
-
}}
|
|
590
|
-
>
|
|
591
|
-
Sample Values already in Data Element
|
|
592
|
-
</span>
|
|
593
|
-
<div
|
|
594
|
-
style={{
|
|
595
|
-
display: 'flex',
|
|
596
|
-
alignItems: 'center',
|
|
597
|
-
gap: '0.5rem',
|
|
598
|
-
padding: '0.5rem 1rem',
|
|
599
|
-
background: 'var(--color-dark-grey-100)',
|
|
600
|
-
border: '1px solid var(--color-dark-grey-300)',
|
|
601
|
-
borderRadius: '0.2rem',
|
|
602
|
-
}}
|
|
603
|
-
>
|
|
604
|
-
<span
|
|
605
|
-
style={{
|
|
606
|
-
fontSize: '1.3rem',
|
|
607
|
-
fontWeight: 600,
|
|
608
|
-
color: 'var(--color-light-grey-200)',
|
|
609
|
-
}}
|
|
610
|
-
>
|
|
611
|
-
{dataElementPath}
|
|
612
|
-
</span>
|
|
613
|
-
<button
|
|
614
|
-
className="btn--sm btn--dark"
|
|
615
|
-
onClick={handleNavigateToDataElement}
|
|
616
|
-
tabIndex={-1}
|
|
617
|
-
title="Navigate to data element"
|
|
618
|
-
style={{
|
|
619
|
-
padding: '0.3rem 0.5rem',
|
|
620
|
-
display: 'flex',
|
|
621
|
-
alignItems: 'center',
|
|
622
|
-
}}
|
|
623
|
-
>
|
|
624
|
-
<LongArrowRightIcon />
|
|
625
|
-
</button>
|
|
626
|
-
</div>
|
|
627
|
-
</div>
|
|
628
|
-
) : (
|
|
629
|
-
<>
|
|
630
|
-
<div
|
|
631
|
-
style={{
|
|
632
|
-
color: 'var(--color-orange-200)',
|
|
633
|
-
fontWeight: 'bold',
|
|
634
|
-
fontSize: '14px',
|
|
635
|
-
padding: '0.5rem',
|
|
636
|
-
marginBottom: '1rem',
|
|
637
|
-
textAlign: 'center',
|
|
638
|
-
backgroundColor: 'var(--color-orange-50)',
|
|
639
|
-
border: '2px solid var(--color-orange-200)',
|
|
640
|
-
borderRadius: '4px',
|
|
641
|
-
}}
|
|
642
|
-
>
|
|
643
|
-
DO NOT ADD SENSITIVE DATA
|
|
644
|
-
</div>
|
|
645
|
-
{accessPointState.relationElementState && (
|
|
646
|
-
<Tooltip
|
|
647
|
-
title={
|
|
648
|
-
accessPointState.getRelationElementMismatchMessage() ??
|
|
649
|
-
''
|
|
650
|
-
}
|
|
651
|
-
arrow={true}
|
|
652
|
-
placement="top"
|
|
653
|
-
disableHoverListener={
|
|
654
|
-
!accessPointState.hasRelationElementMismatch
|
|
655
|
-
}
|
|
656
|
-
>
|
|
657
|
-
<div
|
|
658
|
-
style={{
|
|
659
|
-
border: accessPointState.hasRelationElementMismatch
|
|
660
|
-
? '2px solid var(--color-red-300)'
|
|
661
|
-
: 'none',
|
|
662
|
-
borderRadius: '4px',
|
|
663
|
-
padding: accessPointState.hasRelationElementMismatch
|
|
664
|
-
? '0.5rem'
|
|
665
|
-
: '0',
|
|
666
|
-
}}
|
|
667
|
-
>
|
|
668
|
-
<RelationElementEditor
|
|
669
|
-
relationElementState={
|
|
670
|
-
accessPointState.relationElementState
|
|
671
|
-
}
|
|
672
|
-
isReadOnly={isReadOnly}
|
|
673
|
-
hideColumnDefinitions={true}
|
|
674
|
-
/>
|
|
675
|
-
</div>
|
|
676
|
-
</Tooltip>
|
|
677
|
-
)}
|
|
678
|
-
</>
|
|
679
|
-
)}
|
|
680
|
-
</div>
|
|
681
|
-
</ModalBody>
|
|
682
|
-
<ModalFooter>
|
|
683
|
-
{dataElementPath === undefined && (
|
|
684
|
-
<ModalFooterButton
|
|
685
|
-
title="Delete sample values"
|
|
686
|
-
onClick={handleDeleteSampleValues}
|
|
687
|
-
text="Delete"
|
|
688
|
-
type="secondary"
|
|
689
|
-
disabled={isReadOnly}
|
|
690
|
-
/>
|
|
691
|
-
)}
|
|
692
|
-
<ModalFooterButton
|
|
693
|
-
title="Close sample values editor"
|
|
694
|
-
onClick={closeModal}
|
|
695
|
-
text="Close"
|
|
696
|
-
type="secondary"
|
|
697
|
-
/>
|
|
698
|
-
</ModalFooter>
|
|
699
|
-
</Modal>
|
|
700
|
-
</Dialog>
|
|
701
|
-
);
|
|
702
|
-
},
|
|
703
|
-
);
|
|
704
|
-
|
|
705
494
|
export const LakehouseDataProductAccessPointEditor = observer(
|
|
706
495
|
(props: {
|
|
707
496
|
accessPointState: LakehouseAccessPointState;
|
|
@@ -971,58 +760,39 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
971
760
|
<div>Reproducible</div>
|
|
972
761
|
</Tooltip>
|
|
973
762
|
</div>
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
</button>
|
|
1008
|
-
) : (
|
|
1009
|
-
<button
|
|
1010
|
-
className="access-point-editor__sample-values-btn"
|
|
1011
|
-
onClick={() => {
|
|
1012
|
-
flowResult(
|
|
1013
|
-
accessPointState.createAndaddRelationElement(),
|
|
1014
|
-
).catch(editorStore.applicationStore.alertUnhandledError);
|
|
1015
|
-
}}
|
|
1016
|
-
disabled={props.isReadOnly}
|
|
1017
|
-
title="Add sample values"
|
|
1018
|
-
style={{
|
|
1019
|
-
cursor: props.isReadOnly ? 'not-allowed' : 'pointer',
|
|
1020
|
-
}}
|
|
1021
|
-
>
|
|
1022
|
-
<PlusIcon />
|
|
1023
|
-
<span>Sample Values</span>
|
|
1024
|
-
</button>
|
|
1025
|
-
)}
|
|
763
|
+
<RelationElementSampleValuesEditor
|
|
764
|
+
title={`${accessPointState.accessPoint.title ?? accessPointState.accessPoint.id} Sample Values`}
|
|
765
|
+
relationElementState={accessPointState.relationElementState}
|
|
766
|
+
isReadOnly={props.isReadOnly}
|
|
767
|
+
hideColumnDefinitions={true}
|
|
768
|
+
hasMismatch={accessPointState.hasRelationElementMismatch}
|
|
769
|
+
mismatchMessage={accessPointState.getRelationElementMismatchMessage()}
|
|
770
|
+
readOnlySource={(() => {
|
|
771
|
+
const dataElementPath =
|
|
772
|
+
accessPointState.relationElementExistsinDataElementReference();
|
|
773
|
+
return dataElementPath !== undefined
|
|
774
|
+
? {
|
|
775
|
+
label: dataElementPath,
|
|
776
|
+
onNavigate: () => {
|
|
777
|
+
const dataElement =
|
|
778
|
+
editorStore.graphManagerState.graph.getNullableElement(
|
|
779
|
+
dataElementPath,
|
|
780
|
+
);
|
|
781
|
+
if (dataElement) {
|
|
782
|
+
editorStore.graphEditorMode.openElement(
|
|
783
|
+
dataElement,
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
}
|
|
788
|
+
: undefined;
|
|
789
|
+
})()}
|
|
790
|
+
deleteConfirmMessage={`Are you sure you want to delete sample values for Access Point ${accessPointState.accessPoint.id}?`}
|
|
791
|
+
onAdd={() =>
|
|
792
|
+
flowResult(accessPointState.createAndaddRelationElement())
|
|
793
|
+
}
|
|
794
|
+
onDelete={() => accessPointState.deleteRelationElement()}
|
|
795
|
+
/>
|
|
1026
796
|
{editorStore.applicationStore.config.options
|
|
1027
797
|
.dataProductConfig && (
|
|
1028
798
|
<AccessPointClassification
|
|
@@ -1277,68 +1047,12 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
|
1277
1047
|
generationOutput={accessPointState.artifactGenerationContent}
|
|
1278
1048
|
/>
|
|
1279
1049
|
)}
|
|
1280
|
-
{accessPointState.showSampleValuesModal && (
|
|
1281
|
-
<SampleValuesEditorModal
|
|
1282
|
-
accessPointState={accessPointState}
|
|
1283
|
-
isReadOnly={props.isReadOnly}
|
|
1284
|
-
/>
|
|
1285
|
-
)}
|
|
1286
1050
|
</div>
|
|
1287
1051
|
</PanelDnDEntry>
|
|
1288
1052
|
);
|
|
1289
1053
|
},
|
|
1290
1054
|
);
|
|
1291
1055
|
|
|
1292
|
-
const DataProductDeploymentResponseModal = observer(
|
|
1293
|
-
(props: { state: DataProductEditorState }) => {
|
|
1294
|
-
const { state } = props;
|
|
1295
|
-
const applicationStore = state.editorStore.applicationStore;
|
|
1296
|
-
const closeModal = (): void => state.setDeployResponse(undefined);
|
|
1297
|
-
return (
|
|
1298
|
-
<Dialog
|
|
1299
|
-
open={Boolean(state.deployResponse)}
|
|
1300
|
-
classes={{
|
|
1301
|
-
root: 'editor-modal__root-container',
|
|
1302
|
-
container: 'editor-modal__container',
|
|
1303
|
-
paper: 'editor-modal__content',
|
|
1304
|
-
}}
|
|
1305
|
-
onClose={closeModal}
|
|
1306
|
-
>
|
|
1307
|
-
<Modal
|
|
1308
|
-
darkMode={
|
|
1309
|
-
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
|
1310
|
-
}
|
|
1311
|
-
className="editor-modal"
|
|
1312
|
-
>
|
|
1313
|
-
<ModalHeader>
|
|
1314
|
-
<ModalTitle title="Data Product Deployment Response" />
|
|
1315
|
-
</ModalHeader>
|
|
1316
|
-
<ModalBody>
|
|
1317
|
-
<PanelContent>
|
|
1318
|
-
<CodeEditor
|
|
1319
|
-
inputValue={JSON.stringify(
|
|
1320
|
-
state.deployResponse?.content ?? {},
|
|
1321
|
-
null,
|
|
1322
|
-
2,
|
|
1323
|
-
)}
|
|
1324
|
-
isReadOnly={true}
|
|
1325
|
-
language={CODE_EDITOR_LANGUAGE.JSON}
|
|
1326
|
-
/>
|
|
1327
|
-
</PanelContent>
|
|
1328
|
-
</ModalBody>
|
|
1329
|
-
<ModalFooter>
|
|
1330
|
-
<ModalFooterButton
|
|
1331
|
-
onClick={closeModal}
|
|
1332
|
-
text="Close"
|
|
1333
|
-
type="secondary"
|
|
1334
|
-
/>
|
|
1335
|
-
</ModalFooter>
|
|
1336
|
-
</Modal>
|
|
1337
|
-
</Dialog>
|
|
1338
|
-
);
|
|
1339
|
-
},
|
|
1340
|
-
);
|
|
1341
|
-
|
|
1342
1056
|
const AccessPointGroupPublicToggle = observer(
|
|
1343
1057
|
(props: { groupState: AccessPointGroupState }) => {
|
|
1344
1058
|
const { groupState } = props;
|
|
@@ -1580,6 +1294,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1580
1294
|
LegendStudioTelemetryHelper.logEvent_DataProductLegendAISuggestLaunched(
|
|
1581
1295
|
editorStore.applicationStore.telemetryService,
|
|
1582
1296
|
productEditorState.product.path,
|
|
1297
|
+
editorStore.editorMode.getSourceInfo(),
|
|
1583
1298
|
);
|
|
1584
1299
|
setIsSuggestingWithAI(true);
|
|
1585
1300
|
setAISuggestion(undefined);
|
|
@@ -1602,6 +1317,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1602
1317
|
editorStore.applicationStore.telemetryService,
|
|
1603
1318
|
productEditorState.product.path,
|
|
1604
1319
|
error.message,
|
|
1320
|
+
editorStore.editorMode.getSourceInfo(),
|
|
1605
1321
|
);
|
|
1606
1322
|
if (
|
|
1607
1323
|
error instanceof NetworkClientError &&
|
|
@@ -1630,6 +1346,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1630
1346
|
LegendStudioTelemetryHelper.logEvent_DataProductLegendAISuggestApplied(
|
|
1631
1347
|
editorStore.applicationStore.telemetryService,
|
|
1632
1348
|
productEditorState.product.path,
|
|
1349
|
+
editorStore.editorMode.getSourceInfo(),
|
|
1633
1350
|
);
|
|
1634
1351
|
// Find matching group in the response
|
|
1635
1352
|
const gIdx =
|
|
@@ -1672,6 +1389,7 @@ const AccessPointGroupEditor = observer(
|
|
|
1672
1389
|
LegendStudioTelemetryHelper.logEvent_DataProductLegendAISuggestDiscarded(
|
|
1673
1390
|
editorStore.applicationStore.telemetryService,
|
|
1674
1391
|
productEditorState.product.path,
|
|
1392
|
+
editorStore.editorMode.getSourceInfo(),
|
|
1675
1393
|
);
|
|
1676
1394
|
setAISuggestion(undefined);
|
|
1677
1395
|
};
|
|
@@ -2198,9 +1916,6 @@ const AccessPointGroupTab = observer(
|
|
|
2198
1916
|
/>
|
|
2199
1917
|
)}
|
|
2200
1918
|
</PanelContent>
|
|
2201
|
-
{dataProductEditorState.deployResponse && (
|
|
2202
|
-
<DataProductDeploymentResponseModal state={dataProductEditorState} />
|
|
2203
|
-
)}
|
|
2204
1919
|
</div>
|
|
2205
1920
|
);
|
|
2206
1921
|
},
|
|
@@ -274,6 +274,7 @@ const ServiceGeneralEditor = observer(() => {
|
|
|
274
274
|
LegendStudioTelemetryHelper.logEvent_ServiceLegendAISuggestLaunched(
|
|
275
275
|
applicationStore.telemetryService,
|
|
276
276
|
service.path,
|
|
277
|
+
editorStore.editorMode.getSourceInfo(),
|
|
277
278
|
);
|
|
278
279
|
setIsSuggestingWithAI(true);
|
|
279
280
|
setAIDocSuggestion(undefined);
|
|
@@ -290,6 +291,7 @@ const ServiceGeneralEditor = observer(() => {
|
|
|
290
291
|
applicationStore.telemetryService,
|
|
291
292
|
service.path,
|
|
292
293
|
error.message,
|
|
294
|
+
editorStore.editorMode.getSourceInfo(),
|
|
293
295
|
);
|
|
294
296
|
if (
|
|
295
297
|
error instanceof NetworkClientError &&
|
|
@@ -315,6 +317,7 @@ const ServiceGeneralEditor = observer(() => {
|
|
|
315
317
|
LegendStudioTelemetryHelper.logEvent_ServiceLegendAISuggestApplied(
|
|
316
318
|
applicationStore.telemetryService,
|
|
317
319
|
service.path,
|
|
320
|
+
editorStore.editorMode.getSourceInfo(),
|
|
318
321
|
);
|
|
319
322
|
service_setDocumentation(service, aiDocSuggestion);
|
|
320
323
|
setAIDocSuggestion(undefined);
|
|
@@ -323,6 +326,7 @@ const ServiceGeneralEditor = observer(() => {
|
|
|
323
326
|
LegendStudioTelemetryHelper.logEvent_ServiceLegendAISuggestDiscarded(
|
|
324
327
|
applicationStore.telemetryService,
|
|
325
328
|
service.path,
|
|
329
|
+
editorStore.editorMode.getSourceInfo(),
|
|
326
330
|
);
|
|
327
331
|
setAIDocSuggestion(undefined);
|
|
328
332
|
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { useEffect, useRef, useState } from 'react';
|
|
18
|
+
import { clsx, ThumbsUpIcon, ThumbsDownIcon } from '@finos/legend-art';
|
|
19
|
+
import { useApplicationStore } from '@finos/legend-application';
|
|
20
|
+
import { LegendStudioUserDataHelper } from '../../__lib__/LegendStudioUserDataHelper.js';
|
|
21
|
+
import {
|
|
22
|
+
LegendStudioTelemetryHelper,
|
|
23
|
+
SHOWCASE_FEEDBACK_VOTE,
|
|
24
|
+
type SHOWCASE_FEEDBACK_SURFACE,
|
|
25
|
+
} from '../../__lib__/LegendStudioTelemetryHelper.js';
|
|
26
|
+
|
|
27
|
+
const THANKS_DISPLAY_DURATION_MS = 2500;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* "Was this showcase helpful?" widget.
|
|
31
|
+
*
|
|
32
|
+
* v1 storage strategy: telemetry is the source of truth for aggregate
|
|
33
|
+
* analysis (`showcase.viewer.feedback.submit`). The user's vote per
|
|
34
|
+
* showcase is cached in browser `UserDataService` (localStorage) purely
|
|
35
|
+
* so we can suppress re-prompting on revisit — there is no backend today.
|
|
36
|
+
*
|
|
37
|
+
* UX: once a user votes, the buttons are replaced with a brief
|
|
38
|
+
* "Thanks for the feedback!" message and then the whole widget unmounts.
|
|
39
|
+
* On subsequent visits to the same showcase, the widget renders nothing.
|
|
40
|
+
*/
|
|
41
|
+
export const ShowcaseFeedback = (props: {
|
|
42
|
+
showcasePath: string;
|
|
43
|
+
title?: string | undefined;
|
|
44
|
+
surface: SHOWCASE_FEEDBACK_SURFACE;
|
|
45
|
+
/** Optional CSS class hook so the two mount points can size / align. */
|
|
46
|
+
className?: string | undefined;
|
|
47
|
+
}) => {
|
|
48
|
+
const { showcasePath, title, surface, className } = props;
|
|
49
|
+
const applicationStore = useApplicationStore();
|
|
50
|
+
const alreadyVoted = Boolean(
|
|
51
|
+
LegendStudioUserDataHelper.showcaseFeedback_getVote(
|
|
52
|
+
applicationStore.userDataService,
|
|
53
|
+
showcasePath,
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
const [phase, setPhase] = useState<'prompt' | 'thanks' | 'done'>(
|
|
57
|
+
alreadyVoted ? 'done' : 'prompt',
|
|
58
|
+
);
|
|
59
|
+
const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
60
|
+
undefined,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
useEffect(
|
|
64
|
+
() => (): void => {
|
|
65
|
+
if (timeoutRef.current !== undefined) {
|
|
66
|
+
clearTimeout(timeoutRef.current);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
[],
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const submit = (vote: SHOWCASE_FEEDBACK_VOTE): void => {
|
|
73
|
+
LegendStudioUserDataHelper.showcaseFeedback_recordVote(
|
|
74
|
+
applicationStore.userDataService,
|
|
75
|
+
{
|
|
76
|
+
showcasePath,
|
|
77
|
+
vote: vote === SHOWCASE_FEEDBACK_VOTE.UP ? 'up' : 'down',
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
LegendStudioTelemetryHelper.logEvent_ShowcaseFeedbackSubmit(
|
|
81
|
+
applicationStore.telemetryService,
|
|
82
|
+
{
|
|
83
|
+
showcasePath,
|
|
84
|
+
title,
|
|
85
|
+
vote,
|
|
86
|
+
surface,
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
setPhase('thanks');
|
|
90
|
+
timeoutRef.current = setTimeout(() => {
|
|
91
|
+
setPhase('done');
|
|
92
|
+
}, THANKS_DISPLAY_DURATION_MS);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (phase === 'done') {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (phase === 'thanks') {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={clsx('showcase-feedback', className)}
|
|
103
|
+
role="status"
|
|
104
|
+
aria-live="polite"
|
|
105
|
+
>
|
|
106
|
+
<div className="showcase-feedback__prompt">
|
|
107
|
+
Thanks for the feedback!
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<div className={clsx('showcase-feedback', className)}>
|
|
115
|
+
<div className="showcase-feedback__prompt">Was this helpful?</div>
|
|
116
|
+
<button
|
|
117
|
+
type="button"
|
|
118
|
+
className="showcase-feedback__btn"
|
|
119
|
+
tabIndex={-1}
|
|
120
|
+
title="Thumbs up"
|
|
121
|
+
onClick={() => submit(SHOWCASE_FEEDBACK_VOTE.UP)}
|
|
122
|
+
>
|
|
123
|
+
<ThumbsUpIcon />
|
|
124
|
+
</button>
|
|
125
|
+
<button
|
|
126
|
+
type="button"
|
|
127
|
+
className="showcase-feedback__btn"
|
|
128
|
+
tabIndex={-1}
|
|
129
|
+
title="Thumbs down"
|
|
130
|
+
onClick={() => submit(SHOWCASE_FEEDBACK_VOTE.DOWN)}
|
|
131
|
+
>
|
|
132
|
+
<ThumbsDownIcon />
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
@@ -62,6 +62,8 @@ import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js';
|
|
|
62
62
|
import { Explorer } from '../editor/side-bar/Explorer.js';
|
|
63
63
|
import { PanelGroup } from '../editor/panel-group/PanelGroup.js';
|
|
64
64
|
import { QueryDataCubeViewer } from '@finos/legend-query-builder';
|
|
65
|
+
import { ShowcaseFeedback } from './ShowcaseFeedback.js';
|
|
66
|
+
import { SHOWCASE_FEEDBACK_SURFACE } from '../../__lib__/LegendStudioTelemetryHelper.js';
|
|
65
67
|
|
|
66
68
|
const ShowcaseViewerStatusBar = observer(() => {
|
|
67
69
|
const editorStore = useEditorStore();
|
|
@@ -109,6 +111,14 @@ const ShowcaseViewerStatusBar = observer(() => {
|
|
|
109
111
|
</div>
|
|
110
112
|
</div>
|
|
111
113
|
)}
|
|
114
|
+
{showcase && (
|
|
115
|
+
<ShowcaseFeedback
|
|
116
|
+
className="showcase-feedback--status-bar"
|
|
117
|
+
showcasePath={showcaseStore.showcase.path}
|
|
118
|
+
title={showcase.title}
|
|
119
|
+
surface={SHOWCASE_FEEDBACK_SURFACE.DEEP_LINK_VIEWER}
|
|
120
|
+
/>
|
|
121
|
+
)}
|
|
112
122
|
</div>
|
|
113
123
|
<div className="editor__status-bar__right">
|
|
114
124
|
<button
|
|
@@ -80,6 +80,7 @@ import {
|
|
|
80
80
|
import { Project } from '@finos/legend-server-sdlc';
|
|
81
81
|
import { WorkspaceSetupStore } from '../../stores/workspace-setup/WorkspaceSetupStore.js';
|
|
82
82
|
import { openShowcaseManager } from '../../stores/ShowcaseManagerState.js';
|
|
83
|
+
import { SHOWCASE_MANAGER_ENTRY_POINT } from '../../__lib__/LegendStudioTelemetryHelper.js';
|
|
83
84
|
|
|
84
85
|
const WorkspaceSetupStoreContext = createContext<
|
|
85
86
|
WorkspaceSetupStore | undefined
|
|
@@ -151,7 +152,11 @@ export const ShowcaseCard: React.FC<{ hideDocumentation?: boolean }> = (
|
|
|
151
152
|
<OpenIcon />
|
|
152
153
|
</div>
|
|
153
154
|
),
|
|
154
|
-
action: () =>
|
|
155
|
+
action: () =>
|
|
156
|
+
openShowcaseManager(
|
|
157
|
+
applicationStore,
|
|
158
|
+
SHOWCASE_MANAGER_ENTRY_POINT.WORKSPACE_SETUP,
|
|
159
|
+
),
|
|
155
160
|
},
|
|
156
161
|
]}
|
|
157
162
|
isStable={true}
|
package/src/index.ts
CHANGED
|
@@ -118,9 +118,11 @@ export {
|
|
|
118
118
|
externalFormatData_setContentType,
|
|
119
119
|
} from './stores/graph-modifier/DSL_Data_GraphModifierHelper.js';
|
|
120
120
|
export { ExternalFormatDataEditor } from './components/editor/editor-group/data-editor/DataElementEditor.js';
|
|
121
|
+
export { RelationElementSampleValuesEditor } from './components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.js';
|
|
121
122
|
export {
|
|
122
123
|
ExternalFormatDataState,
|
|
123
124
|
EmbeddedDataState,
|
|
125
|
+
RelationElementState,
|
|
124
126
|
} from './stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js';
|
|
125
127
|
export type { EmbeddedDataTypeOption } from './stores/editor/editor-state/element-editor-state/data/DataEditorState.js';
|
|
126
128
|
|
|
@@ -159,6 +159,7 @@ export class LegendStudioBaseStore {
|
|
|
159
159
|
serverUrl: this.applicationStore.config.sdlcServerUrl,
|
|
160
160
|
baseHeaders: this.applicationStore.config.sdlcServerBaseHeaders,
|
|
161
161
|
client: this.applicationStore.config.sdlcServerClient,
|
|
162
|
+
useCookieAuthOnly: this.applicationStore.config.sdlcUseCookieAuthOnly,
|
|
162
163
|
// On a mid-session 401, auto-launch the popup re-auth flow. The
|
|
163
164
|
// handler enforces a one-attempt-per-episode guard to prevent endless
|
|
164
165
|
// retry loops; when it gives up, the StatusBar manual button remains
|