@finos/legend-application-studio 28.21.3 → 28.21.5
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/EmbeddedDataEditor.d.ts +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js +3 -3
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts +3 -0
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +72 -52
- 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 +22 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts +23 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js +267 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +113 -75
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.d.ts.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js +39 -5
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js.map +1 -1
- package/lib/components/editor/side-bar/DevMetadataPanel.d.ts.map +1 -1
- package/lib/components/editor/side-bar/DevMetadataPanel.js +37 -6
- package/lib/components/editor/side-bar/DevMetadataPanel.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/editor-state/element-editor-state/data/EmbeddedDataState.d.ts +17 -2
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js +56 -49
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +4 -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 +4 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts +113 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js +647 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +18 -4
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +214 -53
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.d.ts +17 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.js +46 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts +9 -0
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js +55 -0
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js.map +1 -1
- package/package.json +16 -16
- package/src/components/editor/editor-group/data-editor/EmbeddedDataEditor.tsx +3 -0
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +331 -231
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +32 -0
- package/src/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.tsx +935 -0
- package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +425 -308
- package/src/components/editor/editor-group/testable/TestableSharedComponents.tsx +160 -15
- package/src/components/editor/side-bar/DevMetadataPanel.tsx +194 -10
- package/src/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.ts +82 -51
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +4 -0
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.ts +927 -0
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +303 -72
- package/src/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.ts +66 -0
- package/src/stores/editor/sidebar-state/dev-metadata/DevMetadataState.ts +76 -0
- package/tsconfig.json +2 -0
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
|
+
BlankPanelPlaceholder,
|
|
18
19
|
clsx,
|
|
19
20
|
CompareIcon,
|
|
20
21
|
ContextMenu,
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
} from '@finos/legend-art';
|
|
39
40
|
import {
|
|
40
41
|
type DataElement,
|
|
42
|
+
DataProduct,
|
|
41
43
|
type ValueSpecification,
|
|
42
44
|
type VariableExpression,
|
|
43
45
|
type PrimitiveInstanceValue,
|
|
@@ -61,6 +63,8 @@ import {
|
|
|
61
63
|
type TestAssertionState,
|
|
62
64
|
EqualToAssertionState,
|
|
63
65
|
EqualToAssertFailState,
|
|
66
|
+
EqualToRelationAssertionState,
|
|
67
|
+
EqualToRelationAssertFailState,
|
|
64
68
|
} from '../../../../stores/editor/editor-state/element-editor-state/testable/TestAssertionState.js';
|
|
65
69
|
import { externalFormatData_setData } from '../../../../stores/graph-modifier/DSL_Data_GraphModifierHelper.js';
|
|
66
70
|
import { TESTABLE_RESULT } from '../../../../stores/editor/sidebar-state/testable/GlobalTestRunnerState.js';
|
|
@@ -76,11 +80,13 @@ import {
|
|
|
76
80
|
getPackageableElementOptionFormatter,
|
|
77
81
|
} from '@finos/legend-lego/graph-editor';
|
|
78
82
|
import type { TestParamContentType } from '../../../../stores/editor/utils/TestableUtils.js';
|
|
83
|
+
import { RelationElementEditor } from '../data-editor/RelationElementsDataEditor.js';
|
|
79
84
|
import {
|
|
80
85
|
BasicValueSpecificationEditor,
|
|
81
86
|
buildDefaultInstanceValue,
|
|
82
87
|
} from '@finos/legend-query-builder';
|
|
83
88
|
import { useApplicationStore } from '@finos/legend-application';
|
|
89
|
+
import type { DataProductTestState } from '../../../../stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js';
|
|
84
90
|
|
|
85
91
|
export const SharedDataElementModal = observer(
|
|
86
92
|
(props: {
|
|
@@ -575,6 +581,123 @@ const TestErrorViewer = observer((props: { testError: TestError }) => {
|
|
|
575
581
|
);
|
|
576
582
|
});
|
|
577
583
|
|
|
584
|
+
const EqualToRelationAsssertionEditor = observer(
|
|
585
|
+
(props: {
|
|
586
|
+
testAssertionEditorState: TestAssertionEditorState;
|
|
587
|
+
equalToRelationAssertionState: EqualToRelationAssertionState;
|
|
588
|
+
}) => {
|
|
589
|
+
const { equalToRelationAssertionState, testAssertionEditorState } = props;
|
|
590
|
+
const isReadOnly = testAssertionEditorState.testState.isReadOnly;
|
|
591
|
+
|
|
592
|
+
return (
|
|
593
|
+
<RelationElementEditor
|
|
594
|
+
relationElementState={
|
|
595
|
+
equalToRelationAssertionState.expectedRelationElementState
|
|
596
|
+
}
|
|
597
|
+
isReadOnly={isReadOnly}
|
|
598
|
+
/>
|
|
599
|
+
);
|
|
600
|
+
},
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
const DataProductEqualToRelationAssertionEditor = observer(
|
|
604
|
+
(props: { testAssertionEditorState: TestAssertionEditorState }) => {
|
|
605
|
+
const { testAssertionEditorState } = props;
|
|
606
|
+
const testState =
|
|
607
|
+
testAssertionEditorState.testState as DataProductTestState;
|
|
608
|
+
const isReadOnly = testAssertionEditorState.testState.isReadOnly;
|
|
609
|
+
const relationElementState = testState.testDataRelationState;
|
|
610
|
+
|
|
611
|
+
return (
|
|
612
|
+
<div className="service-test-data-editor panel">
|
|
613
|
+
<div className="panel__content__form__section">
|
|
614
|
+
<div className="panel__content__form__section__header__label">
|
|
615
|
+
Access Point: {testState.accessPointLabel}
|
|
616
|
+
</div>
|
|
617
|
+
</div>
|
|
618
|
+
{relationElementState ? (
|
|
619
|
+
<RelationElementEditor
|
|
620
|
+
relationElementState={relationElementState}
|
|
621
|
+
isReadOnly={isReadOnly}
|
|
622
|
+
hideColumnDefinitions={true}
|
|
623
|
+
/>
|
|
624
|
+
) : (
|
|
625
|
+
<BlankPanelPlaceholder
|
|
626
|
+
text="No expected columns"
|
|
627
|
+
tooltipText="No expected columns configured for this test"
|
|
628
|
+
/>
|
|
629
|
+
)}
|
|
630
|
+
</div>
|
|
631
|
+
);
|
|
632
|
+
},
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
const EqualToRelationAssertFailViewer = observer(
|
|
636
|
+
(props: {
|
|
637
|
+
equalToRelationAssertFailState: EqualToRelationAssertFailState;
|
|
638
|
+
}) => {
|
|
639
|
+
const { equalToRelationAssertFailState } = props;
|
|
640
|
+
const applicationStore =
|
|
641
|
+
equalToRelationAssertFailState.resultState.editorStore.applicationStore;
|
|
642
|
+
const open = (): void => equalToRelationAssertFailState.setDiffModal(true);
|
|
643
|
+
const close = (): void =>
|
|
644
|
+
equalToRelationAssertFailState.setDiffModal(false);
|
|
645
|
+
const expected = equalToRelationAssertFailState.status.expected;
|
|
646
|
+
const actual = equalToRelationAssertFailState.status.actual;
|
|
647
|
+
|
|
648
|
+
return (
|
|
649
|
+
<>
|
|
650
|
+
<div className="equal-to-json-editor__message" onClick={open}>
|
|
651
|
+
{`<Click to see difference>`}
|
|
652
|
+
</div>
|
|
653
|
+
{equalToRelationAssertFailState.diffModal && (
|
|
654
|
+
<Dialog
|
|
655
|
+
open={Boolean(equalToRelationAssertFailState.diffModal)}
|
|
656
|
+
onClose={close}
|
|
657
|
+
classes={{
|
|
658
|
+
root: 'editor-modal__root-container',
|
|
659
|
+
container: 'editor-modal__container',
|
|
660
|
+
paper: 'editor-modal__content',
|
|
661
|
+
}}
|
|
662
|
+
>
|
|
663
|
+
<Modal
|
|
664
|
+
darkMode={
|
|
665
|
+
!applicationStore.layoutService
|
|
666
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
667
|
+
}
|
|
668
|
+
className="editor-modal"
|
|
669
|
+
>
|
|
670
|
+
<ModalHeader>
|
|
671
|
+
<div className="equal-to-json-result__diff__summary">
|
|
672
|
+
<div className="equal-to-json-result__diff__header__label">
|
|
673
|
+
expected
|
|
674
|
+
</div>
|
|
675
|
+
<div className="equal-to-json-result__diff__icon">
|
|
676
|
+
<CompareIcon />
|
|
677
|
+
</div>
|
|
678
|
+
<div className="equal-to-json-result__diff__header__label">
|
|
679
|
+
actual
|
|
680
|
+
</div>
|
|
681
|
+
</div>
|
|
682
|
+
</ModalHeader>
|
|
683
|
+
<ModalBody>
|
|
684
|
+
<JSONDiffView from={expected} to={actual} lossless={false} />
|
|
685
|
+
</ModalBody>
|
|
686
|
+
<ModalFooter>
|
|
687
|
+
<ModalFooterButton
|
|
688
|
+
text="Close"
|
|
689
|
+
onClick={close}
|
|
690
|
+
type="secondary"
|
|
691
|
+
/>
|
|
692
|
+
</ModalFooter>
|
|
693
|
+
</Modal>
|
|
694
|
+
</Dialog>
|
|
695
|
+
)}
|
|
696
|
+
</>
|
|
697
|
+
);
|
|
698
|
+
},
|
|
699
|
+
);
|
|
700
|
+
|
|
578
701
|
const AssertFailViewer = observer(
|
|
579
702
|
(props: { assertFailState: AssertFailState }) => {
|
|
580
703
|
const { assertFailState } = props;
|
|
@@ -606,6 +729,10 @@ const AssertFailViewer = observer(
|
|
|
606
729
|
<EqualToJsonAssertFailViewer
|
|
607
730
|
equalToJsonAssertFailState={assertFailState}
|
|
608
731
|
/>
|
|
732
|
+
) : assertFailState instanceof EqualToRelationAssertFailState ? (
|
|
733
|
+
<EqualToRelationAssertFailViewer
|
|
734
|
+
equalToRelationAssertFailState={assertFailState}
|
|
735
|
+
/>
|
|
609
736
|
) : assertFailState instanceof EqualToAssertFailState ? (
|
|
610
737
|
<EqualToAssertFailViewer equalToAssertFailState={assertFailState} />
|
|
611
738
|
) : isGenericEqualToFail ? (
|
|
@@ -849,6 +976,8 @@ export const TestAssertionEditor = observer(
|
|
|
849
976
|
const { testAssertionState } = props;
|
|
850
977
|
const selectedTab = testAssertionState.selectedTab;
|
|
851
978
|
const isReadOnly = testAssertionState.testState.isReadOnly;
|
|
979
|
+
const isDataProductTest =
|
|
980
|
+
testAssertionState.testState.testable instanceof DataProduct;
|
|
852
981
|
const isDisabled =
|
|
853
982
|
isReadOnly ||
|
|
854
983
|
!testAssertionState.assertionState.supportsGeneratingAssertion ||
|
|
@@ -870,6 +999,20 @@ export const TestAssertionEditor = observer(
|
|
|
870
999
|
testAssertionEditorState={testAssertionState}
|
|
871
1000
|
/>
|
|
872
1001
|
);
|
|
1002
|
+
} else if (state instanceof EqualToRelationAssertionState) {
|
|
1003
|
+
if (isDataProductTest) {
|
|
1004
|
+
return (
|
|
1005
|
+
<DataProductEqualToRelationAssertionEditor
|
|
1006
|
+
testAssertionEditorState={testAssertionState}
|
|
1007
|
+
/>
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
return (
|
|
1011
|
+
<EqualToRelationAsssertionEditor
|
|
1012
|
+
equalToRelationAssertionState={state}
|
|
1013
|
+
testAssertionEditorState={testAssertionState}
|
|
1014
|
+
/>
|
|
1015
|
+
);
|
|
873
1016
|
}
|
|
874
1017
|
return (
|
|
875
1018
|
<UnsupportedEditorPanel
|
|
@@ -901,22 +1044,24 @@ export const TestAssertionEditor = observer(
|
|
|
901
1044
|
</div>
|
|
902
1045
|
))}
|
|
903
1046
|
</div>
|
|
904
|
-
|
|
905
|
-
<
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
<
|
|
914
|
-
|
|
915
|
-
|
|
1047
|
+
{!isDataProductTest && (
|
|
1048
|
+
<div className="testable-test-assertion-editor__header__actions">
|
|
1049
|
+
<button
|
|
1050
|
+
className="panel__header__action service-execution-editor__test-data__generate-btn"
|
|
1051
|
+
onClick={generate}
|
|
1052
|
+
title="Generate expected result if possible"
|
|
1053
|
+
disabled={isDisabled}
|
|
1054
|
+
tabIndex={-1}
|
|
1055
|
+
>
|
|
1056
|
+
<div className="service-execution-editor__test-data__generate-btn__label">
|
|
1057
|
+
<RefreshIcon className="service-execution-editor__test-data__generate-btn__label__icon" />
|
|
1058
|
+
<div className="service-execution-editor__test-data__generate-btn__label__title">
|
|
1059
|
+
Generate
|
|
1060
|
+
</div>
|
|
916
1061
|
</div>
|
|
917
|
-
</
|
|
918
|
-
</
|
|
919
|
-
|
|
1062
|
+
</button>
|
|
1063
|
+
</div>
|
|
1064
|
+
)}
|
|
920
1065
|
</div>
|
|
921
1066
|
<div className="testable-test-assertion-editor__content">
|
|
922
1067
|
{selectedTab === TEST_ASSERTION_TAB.EXPECTED && (
|
|
@@ -46,9 +46,13 @@ import {
|
|
|
46
46
|
TrashIcon,
|
|
47
47
|
PlusIcon,
|
|
48
48
|
CogIcon,
|
|
49
|
+
InfoCircleIcon,
|
|
50
|
+
CompareIcon,
|
|
51
|
+
ChevronDownIcon,
|
|
52
|
+
ChevronRightIcon,
|
|
49
53
|
} from '@finos/legend-art';
|
|
50
54
|
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
|
|
51
|
-
import { CodeEditor } from '@finos/legend-lego/code-editor';
|
|
55
|
+
import { CodeDiffView, CodeEditor } from '@finos/legend-lego/code-editor';
|
|
52
56
|
import {
|
|
53
57
|
type BuildLog,
|
|
54
58
|
type BuildPhaseActionState,
|
|
@@ -338,6 +342,103 @@ const getPhaseStatusIcon = (status: BuildPhaseStatus): ReactNode => {
|
|
|
338
342
|
}
|
|
339
343
|
};
|
|
340
344
|
|
|
345
|
+
const DevMetadataCompareModal = observer(() => {
|
|
346
|
+
const editorStore = useEditorStore();
|
|
347
|
+
const applicationStore = editorStore.applicationStore;
|
|
348
|
+
const devMetadataState = editorStore.devMetadataState;
|
|
349
|
+
const isOpen = devMetadataState.isCompareModalOpen;
|
|
350
|
+
const isLoading = devMetadataState.compareState.isInProgress;
|
|
351
|
+
|
|
352
|
+
if (!isOpen) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return (
|
|
357
|
+
<Dialog
|
|
358
|
+
open={isOpen}
|
|
359
|
+
onClose={() => devMetadataState.closeCompareModal()}
|
|
360
|
+
classes={{
|
|
361
|
+
root: 'editor-modal__root-container',
|
|
362
|
+
container: 'editor-modal__container',
|
|
363
|
+
paper: 'editor-modal__content',
|
|
364
|
+
}}
|
|
365
|
+
>
|
|
366
|
+
<Modal
|
|
367
|
+
darkMode={
|
|
368
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
|
369
|
+
}
|
|
370
|
+
className="editor-modal dev-metadata-compare-modal"
|
|
371
|
+
>
|
|
372
|
+
<ModalHeader>
|
|
373
|
+
<ModalTitle title="Compare Workspace with Dev Snapshot" />
|
|
374
|
+
</ModalHeader>
|
|
375
|
+
<ModalBody className="dev-metadata-compare-modal__body">
|
|
376
|
+
{isLoading && (
|
|
377
|
+
<div className="dev-metadata-compare-modal__loading">
|
|
378
|
+
<CircleNotchIcon className="dev-metadata-compare-modal__loading__spinner" />
|
|
379
|
+
<span>Loading diff…</span>
|
|
380
|
+
</div>
|
|
381
|
+
)}
|
|
382
|
+
{!isLoading && devMetadataState.snapshotNotAvailable && (
|
|
383
|
+
<div className="dev-metadata-compare-modal__empty">
|
|
384
|
+
<InfoCircleIcon />
|
|
385
|
+
<div>
|
|
386
|
+
<div className="dev-metadata-compare-modal__empty__title">
|
|
387
|
+
Dev snapshot not available
|
|
388
|
+
</div>
|
|
389
|
+
<div className="dev-metadata-compare-modal__empty__body">
|
|
390
|
+
No deployed metadata was found for this project at version{' '}
|
|
391
|
+
<code>1.0.0-SNAPSHOT</code>. Push to dev first to create a
|
|
392
|
+
snapshot to compare against.
|
|
393
|
+
</div>
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
)}
|
|
397
|
+
{!isLoading && !devMetadataState.snapshotNotAvailable && (
|
|
398
|
+
<div className="dev-metadata-compare-modal__diff">
|
|
399
|
+
<div className="dev-metadata-compare-modal__diff__legend">
|
|
400
|
+
<div className="dev-metadata-compare-modal__diff__legend__side dev-metadata-compare-modal__diff__legend__side--from">
|
|
401
|
+
<span className="dev-metadata-compare-modal__diff__legend__badge dev-metadata-compare-modal__diff__legend__badge--from">
|
|
402
|
+
Deployed
|
|
403
|
+
</span>
|
|
404
|
+
<span className="dev-metadata-compare-modal__diff__legend__label">
|
|
405
|
+
Dev Snapshot
|
|
406
|
+
</span>
|
|
407
|
+
<code className="dev-metadata-compare-modal__diff__legend__version">
|
|
408
|
+
1.0.0-SNAPSHOT
|
|
409
|
+
</code>
|
|
410
|
+
</div>
|
|
411
|
+
<div className="dev-metadata-compare-modal__diff__legend__side dev-metadata-compare-modal__diff__legend__side--to">
|
|
412
|
+
<span className="dev-metadata-compare-modal__diff__legend__badge dev-metadata-compare-modal__diff__legend__badge--to">
|
|
413
|
+
Local
|
|
414
|
+
</span>
|
|
415
|
+
<span className="dev-metadata-compare-modal__diff__legend__label">
|
|
416
|
+
Current Workspace
|
|
417
|
+
</span>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
<div className="dev-metadata-compare-modal__diff__view">
|
|
421
|
+
<CodeDiffView
|
|
422
|
+
language={CODE_EDITOR_LANGUAGE.PURE}
|
|
423
|
+
from={devMetadataState.snapshotCode ?? ''}
|
|
424
|
+
to={devMetadataState.currentWorkspaceCode ?? ''}
|
|
425
|
+
/>
|
|
426
|
+
</div>
|
|
427
|
+
</div>
|
|
428
|
+
)}
|
|
429
|
+
</ModalBody>
|
|
430
|
+
<ModalFooter>
|
|
431
|
+
<ModalFooterButton
|
|
432
|
+
text="Close"
|
|
433
|
+
onClick={() => devMetadataState.closeCompareModal()}
|
|
434
|
+
type="secondary"
|
|
435
|
+
/>
|
|
436
|
+
</ModalFooter>
|
|
437
|
+
</Modal>
|
|
438
|
+
</Dialog>
|
|
439
|
+
);
|
|
440
|
+
});
|
|
441
|
+
|
|
341
442
|
const PhaseLogsViewer = observer(
|
|
342
443
|
(props: { phase: BuildPhaseActionState; onClose: () => void }) => {
|
|
343
444
|
const { phase, onClose } = props;
|
|
@@ -356,6 +457,17 @@ const PhaseLogsViewer = observer(
|
|
|
356
457
|
|
|
357
458
|
const logs = phase.logs ? formatLogs(phase.logs) : 'No logs available';
|
|
358
459
|
|
|
460
|
+
const handleCopyLogs = (): void => {
|
|
461
|
+
applicationStore.clipboardService
|
|
462
|
+
.copyTextToClipboard(logs)
|
|
463
|
+
.then(() =>
|
|
464
|
+
applicationStore.notificationService.notifySuccess(
|
|
465
|
+
'Logs copied to clipboard',
|
|
466
|
+
),
|
|
467
|
+
)
|
|
468
|
+
.catch(applicationStore.alertUnhandledError);
|
|
469
|
+
};
|
|
470
|
+
|
|
359
471
|
return (
|
|
360
472
|
<Dialog
|
|
361
473
|
open={true}
|
|
@@ -386,6 +498,11 @@ const PhaseLogsViewer = observer(
|
|
|
386
498
|
/>
|
|
387
499
|
</ModalBody>
|
|
388
500
|
<ModalFooter>
|
|
501
|
+
<ModalFooterButton
|
|
502
|
+
text="Copy Logs"
|
|
503
|
+
onClick={handleCopyLogs}
|
|
504
|
+
type="secondary"
|
|
505
|
+
/>
|
|
389
506
|
<ModalFooterButton
|
|
390
507
|
text="Close"
|
|
391
508
|
onClick={onClose}
|
|
@@ -444,7 +561,13 @@ const DeploymentPhaseNode = observer(
|
|
|
444
561
|
}
|
|
445
562
|
menuProps={{ elevation: 7 }}
|
|
446
563
|
>
|
|
447
|
-
<div
|
|
564
|
+
<div
|
|
565
|
+
className={clsx('deployment-phase__node', {
|
|
566
|
+
'deployment-phase__node--clickable': hasLogs,
|
|
567
|
+
})}
|
|
568
|
+
onClick={hasLogs ? () => onViewLogs(phase) : undefined}
|
|
569
|
+
title={hasLogs ? 'Click to view logs' : undefined}
|
|
570
|
+
>
|
|
448
571
|
<div className="deployment-phase__node__icon">{statusIcon}</div>
|
|
449
572
|
<div className="deployment-phase__node__content">
|
|
450
573
|
<div className="deployment-phase__node__title">{phase.phase}</div>
|
|
@@ -578,6 +701,7 @@ export const DevMetadataPanel = observer(() => {
|
|
|
578
701
|
const editorStore = useEditorStore();
|
|
579
702
|
const devMetadataState = editorStore.devMetadataState;
|
|
580
703
|
const [isOptionsModalOpen, setIsOptionsModalOpen] = useState(false);
|
|
704
|
+
const [isInfoExpanded, setIsInfoExpanded] = useState(false);
|
|
581
705
|
|
|
582
706
|
const handlePush = (): void => {
|
|
583
707
|
flowResult(devMetadataState.push()).catch(
|
|
@@ -589,7 +713,15 @@ export const DevMetadataPanel = observer(() => {
|
|
|
589
713
|
devMetadataState.setOptions(newOptions);
|
|
590
714
|
};
|
|
591
715
|
|
|
716
|
+
const handleCompare = (): void => {
|
|
717
|
+
devMetadataState.openCompareModal();
|
|
718
|
+
flowResult(devMetadataState.compareWithSnapshot()).catch(
|
|
719
|
+
editorStore.applicationStore.alertUnhandledError,
|
|
720
|
+
);
|
|
721
|
+
};
|
|
722
|
+
|
|
592
723
|
const isPushing = devMetadataState.pushState.isInProgress;
|
|
724
|
+
const isComparing = devMetadataState.compareState.isInProgress;
|
|
593
725
|
|
|
594
726
|
return (
|
|
595
727
|
<Panel>
|
|
@@ -628,6 +760,46 @@ export const DevMetadataPanel = observer(() => {
|
|
|
628
760
|
</PanelFormSection>
|
|
629
761
|
|
|
630
762
|
<PanelDivider />
|
|
763
|
+
<PanelFormSection>
|
|
764
|
+
<div
|
|
765
|
+
className={clsx('dev-metadata-panel__info-callout', {
|
|
766
|
+
'dev-metadata-panel__info-callout--collapsed': !isInfoExpanded,
|
|
767
|
+
})}
|
|
768
|
+
>
|
|
769
|
+
<button
|
|
770
|
+
type="button"
|
|
771
|
+
className="dev-metadata-panel__info-callout__header"
|
|
772
|
+
onClick={() => setIsInfoExpanded(!isInfoExpanded)}
|
|
773
|
+
title={isInfoExpanded ? 'Hide details' : 'Show details'}
|
|
774
|
+
>
|
|
775
|
+
<span className="dev-metadata-panel__info-callout__header__chevron">
|
|
776
|
+
{isInfoExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}
|
|
777
|
+
</span>
|
|
778
|
+
<InfoCircleIcon />
|
|
779
|
+
<span className="dev-metadata-panel__info-callout__header__title">
|
|
780
|
+
Heads up — you're using Dev Mode
|
|
781
|
+
</span>
|
|
782
|
+
</button>
|
|
783
|
+
{isInfoExpanded && (
|
|
784
|
+
<div className="dev-metadata-panel__info-callout__content">
|
|
785
|
+
<div className="dev-metadata-panel__info-callout__body">
|
|
786
|
+
This pushes your current workspace straight to your dev branch
|
|
787
|
+
(
|
|
788
|
+
<code className="dev-metadata-panel__info-callout__code">
|
|
789
|
+
1.0.0-SNAPSHOT
|
|
790
|
+
</code>
|
|
791
|
+
), bypassing the GitLab build pipeline so you can iterate and
|
|
792
|
+
test changes faster.
|
|
793
|
+
</div>
|
|
794
|
+
<div className="dev-metadata-panel__info-callout__body">
|
|
795
|
+
Any Lakehouse elements in your workspace — including ingests,
|
|
796
|
+
materialized views, and data products — will be deployed by
|
|
797
|
+
default.
|
|
798
|
+
</div>
|
|
799
|
+
</div>
|
|
800
|
+
)}
|
|
801
|
+
</div>
|
|
802
|
+
</PanelFormSection>
|
|
631
803
|
<PanelFormSection>
|
|
632
804
|
<div className="dev-metadata-panel__push-section">
|
|
633
805
|
<div className="dev-metadata-panel__push-header">
|
|
@@ -635,14 +807,25 @@ export const DevMetadataPanel = observer(() => {
|
|
|
635
807
|
<div className="panel__content__form__section__header__label">
|
|
636
808
|
Deploy Metadata
|
|
637
809
|
</div>
|
|
638
|
-
<
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
810
|
+
<div className="dev-metadata-panel__push-title-row__actions">
|
|
811
|
+
<button
|
|
812
|
+
className="dev-metadata-panel__compare-btn"
|
|
813
|
+
onClick={handleCompare}
|
|
814
|
+
title="Compare current workspace with the deployed dev snapshot"
|
|
815
|
+
disabled={isPushing || isComparing}
|
|
816
|
+
>
|
|
817
|
+
<CompareIcon />
|
|
818
|
+
<span>Compare with Dev</span>
|
|
819
|
+
</button>
|
|
820
|
+
<button
|
|
821
|
+
className="dev-metadata-panel__settings-btn"
|
|
822
|
+
onClick={() => setIsOptionsModalOpen(true)}
|
|
823
|
+
title="Configure deployment options"
|
|
824
|
+
disabled={isPushing}
|
|
825
|
+
>
|
|
826
|
+
<CogIcon />
|
|
827
|
+
</button>
|
|
828
|
+
</div>
|
|
646
829
|
</div>
|
|
647
830
|
<div className="dev-metadata-panel__push-description">
|
|
648
831
|
{isPushing
|
|
@@ -702,6 +885,7 @@ export const DevMetadataPanel = observer(() => {
|
|
|
702
885
|
options={devMetadataState.options}
|
|
703
886
|
onSave={handleSaveOptions}
|
|
704
887
|
/>
|
|
888
|
+
<DevMetadataCompareModal />
|
|
705
889
|
</PanelContent>
|
|
706
890
|
</Panel>
|
|
707
891
|
);
|