@finos/legend-query-builder 4.0.8 → 4.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. package/lib/__lib__/QueryBuilderColorTheme.js +1 -1
  2. package/lib/__lib__/QueryBuilderColorTheme.js.map +1 -1
  3. package/lib/__lib__/QueryBuilderDocumentation.js +1 -1
  4. package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
  5. package/lib/__lib__/QueryBuilderEvent.js +3 -3
  6. package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
  7. package/lib/__lib__/QueryBuilderSetting.js +1 -1
  8. package/lib/__lib__/QueryBuilderSetting.js.map +1 -1
  9. package/lib/__lib__/QueryBuilderTesting.js +1 -1
  10. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  11. package/lib/components/QueryBuilderComponentElement.js +1 -1
  12. package/lib/components/QueryBuilderComponentElement.js.map +1 -1
  13. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  14. package/lib/components/QueryBuilderResultPanel.js +210 -69
  15. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  16. package/lib/components/QueryBuilder_LegendApplicationPlugin.js +1 -2
  17. package/lib/components/QueryBuilder_LegendApplicationPlugin.js.map +1 -1
  18. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  19. package/lib/components/explorer/QueryBuilderExplorerPanel.js +3 -3
  20. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  21. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  22. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js +3 -3
  23. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
  24. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +60 -21
  26. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  27. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +10 -2
  29. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  30. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  31. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +2 -2
  32. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  33. package/lib/components/filter/QueryBuilderFilterPanel.d.ts +4 -0
  34. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  35. package/lib/components/filter/QueryBuilderFilterPanel.js +69 -31
  36. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  37. package/lib/components/shared/CustomDatePicker.js +1 -1
  38. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  39. package/lib/graph/QueryBuilderMetaModelConst.js +3 -3
  40. package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
  41. package/lib/graph-manager/QueryBuilderConst.js +1 -1
  42. package/lib/graph-manager/QueryBuilderConst.js.map +1 -1
  43. package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.d.ts.map +1 -1
  44. package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.js +4 -4
  45. package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.js.map +1 -1
  46. package/lib/index.css +17 -1
  47. package/lib/index.css.map +1 -1
  48. package/lib/package.json +7 -7
  49. package/lib/stores/QueryBuilderChangeDetectionState.js +1 -1
  50. package/lib/stores/QueryBuilderChangeDetectionState.js.map +1 -1
  51. package/lib/stores/QueryBuilderCommand.js +1 -1
  52. package/lib/stores/QueryBuilderCommand.js.map +1 -1
  53. package/lib/stores/QueryBuilderConfig.js +2 -2
  54. package/lib/stores/QueryBuilderConfig.js.map +1 -1
  55. package/lib/stores/QueryBuilderGroupOperationHelper.js +1 -1
  56. package/lib/stores/QueryBuilderGroupOperationHelper.js.map +1 -1
  57. package/lib/stores/QueryBuilderResultState.d.ts +19 -0
  58. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  59. package/lib/stores/QueryBuilderResultState.js +48 -1
  60. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  61. package/lib/stores/QueryBuilderStateHashUtils.js +1 -1
  62. package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
  63. package/lib/stores/QueryBuilderTextEditorState.js +1 -1
  64. package/lib/stores/QueryBuilderTextEditorState.js.map +1 -1
  65. package/lib/stores/execution-plan/ExecutionPlanState.js +1 -1
  66. package/lib/stores/execution-plan/ExecutionPlanState.js.map +1 -1
  67. package/lib/stores/explorer/QueryBuilderExplorerState.js +1 -1
  68. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  69. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js +1 -1
  70. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  71. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +2 -2
  72. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  73. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +1 -1
  74. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  75. package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js +1 -1
  76. package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js.map +1 -1
  77. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  78. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +2 -2
  79. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  80. package/lib/stores/filter/QueryBuilderFilterState.js +1 -1
  81. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  82. package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
  83. package/lib/stores/shared/LambdaParameterState.js +2 -2
  84. package/lib/stores/shared/LambdaParameterState.js.map +1 -1
  85. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +5 -2
  86. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
  87. package/lib/stores/shared/ValueSpecificationEditorHelper.js +30 -40
  88. package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
  89. package/package.json +15 -15
  90. package/src/components/QueryBuilderResultPanel.tsx +358 -93
  91. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +10 -14
  92. package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +6 -4
  93. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +103 -14
  94. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +18 -1
  95. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +12 -10
  96. package/src/components/filter/QueryBuilderFilterPanel.tsx +134 -42
  97. package/src/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.ts +4 -5
  98. package/src/stores/QueryBuilderResultState.ts +82 -0
  99. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -0
  100. package/src/stores/shared/LambdaParameterState.ts +1 -0
  101. package/src/stores/shared/ValueSpecificationEditorHelper.ts +80 -57
