@finos/legend-application-studio 28.19.41 → 28.19.43
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/application/LegendStudioApplicationConfig.d.ts +1 -29
- package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.js +1 -39
- package/lib/application/LegendStudioApplicationConfig.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 +30 -7
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js +5 -4
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.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 +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 +29 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts +4 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js +27 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
- package/package.json +14 -14
- package/src/application/LegendStudioApplicationConfig.ts +2 -50
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +75 -14
- package/src/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.tsx +12 -1
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +49 -1
- package/src/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.ts +41 -0
@@ -77,6 +77,8 @@ import {
|
|
77
77
|
WarningIcon,
|
78
78
|
LongArrowRightIcon,
|
79
79
|
PURE_MappingIcon,
|
80
|
+
GitBranchIcon,
|
81
|
+
ListIcon,
|
80
82
|
} from '@finos/legend-art';
|
81
83
|
import {
|
82
84
|
type ChangeEventHandler,
|
@@ -86,7 +88,7 @@ import {
|
|
86
88
|
useState,
|
87
89
|
} from 'react';
|
88
90
|
import { filterByType } from '@finos/legend-shared';
|
89
|
-
import { InlineLambdaEditor } from '@finos/legend-query-builder';
|
91
|
+
import { InlineLambdaEditor, LineageViewer } from '@finos/legend-query-builder';
|
90
92
|
import { action, flowResult } from 'mobx';
|
91
93
|
import { useAuth } from 'react-oidc-context';
|
92
94
|
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
|
@@ -569,7 +571,9 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
569
571
|
dragConnector(ref);
|
570
572
|
dropConnector(ref);
|
571
573
|
useDragPreviewLayer(dragPreviewConnector);
|
572
|
-
|
574
|
+
const generateLineage = editorStore.applicationStore.guardUnhandledError(
|
575
|
+
() => flowResult(accessPointState.generateLineage()),
|
576
|
+
);
|
573
577
|
return (
|
574
578
|
<PanelDnDEntry
|
575
579
|
ref={ref}
|
@@ -671,6 +675,74 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
671
675
|
<CaretDownIcon />
|
672
676
|
</ControlledDropdownMenu>
|
673
677
|
</div>
|
678
|
+
<ControlledDropdownMenu
|
679
|
+
className="access-point-editor__dropdown"
|
680
|
+
content={
|
681
|
+
<MenuContent>
|
682
|
+
<MenuContentItem
|
683
|
+
className="btn__dropdown-combo__option"
|
684
|
+
onClick={() => {
|
685
|
+
debugPlanGeneration().catch(
|
686
|
+
editorStore.applicationStore.alertUnhandledError,
|
687
|
+
);
|
688
|
+
}}
|
689
|
+
>
|
690
|
+
<div
|
691
|
+
style={{
|
692
|
+
display: 'flex',
|
693
|
+
gap: '0.5rem',
|
694
|
+
alignItems: 'center',
|
695
|
+
}}
|
696
|
+
>
|
697
|
+
<BugIcon /> <span>AP Plan Generation</span>
|
698
|
+
</div>
|
699
|
+
</MenuContentItem>
|
700
|
+
<MenuContentItem
|
701
|
+
className="btn__dropdown-combo__option"
|
702
|
+
onClick={generateLineage}
|
703
|
+
>
|
704
|
+
<div
|
705
|
+
style={{
|
706
|
+
display: 'flex',
|
707
|
+
gap: '0.5rem',
|
708
|
+
alignItems: 'center',
|
709
|
+
}}
|
710
|
+
>
|
711
|
+
<span
|
712
|
+
style={{
|
713
|
+
display: 'flex',
|
714
|
+
alignItems: 'center',
|
715
|
+
transform: 'rotate(90deg)',
|
716
|
+
}}
|
717
|
+
>
|
718
|
+
<GitBranchIcon />
|
719
|
+
</span>
|
720
|
+
<span>Lineage Viewer</span>
|
721
|
+
</div>
|
722
|
+
</MenuContentItem>
|
723
|
+
</MenuContent>
|
724
|
+
}
|
725
|
+
menuProps={{
|
726
|
+
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
727
|
+
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
728
|
+
}}
|
729
|
+
>
|
730
|
+
<div
|
731
|
+
className="access-point-editor__generic-entry__remove-btn__debug"
|
732
|
+
tabIndex={-1}
|
733
|
+
title="Access Point Tools"
|
734
|
+
style={{
|
735
|
+
background: 'var(--color-blue-200)',
|
736
|
+
borderRadius: '4px',
|
737
|
+
marginRight: '0.5rem',
|
738
|
+
padding: '0.25rem 0.5rem',
|
739
|
+
display: 'flex',
|
740
|
+
alignItems: 'center',
|
741
|
+
}}
|
742
|
+
>
|
743
|
+
<ListIcon />
|
744
|
+
</div>
|
745
|
+
</ControlledDropdownMenu>
|
674
746
|
</div>
|
675
747
|
</div>
|
676
748
|
{editingDescription ? (
|
@@ -729,20 +801,9 @@ export const LakehouseDataProductAccessPointEditor = observer(
|
|
729
801
|
/>
|
730
802
|
</div>
|
731
803
|
</div>
|
732
|
-
<button
|
733
|
-
className="access-point-editor__generic-entry__remove-btn__debug"
|
734
|
-
onClick={() => {
|
735
|
-
debugPlanGeneration().catch(
|
736
|
-
editorStore.applicationStore.alertUnhandledError,
|
737
|
-
);
|
738
|
-
}}
|
739
|
-
tabIndex={-1}
|
740
|
-
title="AP Plan Generation"
|
741
|
-
>
|
742
|
-
<BugIcon />
|
743
|
-
</button>
|
744
804
|
</div>
|
745
805
|
</div>
|
806
|
+
{<LineageViewer lineageState={accessPointState.lineageState} />}
|
746
807
|
</div>
|
747
808
|
<button
|
748
809
|
className="access-point-editor__generic-entry__remove-btn"
|
@@ -14,7 +14,7 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import { useEffect } from 'react';
|
17
|
+
import React, { useEffect } from 'react';
|
18
18
|
import { observer } from 'mobx-react-lite';
|
19
19
|
import { ServicePureExecutionState } from '../../../../stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js';
|
20
20
|
import {
|
@@ -55,6 +55,7 @@ import {
|
|
55
55
|
ExecutionPlanViewer,
|
56
56
|
QueryBuilderAdvancedWorkflowState,
|
57
57
|
QueryBuilderActionConfig,
|
58
|
+
LineageViewer,
|
58
59
|
} from '@finos/legend-query-builder';
|
59
60
|
import { ProjectViewerEditorMode } from '../../../../stores/project-view/ProjectViewerEditorMode.js';
|
60
61
|
import { useLegendStudioApplicationStore } from '../../../LegendStudioFrameworkProvider.js';
|
@@ -231,6 +232,9 @@ export const ServiceExecutionQueryEditor = observer(
|
|
231
232
|
flowResult(executionState.generatePlan(false)),
|
232
233
|
);
|
233
234
|
|
235
|
+
const generateLineage = applicationStore.guardUnhandledError(() =>
|
236
|
+
flowResult(executionState.generateLineage()),
|
237
|
+
);
|
234
238
|
const debugPlanGeneration = applicationStore.guardUnhandledError(() =>
|
235
239
|
flowResult(executionState.generatePlan(true)),
|
236
240
|
);
|
@@ -379,6 +383,12 @@ export const ServiceExecutionQueryEditor = observer(
|
|
379
383
|
>
|
380
384
|
Generate Plan
|
381
385
|
</MenuContentItem>
|
386
|
+
<MenuContentItem
|
387
|
+
className="btn__dropdown-combo__option"
|
388
|
+
onClick={generateLineage}
|
389
|
+
>
|
390
|
+
View Lineage
|
391
|
+
</MenuContentItem>
|
382
392
|
<MenuContentItem
|
383
393
|
className="btn__dropdown-combo__option"
|
384
394
|
onClick={debugPlanGeneration}
|
@@ -468,6 +478,7 @@ export const ServiceExecutionQueryEditor = observer(
|
|
468
478
|
<ExecutionPlanViewer
|
469
479
|
executionPlanState={executionState.executionPlanState}
|
470
480
|
/>
|
481
|
+
<LineageViewer lineageState={executionState.lineageState} />
|
471
482
|
<ServiceExecutionResultViewer executionState={executionState} />
|
472
483
|
{executionState.parametersState.parameterValuesEditorState
|
473
484
|
.showModal && (
|
package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts
CHANGED
@@ -46,6 +46,7 @@ import {
|
|
46
46
|
observe_DataProductElementScope,
|
47
47
|
DataProductElementScope,
|
48
48
|
validate_PureExecutionMapping,
|
49
|
+
type V1_RawLineageModel,
|
49
50
|
} from '@finos/legend-graph';
|
50
51
|
import type { EditorStore } from '../../../EditorStore.js';
|
51
52
|
import { ElementEditorState } from '../ElementEditorState.js';
|
@@ -88,7 +89,7 @@ import {
|
|
88
89
|
modelAccessPointGroup_setElementExclude,
|
89
90
|
modelAccessPointGroup_setMapping,
|
90
91
|
} from '../../../../graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
|
91
|
-
import { LambdaEditorState } from '@finos/legend-query-builder';
|
92
|
+
import { LambdaEditorState, LineageState } from '@finos/legend-query-builder';
|
92
93
|
import {
|
93
94
|
DataProductElementEditorInitialConfiguration,
|
94
95
|
EditorInitialConfiguration,
|
@@ -238,20 +239,67 @@ export class LakehouseAccessPointState extends AccessPointState {
|
|
238
239
|
|
239
240
|
showDebug = false;
|
240
241
|
|
242
|
+
// Add lineage state and isGeneratingLineage
|
243
|
+
lineageState: LineageState;
|
244
|
+
isGeneratingLineage = false;
|
245
|
+
|
241
246
|
constructor(val: LakehouseAccessPoint, editorState: AccessPointGroupState) {
|
242
247
|
super(val, editorState);
|
243
248
|
makeObservable(this, {
|
244
249
|
lambdaState: observable,
|
245
250
|
showDebug: observable,
|
246
251
|
setShowDebug: action,
|
252
|
+
// Add observables for lineage
|
253
|
+
lineageState: observable,
|
254
|
+
isGeneratingLineage: observable,
|
255
|
+
generateLineage: flow,
|
247
256
|
});
|
248
257
|
this.accessPoint = val;
|
249
258
|
this.lambdaState = new AccessPointLambdaEditorState(this);
|
259
|
+
this.lineageState = new LineageState(
|
260
|
+
this.state.state.editorStore.applicationStore,
|
261
|
+
);
|
250
262
|
}
|
251
263
|
|
252
264
|
setShowDebug(value: boolean): void {
|
253
265
|
this.showDebug = value;
|
254
266
|
}
|
267
|
+
|
268
|
+
*generateLineage(): GeneratorFn<void> {
|
269
|
+
if (this.isGeneratingLineage) {
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
try {
|
273
|
+
this.isGeneratingLineage = true;
|
274
|
+
const lambda = this.accessPoint.func;
|
275
|
+
const lineageRawData =
|
276
|
+
(yield this.state.state.editorStore.graphManagerState.graphManager.generateLineage(
|
277
|
+
lambda,
|
278
|
+
undefined,
|
279
|
+
undefined,
|
280
|
+
this.state.state.editorStore.graphManagerState.graph,
|
281
|
+
undefined,
|
282
|
+
)) as V1_RawLineageModel;
|
283
|
+
|
284
|
+
const lineageData =
|
285
|
+
this.state.state.editorStore.graphManagerState.graphManager.buildLineage(
|
286
|
+
lineageRawData,
|
287
|
+
);
|
288
|
+
|
289
|
+
this.lineageState.setLineageData(lineageData);
|
290
|
+
} catch (error) {
|
291
|
+
assertErrorThrown(error);
|
292
|
+
this.state.state.editorStore.applicationStore.logService.error(
|
293
|
+
LogEvent.create(GRAPH_MANAGER_EVENT.LINEAGE_GENERATION_FAILURE),
|
294
|
+
error,
|
295
|
+
);
|
296
|
+
this.state.state.editorStore.applicationStore.notificationService.notifyError(
|
297
|
+
error,
|
298
|
+
);
|
299
|
+
} finally {
|
300
|
+
this.isGeneratingLineage = false;
|
301
|
+
}
|
302
|
+
}
|
255
303
|
}
|
256
304
|
|
257
305
|
export class AccessPointGroupState {
|
package/src/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.ts
CHANGED
@@ -59,6 +59,7 @@ import {
|
|
59
59
|
stub_Mapping,
|
60
60
|
reportGraphAnalytics,
|
61
61
|
QuerySearchSpecification,
|
62
|
+
type V1_RawLineageModel,
|
62
63
|
} from '@finos/legend-graph';
|
63
64
|
import { parseGACoordinates } from '@finos/legend-storage';
|
64
65
|
import { runtime_addMapping } from '../../../../graph-modifier/DSL_Mapping_GraphModifierHelper.js';
|
@@ -86,6 +87,7 @@ import {
|
|
86
87
|
ExecutionPlanState,
|
87
88
|
QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT,
|
88
89
|
getRawLambdaForLetFuncs,
|
90
|
+
LineageState,
|
89
91
|
} from '@finos/legend-query-builder';
|
90
92
|
import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
|
91
93
|
import { openDataCube } from '../../../data-cube/LegendStudioDataCubeHelper.js';
|
@@ -457,10 +459,12 @@ export abstract class ServicePureExecutionState extends ServiceExecutionState {
|
|
457
459
|
showChangeExecModal = false;
|
458
460
|
isRunningQuery = false;
|
459
461
|
isGeneratingPlan = false;
|
462
|
+
isGeneratingLineage = false;
|
460
463
|
executionResultText?: string | undefined; // NOTE: stored as lossless JSON string
|
461
464
|
executionPlanState: ExecutionPlanState;
|
462
465
|
readonly parametersState: ServiceExecutionParametersState;
|
463
466
|
queryRunPromise: Promise<ExecutionResultWithMetadata> | undefined = undefined;
|
467
|
+
lineageState: LineageState;
|
464
468
|
|
465
469
|
constructor(
|
466
470
|
editorStore: EditorStore,
|
@@ -470,6 +474,8 @@ export abstract class ServicePureExecutionState extends ServiceExecutionState {
|
|
470
474
|
super(editorStore, serviceEditorState, execution);
|
471
475
|
makeObservable(this, {
|
472
476
|
cancelQuery: flow,
|
477
|
+
generateLineage: flow,
|
478
|
+
isGeneratingLineage: observable,
|
473
479
|
});
|
474
480
|
|
475
481
|
this.execution = execution;
|
@@ -482,6 +488,7 @@ export abstract class ServicePureExecutionState extends ServiceExecutionState {
|
|
482
488
|
this.editorStore.graphManagerState,
|
483
489
|
);
|
484
490
|
this.parametersState = new ServiceExecutionParametersState(this);
|
491
|
+
this.lineageState = new LineageState(this.editorStore.applicationStore);
|
485
492
|
}
|
486
493
|
|
487
494
|
abstract changeExecution(): void;
|
@@ -737,6 +744,40 @@ export abstract class ServicePureExecutionState extends ServiceExecutionState {
|
|
737
744
|
}
|
738
745
|
}
|
739
746
|
|
747
|
+
*generateLineage(): GeneratorFn<void> {
|
748
|
+
if (this.isGeneratingLineage) {
|
749
|
+
return;
|
750
|
+
}
|
751
|
+
try {
|
752
|
+
this.isGeneratingLineage = true;
|
753
|
+
const query = this.queryState.query;
|
754
|
+
const mapping =
|
755
|
+
this.selectedExecutionContextState?.executionContext.mapping.value;
|
756
|
+
const lineageRawData =
|
757
|
+
(yield this.editorStore.graphManagerState.graphManager.generateLineage(
|
758
|
+
query,
|
759
|
+
mapping,
|
760
|
+
undefined,
|
761
|
+
this.editorStore.graphManagerState.graph,
|
762
|
+
undefined,
|
763
|
+
)) as V1_RawLineageModel;
|
764
|
+
const lineageData =
|
765
|
+
this.editorStore.graphManagerState.graphManager.buildLineage(
|
766
|
+
lineageRawData,
|
767
|
+
);
|
768
|
+
this.lineageState.setLineageData(lineageData);
|
769
|
+
} catch (error) {
|
770
|
+
assertErrorThrown(error);
|
771
|
+
this.editorStore.applicationStore.logService.error(
|
772
|
+
LogEvent.create(GRAPH_MANAGER_EVENT.LINEAGE_GENERATION_FAILURE),
|
773
|
+
error,
|
774
|
+
);
|
775
|
+
this.editorStore.applicationStore.notificationService.notifyError(error);
|
776
|
+
} finally {
|
777
|
+
this.isGeneratingLineage = false;
|
778
|
+
}
|
779
|
+
}
|
780
|
+
|
740
781
|
get serviceExecutionParameters():
|
741
782
|
| { query: RawLambda; mapping: Mapping; runtime: Runtime }
|
742
783
|
| undefined {
|