@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.
Files changed (26) hide show
  1. package/lib/application/LegendStudioApplicationConfig.d.ts +1 -29
  2. package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
  3. package/lib/application/LegendStudioApplicationConfig.js +1 -39
  4. package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
  5. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
  6. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +30 -7
  7. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
  8. package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.d.ts.map +1 -1
  9. package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js +5 -4
  10. package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js.map +1 -1
  11. package/lib/index.css +1 -1
  12. package/lib/package.json +1 -1
  13. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +4 -1
  14. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
  15. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +29 -1
  16. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
  17. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts +4 -1
  18. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts.map +1 -1
  19. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js +27 -1
  20. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
  21. package/package.json +14 -14
  22. package/src/application/LegendStudioApplicationConfig.ts +2 -50
  23. package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +75 -14
  24. package/src/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.tsx +12 -1
  25. package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +49 -1
  26. 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 && (
@@ -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 {
@@ -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 {