@finos/legend-query-builder 4.0.8 → 4.0.10

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 (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
+ };