@finos/legend-query-builder 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderResultPanel.js +6 -7
  3. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  4. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  5. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +19 -17
  6. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +31 -29
  9. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  10. package/lib/index.css +2 -2
  11. package/lib/index.css.map +1 -1
  12. package/lib/package.json +2 -2
  13. package/lib/stores/QueryBuilderResultState.d.ts +7 -3
  14. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  15. package/lib/stores/QueryBuilderResultState.js +14 -20
  16. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  17. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts +3 -0
  18. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts.map +1 -1
  19. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  20. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +10 -1
  21. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  22. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +36 -1
  23. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  24. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +6 -0
  25. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  26. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +21 -2
  27. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  28. package/package.json +9 -9
  29. package/src/components/QueryBuilderResultPanel.tsx +18 -20
  30. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +128 -126
  31. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +254 -251
  32. package/src/stores/QueryBuilderResultState.ts +28 -33
  33. package/src/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.ts +5 -0
  34. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +44 -0
  35. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +28 -0
@@ -29,7 +29,6 @@ import {
29
29
  clsx,
30
30
  PanelEntryDropZonePlaceholder,
31
31
  ContextMenu,
32
- VerticalDragHandleIcon,
33
32
  TimesIcon,
34
33
  useDragPreviewLayer,
35
34
  SortIcon,
@@ -43,6 +42,8 @@ import {
43
42
  ModalFooter,
44
43
  PanelFormSection,
45
44
  ModalFooterButton,
45
+ PanelDnDEntryDragHandle,
46
+ PanelDnDEntry,
46
47
  } from '@finos/legend-art';
47
48
  import { assertErrorThrown, guaranteeNonNullable } from '@finos/legend-shared';
48
49
  import { observer } from 'mobx-react-lite';
@@ -669,6 +670,8 @@ const QueryBuilderWindowColumnEditor = observer(
669
670
  const operators = windowState.operators;
670
671
  // state
671
672
  const ref = useRef<HTMLDivElement>(null);
673
+ const handleRef = useRef<HTMLDivElement>(null);
674
+
672
675
  const [windowAnchor, setWindowAnchor] = useState<HTMLButtonElement | null>(
673
676
  null,
674
677
  );
@@ -796,7 +799,8 @@ const QueryBuilderWindowColumnEditor = observer(
796
799
  [windowColumnState],
797
800
  );
798
801
  const isBeingDragged = windowColumnState === olapColumnBeingDragged;
799
- dragConnector(dropConnector(ref));
802
+ dragConnector(handleRef);
803
+ dropConnector(ref);
800
804
  useDragPreviewLayer(dragPreviewConnector);
801
805
 
802
806
  const handleOpDrop = (val: QueryBuilderTDSColumnState): void => {
@@ -846,273 +850,272 @@ const QueryBuilderWindowColumnEditor = observer(
846
850
  );
847
851
 
848
852
  return (
849
- <div ref={ref} className="query-builder__olap__column">
850
- <PanelEntryDropZonePlaceholder
851
- showPlaceholder={isBeingDragged}
852
- className="query-builder__dnd__placeholder"
853
+ <PanelDnDEntry
854
+ ref={ref}
855
+ className="query-builder__olap__column"
856
+ showPlaceholder={isBeingDragged}
857
+ >
858
+ <ContextMenu
859
+ content={
860
+ <QueryBuilderWindowColumnContextMenu
861
+ columnState={windowColumnState}
862
+ />
863
+ }
864
+ className={clsx('query-builder__olap__column__context-menu', {
865
+ 'query-builder__olap__column--selected-from-context-menu':
866
+ isSelectedFromContextMenu,
867
+ })}
868
+ menuProps={{ elevation: 7 }}
869
+ onOpen={onContextMenuOpen}
870
+ onClose={onContextMenuClose}
853
871
  >
854
- <ContextMenu
855
- content={
856
- <QueryBuilderWindowColumnContextMenu
857
- columnState={windowColumnState}
858
- />
859
- }
860
- className={clsx('query-builder__olap__column__context-menu', {
861
- 'query-builder__olap__column--selected-from-context-menu':
862
- isSelectedFromContextMenu,
863
- })}
864
- menuProps={{ elevation: 7 }}
865
- onOpen={onContextMenuOpen}
866
- onClose={onContextMenuClose}
867
- >
868
- <div className="query-builder__olap__column__drag-handle__container">
869
- <div className="query-builder__olap__column__drag-handle">
870
- <VerticalDragHandleIcon />
872
+ <PanelDnDEntryDragHandle
873
+ isBeingDragged={isBeingDragged}
874
+ className="query-builder__olap__column__drag-handle__container"
875
+ dropTargetConnector={handleRef}
876
+ />
877
+ <div className="query-builder__olap__column__operation">
878
+ <div className="query-builder__olap__column__operation__operator">
879
+ <div
880
+ className={clsx(
881
+ 'query-builder__olap__column__operation__operator__label',
882
+ {
883
+ 'query-builder__olap__column__operation__operator__label__agg':
884
+ !aggregateColumn,
885
+ },
886
+ )}
887
+ >
888
+ {operationState.operator.getLabel()}
871
889
  </div>
890
+ {aggregateColumn && (
891
+ <TDSColumnReferenceEditor
892
+ tdsColumn={aggregateColumn}
893
+ handleChange={handleOpDrop}
894
+ selectionEditor={{
895
+ options: windowColumnState.possibleReferencedColumns,
896
+ }}
897
+ />
898
+ )}
899
+ <DropdownMenu
900
+ className="query-builder__olap__column__operation__operator__dropdown"
901
+ disabled={!operators.length}
902
+ content={
903
+ <MenuContent>
904
+ {operators.map((op) => (
905
+ <MenuContentItem
906
+ key={op.uuid}
907
+ className="query-builder__olap__column__operation__operator__dropdown__option"
908
+ onClick={changeOperator(op)}
909
+ >
910
+ {op.getLabel()}
911
+ </MenuContentItem>
912
+ ))}
913
+ </MenuContent>
914
+ }
915
+ menuProps={{
916
+ anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
917
+ transformOrigin: { vertical: 'top', horizontal: 'left' },
918
+ elevation: 7,
919
+ }}
920
+ >
921
+ <button
922
+ className="query-builder__olap__column__operation__operator__badge"
923
+ tabIndex={-1}
924
+ title="Choose Window Function Operator..."
925
+ >
926
+ <SigmaIcon />
927
+ </button>
928
+ <button
929
+ className="query-builder__olap__column__operation__operator__dropdown__trigger"
930
+ tabIndex={-1}
931
+ title="Choose Window Function Operator..."
932
+ >
933
+ <CaretDownIcon />
934
+ </button>
935
+ </DropdownMenu>
872
936
  </div>
873
- <div className="query-builder__olap__column__operation">
874
- <div className="query-builder__olap__column__operation__operator">
937
+ </div>
938
+ <div className="query-builder__olap__column__window">
939
+ <button
940
+ ref={dropOpConnector}
941
+ title="Click to edit or drag and drop columns"
942
+ onClick={openWindowPopover}
943
+ className="query-builder__olap__column__window__content"
944
+ >
945
+ <PanelEntryDropZonePlaceholder
946
+ showPlaceholder={isDragOver}
947
+ label="Add"
948
+ className="query-builder__dnd__placeholder"
949
+ >
950
+ <div
951
+ title={`${windowColumnState.windowColumns.length} columns partitioned`}
952
+ className="query-builder__olap__column__window__content__label"
953
+ >
954
+ ({windowColumnState.windowColumns.length})
955
+ </div>
875
956
  <div
876
957
  className={clsx(
877
- 'query-builder__olap__column__operation__operator__label',
878
- {
879
- 'query-builder__olap__column__operation__operator__label__agg':
880
- !aggregateColumn,
881
- },
958
+ 'query-builder__olap__column__window__operator__badge',
882
959
  )}
960
+ tabIndex={-1}
961
+ title="Edit window columns..."
883
962
  >
884
- {operationState.operator.getLabel()}
963
+ <WindowIcon />
885
964
  </div>
886
- {aggregateColumn && (
887
- <TDSColumnReferenceEditor
888
- tdsColumn={aggregateColumn}
889
- handleChange={handleOpDrop}
890
- selectionEditor={{
891
- options: windowColumnState.possibleReferencedColumns,
892
- }}
893
- />
894
- )}
895
- <DropdownMenu
896
- className="query-builder__olap__column__operation__operator__dropdown"
897
- disabled={!operators.length}
898
- content={
899
- <MenuContent>
900
- {operators.map((op) => (
901
- <MenuContentItem
902
- key={op.uuid}
903
- className="query-builder__olap__column__operation__operator__dropdown__option"
904
- onClick={changeOperator(op)}
905
- >
906
- {op.getLabel()}
907
- </MenuContentItem>
908
- ))}
909
- </MenuContent>
910
- }
911
- menuProps={{
912
- anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
913
- transformOrigin: { vertical: 'top', horizontal: 'left' },
914
- elevation: 7,
915
- }}
916
- >
917
- <button
918
- className="query-builder__olap__column__operation__operator__badge"
919
- tabIndex={-1}
920
- title="Choose Window Function Operator..."
921
- >
922
- <SigmaIcon />
923
- </button>
924
- <button
925
- className="query-builder__olap__column__operation__operator__dropdown__trigger"
926
- tabIndex={-1}
927
- title="Choose Window Function Operator..."
928
- >
929
- <CaretDownIcon />
930
- </button>
931
- </DropdownMenu>
932
- </div>
933
- </div>
934
- <div className="query-builder__olap__column__window">
935
- <button
936
- ref={dropOpConnector}
937
- title="Click to edit or drag and drop columns"
938
- onClick={openWindowPopover}
939
- className="query-builder__olap__column__window__content"
940
- >
941
- <PanelEntryDropZonePlaceholder
942
- showPlaceholder={isDragOver}
943
- label="Add"
944
- className="query-builder__dnd__placeholder"
945
- >
946
- <div
947
- title={`${windowColumnState.windowColumns.length} columns partitioned`}
948
- className="query-builder__olap__column__window__content__label"
949
- >
950
- ({windowColumnState.windowColumns.length})
951
- </div>
952
- <div
953
- className={clsx(
954
- 'query-builder__olap__column__window__operator__badge',
955
- )}
956
- tabIndex={-1}
957
- title="Edit window columns..."
958
- >
959
- <WindowIcon />
965
+ </PanelEntryDropZonePlaceholder>
966
+ </button>
967
+ <BasePopover
968
+ open={Boolean(windowAnchor)}
969
+ anchorEl={windowAnchor}
970
+ onClose={closeWindowPopover}
971
+ anchorOrigin={{
972
+ vertical: 'bottom',
973
+ horizontal: 'center',
974
+ }}
975
+ transformOrigin={{
976
+ vertical: 'top',
977
+ horizontal: 'center',
978
+ }}
979
+ >
980
+ <div className="query-builder__olap__column__window__popover">
981
+ <div className="panel__content__form__section__list">
982
+ <div className="panel__content__form__section__list__items">
983
+ {windowColumnState.windowColumns.map((value, idx) => (
984
+ <TDSColumnSelectorEditor
985
+ key={value.uuid}
986
+ colValue={value}
987
+ setColumn={(v: QueryBuilderTDSColumnState) =>
988
+ windowColumnState.changeWindow(v, idx)
989
+ }
990
+ deleteColumn={(v: QueryBuilderTDSColumnState): void =>
991
+ windowColumnState.deleteWindow(v)
992
+ }
993
+ tdsColOptions={windowOptions}
994
+ />
995
+ ))}
960
996
  </div>
961
- </PanelEntryDropZonePlaceholder>
962
- </button>
963
- <BasePopover
964
- open={Boolean(windowAnchor)}
965
- anchorEl={windowAnchor}
966
- onClose={closeWindowPopover}
967
- anchorOrigin={{
968
- vertical: 'bottom',
969
- horizontal: 'center',
970
- }}
971
- transformOrigin={{
972
- vertical: 'top',
973
- horizontal: 'center',
974
- }}
975
- >
976
- <div className="query-builder__olap__column__window__popover">
977
- <div className="panel__content__form__section__list">
978
- <div className="panel__content__form__section__list__items">
979
- {windowColumnState.windowColumns.map((value, idx) => (
980
- <TDSColumnSelectorEditor
981
- key={value.uuid}
982
- colValue={value}
983
- setColumn={(v: QueryBuilderTDSColumnState) =>
984
- windowColumnState.changeWindow(v, idx)
985
- }
986
- deleteColumn={(v: QueryBuilderTDSColumnState): void =>
987
- windowColumnState.deleteWindow(v)
988
- }
989
- tdsColOptions={windowOptions}
990
- />
991
- ))}
992
- </div>
993
- <div className="panel__content__form__section__list__new-item__add">
994
- <button
995
- className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
996
- disabled={!addWindowOptions.length}
997
- onClick={addWindowValue}
998
- tabIndex={-1}
999
- >
1000
- Add Value
1001
- </button>
1002
- </div>
997
+ <div className="panel__content__form__section__list__new-item__add">
998
+ <button
999
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
1000
+ disabled={!addWindowOptions.length}
1001
+ onClick={addWindowValue}
1002
+ tabIndex={-1}
1003
+ >
1004
+ Add Value
1005
+ </button>
1003
1006
  </div>
1004
1007
  </div>
1005
- </BasePopover>
1006
- </div>
1007
- <div className="query-builder__olap__column__sortby">
1008
- <div className="query-builder__olap__column__sortby__operator">
1009
- {sortByState && (
1010
- <div className="query-builder__olap__column__sortby__operator__label">
1011
- {sortByState.sortType.toLowerCase()}
1012
- </div>
1013
- )}
1014
- {sortByState && (
1015
- <TDSColumnReferenceEditor
1016
- tdsColumn={sortByState.columnState}
1017
- handleChange={handleSortDrop}
1018
- selectionEditor={{
1019
- options: windowColumnState.possibleReferencedColumns,
1020
- }}
1021
- />
1022
- )}
1023
- {!sortByState && (
1024
- <div className="query-builder__olap__column__sortby__none">
1025
- (none)
1026
- </div>
1027
- )}
1028
- <DropdownMenu
1029
- className="query-builder__olap__column__sortby__operator__dropdown"
1030
- content={
1031
- <MenuContent>
1008
+ </div>
1009
+ </BasePopover>
1010
+ </div>
1011
+ <div className="query-builder__olap__column__sortby">
1012
+ <div className="query-builder__olap__column__sortby__operator">
1013
+ {sortByState && (
1014
+ <div className="query-builder__olap__column__sortby__operator__label">
1015
+ {sortByState.sortType.toLowerCase()}
1016
+ </div>
1017
+ )}
1018
+ {sortByState && (
1019
+ <TDSColumnReferenceEditor
1020
+ tdsColumn={sortByState.columnState}
1021
+ handleChange={handleSortDrop}
1022
+ selectionEditor={{
1023
+ options: windowColumnState.possibleReferencedColumns,
1024
+ }}
1025
+ />
1026
+ )}
1027
+ {!sortByState && (
1028
+ <div className="query-builder__olap__column__sortby__none">
1029
+ (none)
1030
+ </div>
1031
+ )}
1032
+ <DropdownMenu
1033
+ className="query-builder__olap__column__sortby__operator__dropdown"
1034
+ content={
1035
+ <MenuContent>
1036
+ <MenuContentItem
1037
+ key="none"
1038
+ className="query-builder__olap__column__sortby__operator__dropdown__option"
1039
+ onClick={changeSortBy(undefined)}
1040
+ >
1041
+ (none)
1042
+ </MenuContentItem>
1043
+
1044
+ {Object.values(COLUMN_SORT_TYPE).map((op) => (
1032
1045
  <MenuContentItem
1033
- key="none"
1046
+ key={op}
1034
1047
  className="query-builder__olap__column__sortby__operator__dropdown__option"
1035
- onClick={changeSortBy(undefined)}
1048
+ onClick={changeSortBy(op)}
1036
1049
  >
1037
- (none)
1050
+ {op.toLowerCase()}
1038
1051
  </MenuContentItem>
1039
-
1040
- {Object.values(COLUMN_SORT_TYPE).map((op) => (
1041
- <MenuContentItem
1042
- key={op}
1043
- className="query-builder__olap__column__sortby__operator__dropdown__option"
1044
- onClick={changeSortBy(op)}
1045
- >
1046
- {op.toLowerCase()}
1047
- </MenuContentItem>
1048
- ))}
1049
- </MenuContent>
1050
- }
1051
- menuProps={{
1052
- anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
1053
- transformOrigin: { vertical: 'top', horizontal: 'left' },
1054
- elevation: 7,
1055
- }}
1056
- >
1057
- <button
1058
- className={clsx(
1059
- 'query-builder__olap__column__sortby__operator__badge',
1060
- {
1061
- 'query-builder__olap__column__sortby__operator__badge--activated':
1062
- Boolean(sortByState),
1063
- },
1064
- )}
1065
- tabIndex={-1}
1066
- title="Choose Window Function SortBy Operator..."
1067
- >
1068
- <SortIcon />
1069
- </button>
1070
- <button
1071
- className="query-builder__olap__column__sortby__operator__dropdown__trigger"
1072
- tabIndex={-1}
1073
- title="Choose Window Function SortBy Operator..."
1074
- >
1075
- <CaretDownIcon />
1076
- </button>
1077
- </DropdownMenu>
1078
- </div>
1079
- </div>
1080
- <div className="query-builder__olap__column__name">
1081
- <InputWithInlineValidation
1082
- className="query-builder__olap__column__name__input input-group__input"
1083
- spellCheck={false}
1084
- value={windowColumnState.columnName}
1085
- onChange={changeColumnName}
1086
- validationErrorMessage={
1087
- isDuplicatedColumnName ? 'Duplicated column' : undefined
1088
- }
1089
- />
1090
- </div>
1091
- <div className="query-builder__olap__column__actions">
1092
- <button
1093
- className="query-builder__olap__column__action"
1094
- tabIndex={-1}
1095
- onClick={editoColumn}
1096
- >
1097
- <EditIcon />
1098
- </button>
1099
- <button
1100
- className="query-builder__olap__column__action"
1101
- tabIndex={-1}
1102
- onClick={removeColumn}
1103
- disabled={isRemovalDisabled}
1104
- title={
1105
- isRemovalDisabled
1106
- ? "This column is used in the post filter and can't be removed"
1107
- : 'Remove'
1052
+ ))}
1053
+ </MenuContent>
1108
1054
  }
1055
+ menuProps={{
1056
+ anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
1057
+ transformOrigin: { vertical: 'top', horizontal: 'left' },
1058
+ elevation: 7,
1059
+ }}
1109
1060
  >
1110
- <TimesIcon />
1111
- </button>
1061
+ <button
1062
+ className={clsx(
1063
+ 'query-builder__olap__column__sortby__operator__badge',
1064
+ {
1065
+ 'query-builder__olap__column__sortby__operator__badge--activated':
1066
+ Boolean(sortByState),
1067
+ },
1068
+ )}
1069
+ tabIndex={-1}
1070
+ title="Choose Window Function SortBy Operator..."
1071
+ >
1072
+ <SortIcon />
1073
+ </button>
1074
+ <button
1075
+ className="query-builder__olap__column__sortby__operator__dropdown__trigger"
1076
+ tabIndex={-1}
1077
+ title="Choose Window Function SortBy Operator..."
1078
+ >
1079
+ <CaretDownIcon />
1080
+ </button>
1081
+ </DropdownMenu>
1112
1082
  </div>
1113
- </ContextMenu>
1114
- </PanelEntryDropZonePlaceholder>
1115
- </div>
1083
+ </div>
1084
+ <div className="query-builder__olap__column__name">
1085
+ <InputWithInlineValidation
1086
+ className="query-builder__olap__column__name__input input-group__input"
1087
+ spellCheck={false}
1088
+ value={windowColumnState.columnName}
1089
+ onChange={changeColumnName}
1090
+ validationErrorMessage={
1091
+ isDuplicatedColumnName ? 'Duplicated column' : undefined
1092
+ }
1093
+ />
1094
+ </div>
1095
+ <div className="query-builder__olap__column__actions">
1096
+ <button
1097
+ className="query-builder__olap__column__action"
1098
+ tabIndex={-1}
1099
+ onClick={editoColumn}
1100
+ >
1101
+ <EditIcon />
1102
+ </button>
1103
+ <button
1104
+ className="query-builder__olap__column__action"
1105
+ tabIndex={-1}
1106
+ onClick={removeColumn}
1107
+ disabled={isRemovalDisabled}
1108
+ title={
1109
+ isRemovalDisabled
1110
+ ? "This column is used in the post filter and can't be removed"
1111
+ : 'Remove'
1112
+ }
1113
+ >
1114
+ <TimesIcon />
1115
+ </button>
1116
+ </div>
1117
+ </ContextMenu>
1118
+ </PanelDnDEntry>
1116
1119
  );
1117
1120
  },
1118
1121
  );
@@ -20,26 +20,26 @@ import {
20
20
  assertErrorThrown,
21
21
  LogEvent,
22
22
  guaranteeNonNullable,
23
- ContentType,
24
- guaranteeType,
23
+ type ContentType,
25
24
  downloadFileUsingDataURI,
26
- UnsupportedOperationError,
27
25
  ActionState,
28
26
  StopWatch,
27
+ getContentTypeFileExtension,
29
28
  } from '@finos/legend-shared';
30
29
  import type { QueryBuilderState } from './QueryBuilderState.js';
31
30
  import {
32
31
  type RawExecutionPlan,
33
32
  type ExecutionResult,
34
33
  type RawLambda,
34
+ type EXECUTION_SERIALIZATION_FORMAT,
35
35
  GRAPH_MANAGER_EVENT,
36
- EXECUTION_SERIALIZATION_FORMAT,
37
36
  RawExecutionResult,
38
37
  buildRawLambdaFromLambdaFunction,
39
38
  reportGraphAnalytics,
39
+ extractExecutionResultValues,
40
40
  } from '@finos/legend-graph';
41
41
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
42
- import { ExecutionPlanState } from '@finos/legend-application';
42
+ import { ExecutionPlanState, TAB_SIZE } from '@finos/legend-application';
43
43
  import {
44
44
  buildExecutionParameterValues,
45
45
  getExecutionQueryFromRawLambda,
@@ -50,6 +50,11 @@ import { QUERY_BUILDER_EVENT } from '../application/QueryBuilderEvent.js';
50
50
 
51
51
  const DEFAULT_LIMIT = 1000;
52
52
 
53
+ export interface ExportDataInfo {
54
+ contentType: ContentType;
55
+ serializationFormat?: EXECUTION_SERIALIZATION_FORMAT | undefined;
56
+ }
57
+
53
58
  export class QueryBuilderResultState {
54
59
  readonly queryBuilderState: QueryBuilderState;
55
60
  readonly exportDataState = ActionState.create();
@@ -148,25 +153,21 @@ export class QueryBuilderResultState {
148
153
  return query;
149
154
  }
150
155
 
151
- *exportData(
152
- serializationFormat: EXECUTION_SERIALIZATION_FORMAT,
153
- ): GeneratorFn<void> {
156
+ *exportData(format: string): GeneratorFn<void> {
154
157
  try {
158
+ const exportData =
159
+ this.queryBuilderState.fetchStructureState.implementation.getExportDataInfo(
160
+ format,
161
+ );
162
+ const contentType = exportData.contentType;
163
+ const serializationFormat = exportData.serializationFormat;
155
164
  this.exportDataState.inProgress();
156
- const mapping = guaranteeNonNullable(
157
- this.queryBuilderState.mapping,
158
- 'Mapping is required to execute query',
159
- );
160
- const runtime = guaranteeNonNullable(
161
- this.queryBuilderState.runtimeValue,
162
- `Runtime is required to execute query`,
163
- );
164
165
  const query = this.buildExecutionRawLambda();
165
166
  const result =
166
167
  (yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
167
168
  query,
168
- mapping,
169
- runtime,
169
+ this.queryBuilderState.mapping,
170
+ this.queryBuilderState.runtimeValue,
170
171
  this.queryBuilderState.graphManagerState.graph,
171
172
  {
172
173
  serializationFormat,
@@ -176,23 +177,17 @@ export class QueryBuilderResultState {
176
177
  ),
177
178
  },
178
179
  )) as ExecutionResult;
179
- let contentType: ContentType;
180
- let fileName = 'result';
181
180
  let content: string;
182
- switch (serializationFormat) {
183
- case EXECUTION_SERIALIZATION_FORMAT.CSV:
184
- {
185
- const rawResult = guaranteeType(result, RawExecutionResult);
186
- contentType = ContentType.TEXT_CSV;
187
- fileName = `${fileName}.csv`;
188
- content = rawResult.value;
189
- }
190
- break;
191
- default:
192
- throw new UnsupportedOperationError(
193
- `Can't download file for serialization type: '${serializationFormat}'`,
194
- );
181
+ if (result instanceof RawExecutionResult) {
182
+ content = result.value;
183
+ } else {
184
+ content = JSON.stringify(
185
+ extractExecutionResultValues(result),
186
+ null,
187
+ TAB_SIZE,
188
+ );
195
189
  }
190
+ const fileName = `result.${getContentTypeFileExtension(contentType)}`;
196
191
  downloadFileUsingDataURI(fileName, content, contentType);
197
192
  this.exportDataState.pass();
198
193
  } catch (error) {