@@ -56,7 +56,7 @@ import {
56
56
  QueryBuilderFilterTreeBlankConditionNodeData,
57
57
  QueryBuilderFilterTreeGroupNodeData,
58
58
  } from '../../stores/filter/QueryBuilderFilterState.js';
59
- import { useDrag, useDrop } from 'react-dnd';
59
+ import { useDrag, useDragLayer, useDrop } from 'react-dnd';
60
60
  import {
61
61
  type QueryBuilderExplorerTreeDragSource,
62
62
  type QueryBuilderExplorerTreePropertyNodeData,
@@ -88,12 +88,26 @@ import {
88
88
  } from '../shared/BasicValueSpecificationEditor.js';
89
89
  import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
90
90
 
91
+ export const IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED = [
92
+ QUERY_BUILDER_FILTER_DND_TYPE.CONDITION,
93
+ QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
94
+ QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
95
+ QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE,
96
+ ];
97
+
98
+ export const IS_DRAGGABLE_FILTER_DND_TYPES = [
99
+ QUERY_BUILDER_FILTER_DND_TYPE.CONDITION,
100
+ QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
101
+ QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
102
+ ];
103
+
91
104
  const QueryBuilderFilterGroupConditionEditor = observer(
92
105
  (props: {
93
106
  node: QueryBuilderFilterTreeGroupNodeData;
94
107
  isDragOver: boolean;
108
+ showDroppableSuggestion: boolean;
95
109
  }) => {
96
- const { node, isDragOver } = props;
110
+ const { node, isDragOver, showDroppableSuggestion } = props;
97
111
  const switchOperation: React.MouseEventHandler<HTMLDivElement> = (
98
112
  event,
99
113
  ): void => {
@@ -105,30 +119,31 @@ const QueryBuilderFilterGroupConditionEditor = observer(
105
119
  );
106
120
  };
107
121
  return (
108
- <div className="query-builder-filter-tree__node__label__content">
109
- <PanelEntryDropZonePlaceholder
110
- showPlaceholder={isDragOver}
111
- label="Add to Logical Group"
112
- className="query-builder__dnd__placeholder"
113
- >
122
+ <div className="query-builder-filter-tree__node__label__content dnd__entry__container">
123
+ {showDroppableSuggestion && (
114
124
  <div
115
- className={clsx('query-builder-filter-tree__group-node', {
116
- 'query-builder-filter-tree__group-node--and':
117
- node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND,
118
- 'query-builder-filter-tree__group-node--or':
119
- node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.OR,
125
+ className={clsx('dnd__entry--droppable__indicator ', {
126
+ 'dnd__entry--droppable__indicator--dragover': isDragOver,
120
127
  })}
121
- title="Switch Operation"
122
- onClick={switchOperation}
123
- >
124
- <div className="query-builder-filter-tree__group-node__label">
125
- {node.groupOperation}
126
- </div>
127
- <button className="query-builder-filter-tree__group-node__action">
128
- <FilledTriangleIcon />
129
- </button>
128
+ ></div>
129
+ )}
130
+ <div
131
+ className={clsx('query-builder-filter-tree__group-node', {
132
+ 'query-builder-filter-tree__group-node--and':
133
+ node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND,
134
+ 'query-builder-filter-tree__group-node--or':
135
+ node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.OR,
136
+ })}
137
+ title="Switch Operation"
138
+ onClick={switchOperation}
139
+ >
140
+ <div className="query-builder-filter-tree__group-node__label">
141
+ {node.groupOperation}
130
142
  </div>
131
- </PanelEntryDropZonePlaceholder>
143
+ <button className="query-builder-filter-tree__group-node__action">
144
+ <FilledTriangleIcon />
145
+ </button>
146
+ </div>
132
147
  </div>
133
148
  );
134
149
  },
@@ -190,6 +205,7 @@ const QueryBuilderFilterConditionEditor = observer(
190
205
  }),
191
206
  [handleDrop],
192
207
  );
208
+
193
209
  const resetNode = (): void => {
194
210
  node.condition.setValue(
195
211
  node.condition.operator.getDefaultFilterConditionValue(node.condition),
@@ -215,8 +231,29 @@ const QueryBuilderFilterConditionEditor = observer(
215
231
  reloadValues: debouncedTypeaheadSearch,
216
232
  cleanUpReloadValues,
217
233
  };
234
+
235
+ const { showDroppableSuggestion } = useDragLayer((monitor) => ({
236
+ showDroppableSuggestion:
237
+ monitor.isDragging() &&
238
+ (queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
239
+ ? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
240
+ : IS_DRAGGABLE_FILTER_DND_TYPES
241
+ ).includes(monitor.getItemType()?.toString() ?? ''),
242
+ }));
243
+
218
244
  return (
219
- <div className="query-builder-filter-tree__node__label__content">
245
+ <div className="query-builder-filter-tree__node__label__content dnd__entry__container">
246
+ {showDroppableSuggestion && (
247
+ <div
248
+ className={clsx(
249
+ 'dnd__entry--droppable__indicator dnd__entry-potential__oiodropzone__indicator--full',
250
+ {
251
+ 'dnd__entry--droppable__indicator--dragover': isDragOver,
252
+ },
253
+ )}
254
+ ></div>
255
+ )}
256
+
220
257
  <PanelEntryDropZonePlaceholder
221
258
  showPlaceholder={isDragOver}
222
259
  label="Add New Logical Group"
@@ -299,8 +336,9 @@ const QueryBuilderFilterBlankConditionEditor = observer(
299
336
  (props: {
300
337
  node: QueryBuilderFilterTreeBlankConditionNodeData;
301
338
  isDragOver: boolean;
339
+ showDroppableSuggestion: boolean;
302
340
  }) => {
303
- const { isDragOver } = props;
341
+ const { isDragOver, showDroppableSuggestion } = props;
304
342
  return (
305
343
  <div className="query-builder-filter-tree__node__label__content">
306
344
  <PanelEntryDropZonePlaceholder
@@ -308,6 +346,9 @@ const QueryBuilderFilterBlankConditionEditor = observer(
308
346
  label="Create Condition"
309
347
  className="query-builder__dnd__placeholder"
310
348
  >
349
+ {showDroppableSuggestion && (
350
+ <div className="query-builder-filter-tree__blank-node--droppable"></div>
351
+ )}
311
352
  <div className="query-builder-filter-tree__blank-node">blank</div>
312
353
  </PanelEntryDropZonePlaceholder>
313
354
  </div>
@@ -390,11 +431,31 @@ const QueryBuilderFilterTreeNodeContainer = observer(
390
431
  // Drag and Drop
391
432
  const handleDrop = useCallback(
392
433
  (item: QueryBuilderFilterDropTarget, type: string): void => {
393
- if (
394
- Object.values<string>(QUERY_BUILDER_FILTER_DND_TYPE).includes(type)
395
- ) {
396
- // const dropNode = (item as QueryBuilderFilterConditionDragSource).node;
397
- // TODO: re-arrange
434
+ if (QUERY_BUILDER_FILTER_DND_TYPE.CONDITION === type) {
435
+ const nodeBeingDragged = (
436
+ item as QueryBuilderFilterConditionDragSource
437
+ ).node;
438
+
439
+ const newCreatedNode = new QueryBuilderFilterTreeConditionNodeData(
440
+ undefined,
441
+ (
442
+ filterState.nodes.get(
443
+ nodeBeingDragged.id,
444
+ ) as QueryBuilderFilterTreeConditionNodeData
445
+ ).condition,
446
+ );
447
+
448
+ if (node instanceof QueryBuilderFilterTreeBlankConditionNodeData) {
449
+ filterState.replaceBlankNodeWithNode(newCreatedNode, node);
450
+ filterState.removeNodeAndPruneBranch(nodeBeingDragged);
451
+ } else if (node instanceof QueryBuilderFilterTreeConditionNodeData) {
452
+ filterState.newGroupWithConditionFromNode(newCreatedNode, node);
453
+
454
+ filterState.removeNodeAndPruneBranch(nodeBeingDragged);
455
+ } else if (node instanceof QueryBuilderFilterTreeGroupNodeData) {
456
+ filterState.addNodeFromNode(newCreatedNode, node);
457
+ filterState.removeNodeAndPruneBranch(nodeBeingDragged);
458
+ }
398
459
  } else {
399
460
  let filterConditionState: FilterConditionState;
400
461
  try {
@@ -469,17 +530,8 @@ const QueryBuilderFilterTreeNodeContainer = observer(
469
530
  () => ({
470
531
  accept:
471
532
  queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
472
- ? [
473
- ...Object.values(QUERY_BUILDER_FILTER_DND_TYPE),
474
- QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
475
- QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
476
- QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE,
477
- ]
478
- : [
479
- ...Object.values(QUERY_BUILDER_FILTER_DND_TYPE),
480
- QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
481
- QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
482
- ],
533
+ ? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
534
+ : IS_DRAGGABLE_FILTER_DND_TYPES,
483
535
  drop: (item, monitor): void => {
484
536
  if (!monitor.didDrop()) {
485
537
  handleDrop(item, monitor.getItemType() as string);
@@ -508,6 +560,15 @@ const QueryBuilderFilterTreeNodeContainer = observer(
508
560
  dragConnector(dropConnector(ref));
509
561
  useDragPreviewLayer(dragPreviewConnector);
510
562
 
563
+ const { showDroppableSuggestion } = useDragLayer((monitor) => ({
564
+ showDroppableSuggestion:
565
+ monitor.isDragging() &&
566
+ (queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
567
+ ? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
568
+ : IS_DRAGGABLE_FILTER_DND_TYPES
569
+ ).includes(monitor.getItemType()?.toString() ?? ''),
570
+ }));
571
+
511
572
  // context menu
512
573
  const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
513
574
  const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
@@ -566,6 +627,7 @@ const QueryBuilderFilterTreeNodeContainer = observer(
566
627
  {node instanceof QueryBuilderFilterTreeGroupNodeData && (
567
628
  <QueryBuilderFilterGroupConditionEditor
568
629
  node={node}
630
+ showDroppableSuggestion={showDroppableSuggestion}
569
631
  isDragOver={isDragOver}
570
632
  />
571
633
  )}
@@ -579,6 +641,7 @@ const QueryBuilderFilterTreeNodeContainer = observer(
579
641
  <QueryBuilderFilterBlankConditionEditor
580
642
  node={node}
581
643
  isDragOver={isDragOver}
644
+ showDroppableSuggestion={showDroppableSuggestion}
582
645
  />
583
646
  )}
584
647
  </div>
@@ -747,6 +810,16 @@ export const QueryBuilderFilterPanel = observer(
747
810
  );
748
811
  }
749
812
  };
813
+
814
+ const { showDroppableSuggestion } = useDragLayer((monitor) => ({
815
+ showDroppableSuggestion:
816
+ monitor.isDragging() &&
817
+ (queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
818
+ ? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
819
+ : IS_DRAGGABLE_FILTER_DND_TYPES
820
+ ).includes(monitor.getItemType()?.toString() ?? ''),
821
+ }));
822
+
750
823
  // Drag and Drop
751
824
  const handleDrop = useCallback(
752
825
  (item: QueryBuilderFilterDropTarget, type: string): void => {
@@ -795,6 +868,7 @@ export const QueryBuilderFilterPanel = observer(
795
868
  },
796
869
  [applicationStore, filterState],
797
870
  );
871
+
798
872
  const [{ isDragOver }, dropTargetConnector] = useDrop<
799
873
  QueryBuilderExplorerTreeDragSource,
800
874
  void,
@@ -913,7 +987,11 @@ export const QueryBuilderFilterPanel = observer(
913
987
  </div>
914
988
  <PanelContent>
915
989
  <PanelDropZone
916
- isDragOver={isDragOver}
990
+ isDragOver={isDragOver && filterState.isEmpty}
991
+ showDroppableSuggestion={
992
+ showDroppableSuggestion && filterState.isEmpty
993
+ }
994
+ className="query-builder__panel--droppable"
917
995
  dropTargetConnector={dropTargetConnector}
918
996
  >
919
997
  {filterState.isEmpty && (
@@ -933,6 +1011,20 @@ export const QueryBuilderFilterPanel = observer(
933
1011
  <QueryBuilderFilterTree queryBuilderState={queryBuilderState} />
934
1012
  </>
935
1013
  )}
1014
+
1015
+ {showDroppableSuggestion && !filterState.isEmpty && (
1016
+ <div
1017
+ ref={dropTargetConnector}
1018
+ className={clsx(
1019
+ 'query-builder-post-filter-tree__blank-node--droppable--tall',
1020
+ {
1021
+ 'dnd__entry--droppable__indicator--dragover': isDragOver,
1022
+ },
1023
+ )}
1024
+ >
1025
+ Add filter to main group
1026
+ </div>
1027
+ )}
936
1028
  </PanelDropZone>
937
1029
  </PanelContent>
938
1030
  </div>
@@ -25,7 +25,6 @@ import {
25
25
  V1_PureMultiExecution,
26
26
  V1_Service,
27
27
  V1_PackageableRuntime,
28
- type V1_PackageableElement,
29
28
  type PureModel,
30
29
  V1_PureGraphManager,
31
30
  PureClientVersion,
@@ -72,10 +71,10 @@ export class V1_QueryBuilder_PureGraphManagerExtension extends QueryBuilder_Pure
72
71
  entities,
73
72
  dependencyEntitiesIndex,
74
73
  (entity: Entity): boolean =>
75
- ((entity.content as PlainObject<V1_PackageableElement>)
76
- ._type as string) === V1_MAPPING_ELEMENT_PROTOCOL_TYPE ||
77
- ((entity.content as PlainObject<V1_PackageableElement>)
78
- ._type as string) === V1_PACKAGEABLE_RUNTIME_ELEMENT_PROTOCOL_TYPE,
74
+ (entity.content._type as string) ===
75
+ V1_MAPPING_ELEMENT_PROTOCOL_TYPE ||
76
+ (entity.content._type as string) ===
77
+ V1_PACKAGEABLE_RUNTIME_ELEMENT_PROTOCOL_TYPE,
79
78
  );
80
79
  // handle mapping includes
81
80
  const mappings = [
@@ -37,6 +37,7 @@ import {
37
37
  buildRawLambdaFromLambdaFunction,
38
38
  reportGraphAnalytics,
39
39
  extractExecutionResultValues,
40
+ TDSExecutionResult,
40
41
  } from '@finos/legend-graph';
41
42
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
42
43
  import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
@@ -56,6 +57,17 @@ export interface ExportDataInfo {
56
57
  serializationFormat?: EXECUTION_SERIALIZATION_FORMAT | undefined;
57
58
  }
58
59
 
60
+ export interface QueryBuilderTDSResultCellData {
61
+ value: string | number | boolean | null | undefined;
62
+ columnName: string;
63
+ coordinates: QueryBuilderTDSResultCellCoordinate;
64
+ }
65
+
66
+ export interface QueryBuilderTDSResultCellCoordinate {
67
+ rowIndex: number;
68
+ colIndex: number;
69
+ }
70
+
59
71
  export class QueryBuilderResultState {
60
72
  readonly queryBuilderState: QueryBuilderState;
61
73
  readonly exportDataState = ActionState.create();
@@ -70,6 +82,10 @@ export class QueryBuilderResultState {
70
82
  latestRunHashCode?: string | undefined;
71
83
  queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
72
84
 
85
+ selectedCells: QueryBuilderTDSResultCellData[];
86
+ mousedOverCell: QueryBuilderTDSResultCellData | null = null;
87
+ isSelectingCells: boolean;
88
+
73
89
  constructor(queryBuilderState: QueryBuilderState) {
74
90
  makeObservable(this, {
75
91
  executionResult: observable,
@@ -78,18 +94,28 @@ export class QueryBuilderResultState {
78
94
  latestRunHashCode: observable,
79
95
  queryRunPromise: observable,
80
96
  isGeneratingPlan: observable,
97
+ selectedCells: observable,
98
+ mousedOverCell: observable,
81
99
  isRunningQuery: observable,
100
+ isSelectingCells: observable,
101
+ setIsSelectingCells: action,
82
102
  setIsRunningQuery: action,
83
103
  setExecutionResult: action,
84
104
  setExecutionDuration: action,
85
105
  setPreviewLimit: action,
106
+ addCellData: action,
107
+ setSelectedCells: action,
108
+ setMouseOverCell: action,
86
109
  setQueryRunPromise: action,
110
+
87
111
  exportData: flow,
88
112
  runQuery: flow,
89
113
  cancelQuery: flow,
90
114
  generatePlan: flow,
91
115
  });
116
+ this.isSelectingCells = false;
92
117
 
118
+ this.selectedCells = [];
93
119
  this.queryBuilderState = queryBuilderState;
94
120
  this.executionPlanState = new ExecutionPlanState(
95
121
  this.queryBuilderState.applicationStore,
@@ -97,6 +123,10 @@ export class QueryBuilderResultState {
97
123
  );
98
124
  }
99
125
 
126
+ setIsSelectingCells = (val: boolean): void => {
127
+ this.isSelectingCells = val;
128
+ };
129
+
100
130
  setIsRunningQuery = (val: boolean): void => {
101
131
  this.isRunningQuery = val;
102
132
  };
@@ -113,12 +143,64 @@ export class QueryBuilderResultState {
113
143
  this.previewLimit = Math.max(1, val);
114
144
  };
115
145
 
146
+ addCellData = (val: QueryBuilderTDSResultCellData): void => {
147
+ this.selectedCells.push(val);
148
+ };
149
+
150
+ setSelectedCells = (val: QueryBuilderTDSResultCellData[]): void => {
151
+ this.selectedCells = val;
152
+ };
153
+
154
+ setMouseOverCell = (val: QueryBuilderTDSResultCellData | null): void => {
155
+ this.mousedOverCell = val;
156
+ };
157
+
116
158
  setQueryRunPromise = (
117
159
  promise: Promise<ExecutionResult> | undefined,
118
160
  ): void => {
119
161
  this.queryRunPromise = promise;
120
162
  };
121
163
 
164
+ findColumnFromCoordinates = (
165
+ colIndex: number,
166
+ ): string | number | boolean | null | undefined => {
167
+ if (
168
+ !this.executionResult ||
169
+ !(this.executionResult instanceof TDSExecutionResult)
170
+ ) {
171
+ return undefined;
172
+ }
173
+ return this.executionResult.result.columns[colIndex];
174
+ };
175
+
176
+ findRowFromRowIndex = (
177
+ rowIndex: number,
178
+ ): (string | number | boolean | null)[] => {
179
+ if (
180
+ !this.executionResult ||
181
+ !(this.executionResult instanceof TDSExecutionResult)
182
+ ) {
183
+ return [''];
184
+ }
185
+ return this.executionResult.result.rows[rowIndex]?.values ?? [''];
186
+ };
187
+
188
+ findResultValueFromCoordinates = (
189
+ resultCoordinate: [number, number],
190
+ ): string | number | boolean | null | undefined => {
191
+ const rowIndex = resultCoordinate[0];
192
+ const colIndex = resultCoordinate[1];
193
+
194
+ if (
195
+ !this.executionResult ||
196
+ !(this.executionResult instanceof TDSExecutionResult)
197
+ ) {
198
+ return undefined;
199
+ }
200
+
201
+ return this.executionResult.result.rows[rowIndex]?.values[colIndex];
202
+ };
203
+
122
204
  get checkForStaleResults(): boolean {
123
205
  if (this.latestRunHashCode !== this.queryBuilderState.hashCode) {
124
206
  return true;
@@ -569,6 +569,7 @@ export class QueryBuilderPostFilterState
569
569
  undefined,
570
570
  QUERY_BUILDER_GROUP_OPERATION.AND,
571
571
  );
572
+
572
573
  groupNode.addChildNode(rootNode);
573
574
  groupNode.addChildNode(node);
574
575
  this.rootIds = [groupNode.id];
@@ -235,6 +235,7 @@ export class LambdaParameterState implements Hashable {
235
235
  this.parameter,
236
236
  this.graph,
237
237
  this.observerContext,
238
+ { useCurrentDateDependentFunctions: true },
238
239
  ),
239
240
  );
240
241
  }
@@ -41,16 +41,22 @@ import {
41
41
  Multiplicity,
42
42
  CORE_PURE_PATH,
43
43
  buildRawLambdaFromLambdaFunction,
44
+ getValueSpecificationReturnType,
44
45
  } from '@finos/legend-graph';
45
- import { Randomizer, UnsupportedOperationError } from '@finos/legend-shared';
46
+ import {
47
+ Randomizer,
48
+ UnsupportedOperationError,
49
+ returnUndefOnError,
50
+ } from '@finos/legend-shared';
46
51
  import { generateDefaultValueForPrimitiveType } from '../QueryBuilderValueSpecificationHelper.js';
47
52
  import {
48
53
  instanceValue_setValues,
49
54
  valueSpecification_setGenericType,
50
55
  } from './ValueSpecificationModifierHelper.js';
51
- import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
52
-
53
- const VAR_DEFAULT_NAME = 'var';
56
+ import {
57
+ QUERY_BUILDER_PURE_PATH,
58
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS,
59
+ } from '../../graph/QueryBuilderMetaModelConst.js';
54
60
 
55
61
  export const createSupportedFunctionExpression = (
56
62
  supportedFuncName: string,
@@ -63,52 +69,60 @@ export const createSupportedFunctionExpression = (
63
69
  );
64
70
  return funcExpression;
65
71
  };
72
+ export const buildPrimitiveInstanceValue = (
73
+ graph: PureModel,
74
+ type: PRIMITIVE_TYPE,
75
+ value: unknown,
76
+ observerContext: ObserverContext,
77
+ ): PrimitiveInstanceValue => {
78
+ const instance = new PrimitiveInstanceValue(
79
+ GenericTypeExplicitReference.create(
80
+ new GenericType(graph.getPrimitiveType(type)),
81
+ ),
82
+ );
83
+ instanceValue_setValues(instance, [value], observerContext);
84
+ return instance;
85
+ };
66
86
 
67
87
  const createMockPrimitiveValueSpecification = (
68
88
  primitiveType: PrimitiveType,
69
- propertyName: string,
89
+ graph: PureModel,
70
90
  observerContext: ObserverContext,
91
+ options?: {
92
+ useCurrentDateDependentFunctions?: boolean;
93
+ },
71
94
  ): ValueSpecification => {
72
95
  const primitiveTypeName = primitiveType.name;
73
- if (
74
- primitiveTypeName === PRIMITIVE_TYPE.DATE ||
75
- primitiveTypeName === PRIMITIVE_TYPE.DATETIME
76
- ) {
77
- return createSupportedFunctionExpression(
78
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW,
79
- PrimitiveType.DATETIME,
80
- );
81
- } else if (primitiveTypeName === PRIMITIVE_TYPE.STRICTDATE) {
82
- return createSupportedFunctionExpression(
83
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TODAY,
84
- PrimitiveType.STRICTDATE,
96
+ if (options?.useCurrentDateDependentFunctions) {
97
+ if (
98
+ primitiveTypeName === PRIMITIVE_TYPE.DATE ||
99
+ primitiveTypeName === PRIMITIVE_TYPE.DATETIME
100
+ ) {
101
+ return createSupportedFunctionExpression(
102
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW,
103
+ PrimitiveType.DATETIME,
104
+ );
105
+ } else if (primitiveTypeName === PRIMITIVE_TYPE.STRICTDATE) {
106
+ return createSupportedFunctionExpression(
107
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.TODAY,
108
+ PrimitiveType.STRICTDATE,
109
+ );
110
+ }
111
+ }
112
+ if (primitiveTypeName === PRIMITIVE_TYPE.DATE) {
113
+ return buildPrimitiveInstanceValue(
114
+ graph,
115
+ PRIMITIVE_TYPE.STRICTDATE,
116
+ generateDefaultValueForPrimitiveType(primitiveTypeName),
117
+ observerContext,
85
118
  );
86
119
  }
87
- const primitiveInstanceValue = new PrimitiveInstanceValue(
88
- GenericTypeExplicitReference.create(new GenericType(primitiveType)),
120
+ return buildPrimitiveInstanceValue(
121
+ graph,
122
+ primitiveTypeName as PRIMITIVE_TYPE,
123
+ generateDefaultValueForPrimitiveType(primitiveTypeName as PRIMITIVE_TYPE),
124
+ observerContext,
89
125
  );
90
- const randomizer = new Randomizer();
91
- let value: string | boolean | number;
92
- switch (primitiveType.name) {
93
- case PRIMITIVE_TYPE.BOOLEAN:
94
- value = randomizer.getRandomItemInCollection([true, false]) ?? true;
95
- break;
96
- case PRIMITIVE_TYPE.FLOAT:
97
- value = randomizer.getRandomFloat();
98
- break;
99
- case PRIMITIVE_TYPE.DECIMAL:
100
- value = randomizer.getRandomDouble();
101
- break;
102
- case PRIMITIVE_TYPE.NUMBER:
103
- case PRIMITIVE_TYPE.INTEGER:
104
- value = randomizer.getRandomWholeNumber(100);
105
- break;
106
- case PRIMITIVE_TYPE.STRING:
107
- default:
108
- value = `${propertyName} ${randomizer.getRandomWholeNumber(100)}`;
109
- }
110
- instanceValue_setValues(primitiveInstanceValue, [value], observerContext);
111
- return primitiveInstanceValue;
112
126
  };
113
127
 
114
128
  export const createMockEnumerationProperty = (
@@ -116,21 +130,6 @@ export const createMockEnumerationProperty = (
116
130
  ): string =>
117
131
  new Randomizer().getRandomItemInCollection(enumeration.values)?.name ?? '';
118
132
 
119
- export const buildPrimitiveInstanceValue = (
120
- graph: PureModel,
121
- type: PRIMITIVE_TYPE,
122
- value: unknown,
123
- observerContext: ObserverContext,
124
- ): PrimitiveInstanceValue => {
125
- const instance = new PrimitiveInstanceValue(
126
- GenericTypeExplicitReference.create(
127
- new GenericType(graph.getPrimitiveType(type)),
128
- ),
129
- );
130
- instanceValue_setValues(instance, [value], observerContext);
131
- return instance;
132
- };
133
-
134
133
  export const buildDefaultInstanceValue = (
135
134
  graph: PureModel,
136
135
  type: Type,
@@ -219,6 +218,9 @@ export const generateVariableExpressionMockValue = (
219
218
  parameter: VariableExpression,
220
219
  graph: PureModel,
221
220
  observerContext: ObserverContext,
221
+ options?: {
222
+ useCurrentDateDependentFunctions?: boolean;
223
+ },
222
224
  ): ValueSpecification | undefined => {
223
225
  const varType = parameter.genericType?.value.rawType;
224
226
  const multiplicity = parameter.multiplicity;
@@ -231,8 +233,9 @@ export const generateVariableExpressionMockValue = (
231
233
  if (varType instanceof PrimitiveType) {
232
234
  return createMockPrimitiveValueSpecification(
233
235
  varType,
234
- VAR_DEFAULT_NAME,
236
+ graph,
235
237
  observerContext,
238
+ options,
236
239
  );
237
240
  } else if (varType instanceof Enumeration) {
238
241
  const enumValueInstance = new EnumValueInstanceValue(
@@ -272,3 +275,23 @@ export const getValueSpecificationStringValue = (
272
275
  }
273
276
  return undefined;
274
277
  };
278
+
279
+ export const valueSpecReturnTDS = (
280
+ val: ValueSpecification,
281
+ graph: PureModel,
282
+ ): boolean => {
283
+ const retunType = returnUndefOnError(() =>
284
+ getValueSpecificationReturnType(val),
285
+ );
286
+ const tdsType = returnUndefOnError(() =>
287
+ graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_TABULAR_DATASET),
288
+ );
289
+ const tdsRowType = returnUndefOnError(() =>
290
+ graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_ROW),
291
+ );
292
+ // FIXME: we sometimes return tds row when tds is the return type of the lambda. We do this to properly build post filters.
293
+ // We should fix this to properly build filter functions after a tds function
294
+ return Boolean(
295
+ retunType && tdsType && (retunType === tdsType || retunType === tdsRowType),
296
+ );
297
+ };