@finos/legend-query-builder 4.9.2 → 4.9.4

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 (47) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +4 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +5 -1
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  6. package/lib/components/explorer/QueryBuilderExplorerPanel.js +1 -1
  7. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +4 -5
  10. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  11. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  12. package/lib/components/filter/QueryBuilderFilterPanel.js +4 -4
  13. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  14. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +2 -1
  15. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
  16. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +2 -2
  17. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
  18. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts +1 -1
  19. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts.map +1 -1
  20. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js +2 -2
  21. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js.map +1 -1
  22. package/lib/package.json +1 -1
  23. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +1 -1
  24. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
  25. package/lib/stores/explorer/QueryBuilderExplorerState.js +38 -10
  26. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  27. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.d.ts.map +1 -1
  28. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.js +6 -0
  29. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.js.map +1 -1
  30. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateCalendarFunction.d.ts +3 -3
  31. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateCalendarFunction.d.ts.map +1 -1
  32. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateCalendarFunction.js.map +1 -1
  33. package/lib/stores/fetch-structure/tds/aggregation/calendarFunctions/QueryBuilderAggregateCalendarFunctionValueSpecificationBuilder.d.ts +2 -2
  34. package/lib/stores/fetch-structure/tds/aggregation/calendarFunctions/QueryBuilderAggregateCalendarFunctionValueSpecificationBuilder.d.ts.map +1 -1
  35. package/lib/stores/fetch-structure/tds/aggregation/calendarFunctions/QueryBuilderAggregateCalendarFunctionValueSpecificationBuilder.js +5 -4
  36. package/lib/stores/fetch-structure/tds/aggregation/calendarFunctions/QueryBuilderAggregateCalendarFunctionValueSpecificationBuilder.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/__lib__/QueryBuilderTesting.ts +5 -1
  39. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +1 -0
  40. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +18 -15
  41. package/src/components/filter/QueryBuilderFilterPanel.tsx +12 -3
  42. package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +4 -2
  43. package/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts +3 -4
  44. package/src/stores/explorer/QueryBuilderExplorerState.ts +58 -12
  45. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.ts +10 -0
  46. package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateCalendarFunction.ts +2 -3
  47. package/src/stores/fetch-structure/tds/aggregation/calendarFunctions/QueryBuilderAggregateCalendarFunctionValueSpecificationBuilder.ts +7 -6
@@ -265,24 +265,28 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
265
265
  );
266
266
 
267
267
  type CalendarFunctionOption = {
268
- label: string | React.ReactNode;
268
+ label: string;
269
269
  value: QueryBuilderAggregateCalendarFunction;
270
270
  };
271
271
 
272
+ const formatCalendarFunctionOptionLabel = (
273
+ option: CalendarFunctionOption,
274
+ ): React.ReactNode => (
275
+ <div
276
+ className="query-builder__projection__calendar__function__label"
277
+ title={option.value.getLabel()}
278
+ >
279
+ <FunctionIcon className="query-builder__projection__calendar__function__label__icon" />
280
+ <div className="query-builder__projection__calendar__function__label__title">
281
+ {option.value.getLabel()}
282
+ </div>
283
+ </div>
284
+ );
285
+
272
286
  const buildCalendarFunctionOption = (
273
287
  calendarFunction: QueryBuilderAggregateCalendarFunction,
274
288
  ): CalendarFunctionOption => ({
275
- label: (
276
- <div
277
- className="query-builder__projection__calendar__function__label"
278
- title={calendarFunction.getLabel()}
279
- >
280
- <FunctionIcon className="query-builder__projection__calendar__function__label__icon" />
281
- <div className="query-builder__projection__calendar__function__label__title">
282
- {calendarFunction.getLabel()}
283
- </div>
284
- </div>
285
- ),
289
+ label: calendarFunction.getLabel(),
286
290
  value: calendarFunction,
287
291
  });
288
292
 
@@ -865,6 +869,7 @@ const QueryBuilderProjectionColumnEditor = observer(
865
869
  options={calendarFunctionOptions}
866
870
  onChange={onCalendarFunctionOptionChange}
867
871
  value={selectedCalendarFunctionOption}
872
+ formatOptionLabel={formatCalendarFunctionOptionLabel}
868
873
  placeholder="Select Calendar Function"
869
874
  isClearable={true}
870
875
  escapeClearsValue={true}
@@ -880,9 +885,7 @@ const QueryBuilderProjectionColumnEditor = observer(
880
885
  defaultEndDate
881
886
  }
882
887
  setValueSpecification={(val: ValueSpecification): void => {
883
- if (val instanceof PrimitiveInstanceValue) {
884
- aggregateColumnState.calendarFunction?.setEndDate(val);
885
- }
888
+ aggregateColumnState.calendarFunction?.setEndDate(val);
886
889
  }}
887
890
  graph={tdsState.queryBuilderState.graphManagerState.graph}
888
891
  obseverContext={tdsState.queryBuilderState.observerContext}
@@ -932,6 +932,9 @@ const QueryBuilderFilterTreeNodeContainer = observer(
932
932
  >
933
933
  <div
934
934
  ref={ref}
935
+ data-testid={
936
+ QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_TREE_NODE_CONTENT
937
+ }
935
938
  className={clsx(
936
939
  'tree-view__node__container query-builder-filter-tree__node__container',
937
940
  {
@@ -1036,7 +1039,10 @@ const QueryBuilderFilterTreeNodeView = observer(
1036
1039
  innerProps,
1037
1040
  } = props;
1038
1041
  return (
1039
- <div className="tree-view__node__block">
1042
+ <div
1043
+ data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_TREE_NODE}
1044
+ className="tree-view__node__block"
1045
+ >
1040
1046
  <QueryBuilderFilterTreeNodeContainer
1041
1047
  node={node}
1042
1048
  level={level + 1}
@@ -1079,7 +1085,10 @@ const QueryBuilderFilterTree = observer(
1079
1085
  ? node.childrenIds.map((id) => filterState.getNode(id))
1080
1086
  : [];
1081
1087
  return (
1082
- <div className="tree-view__node__root query-builder-filter-tree__root">
1088
+ <div
1089
+ data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_TREE}
1090
+ className="tree-view__node__root query-builder-filter-tree__root"
1091
+ >
1083
1092
  {rootNodes.map((node) => (
1084
1093
  <QueryBuilderFilterTreeNodeView
1085
1094
  key={node.id}
@@ -1248,7 +1257,7 @@ export const QueryBuilderFilterPanel = observer(
1248
1257
 
1249
1258
  return (
1250
1259
  <div
1251
- data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER}
1260
+ data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_PANEL}
1252
1261
  className="panel"
1253
1262
  >
1254
1263
  <div className="panel__header">
@@ -21,6 +21,7 @@ import {
21
21
  getMultiplicityDescription,
22
22
  CORE_PURE_PATH,
23
23
  PURE_DOC_TAG,
24
+ type Type,
24
25
  } from '@finos/legend-graph';
25
26
 
26
27
  export const QueryBuilderPropertyInfoTooltip: React.FC<{
@@ -29,8 +30,9 @@ export const QueryBuilderPropertyInfoTooltip: React.FC<{
29
30
  isMapped: boolean;
30
31
  children: React.ReactElement;
31
32
  placement?: TooltipPlacement | undefined;
33
+ type?: Type | undefined;
32
34
  }> = (props) => {
33
- const { property, path, isMapped, children, placement } = props;
35
+ const { property, path, isMapped, children, placement, type } = props;
34
36
  const documentation = property.taggedValues
35
37
  .filter(
36
38
  (taggedValue) =>
@@ -60,7 +62,7 @@ export const QueryBuilderPropertyInfoTooltip: React.FC<{
60
62
  <div className="query-builder__tooltip__item">
61
63
  <div className="query-builder__tooltip__item__label">Type</div>
62
64
  <div className="query-builder__tooltip__item__value">
63
- {property.genericType.value.rawType.path}
65
+ {type?.path ?? property.genericType.value.rawType.path}
64
66
  </div>
65
67
  </div>
66
68
  <div className="query-builder__tooltip__item">
@@ -26,7 +26,7 @@ import {
26
26
  import {
27
27
  type V1_GraphBuilderContext,
28
28
  type V1_ProcessingContext,
29
- type V1_ValueSpecification,
29
+ V1_ValueSpecification,
30
30
  type ValueSpecification,
31
31
  type SimpleFunctionExpression,
32
32
  type Type,
@@ -50,7 +50,6 @@ import {
50
50
  VariableExpression,
51
51
  Multiplicity,
52
52
  PrimitiveType,
53
- V1_CStrictDate,
54
53
  V1_CString,
55
54
  CORE_PURE_PATH,
56
55
  FunctionType,
@@ -203,8 +202,8 @@ const buildCalendarFunctionExpression = (
203
202
  );
204
203
  guaranteeType(
205
204
  currentPropertyExpression.parameters[2],
206
- V1_CStrictDate,
207
- `Can't build calendar aggregation column: only support third parameter of calendar function as StrictDate`,
205
+ V1_ValueSpecification,
206
+ `Can't build calendar aggregation column: only support third parameter of calendar function as Date`,
208
207
  );
209
208
  const dateColumn =
210
209
  currentPropertyExpression.parameters[0].accept_ValueSpecificationVisitor(
@@ -152,13 +152,14 @@ export class QueryBuilderExplorerTreePropertyNodeData extends QueryBuilderExplor
152
152
  parentId: string,
153
153
  isPartOfDerivedPropertyBranch: boolean,
154
154
  mappingData: QueryBuilderExplorerTreeNodeMappingData,
155
+ type?: Type | undefined,
155
156
  ) {
156
157
  super(
157
158
  id,
158
159
  label,
159
160
  dndText,
160
161
  isPartOfDerivedPropertyBranch,
161
- property.genericType.value.rawType,
162
+ type ?? property.genericType.value.rawType,
162
163
  mappingData,
163
164
  );
164
165
  this.property = property;
@@ -217,10 +218,11 @@ export const buildPropertyExpressionFromExplorerTreeNodeData = (
217
218
  let parentNode =
218
219
  treeData.nodes.get(node.parentId) ??
219
220
  propertySearchIndexedTreeNodes.find((n) => n.id === node.parentId);
220
- let currentNode: QueryBuilderExplorerTreeNodeData = node;
221
+ let currentNode: QueryBuilderExplorerTreeNodeData | undefined = node;
221
222
  while (
222
- parentNode instanceof QueryBuilderExplorerTreePropertyNodeData ||
223
- parentNode instanceof QueryBuilderExplorerTreeSubTypeNodeData
223
+ currentNode &&
224
+ (parentNode instanceof QueryBuilderExplorerTreePropertyNodeData ||
225
+ parentNode instanceof QueryBuilderExplorerTreeSubTypeNodeData)
224
226
  ) {
225
227
  // NOTE: here, we deliberately simplify subtypes chain
226
228
  // $x.employees->subType(@Person)->subType(@Staff).department will be simplified to $x.employees->subType(@Staff).department
@@ -237,6 +239,24 @@ export const buildPropertyExpressionFromExplorerTreeNodeData = (
237
239
  parentPropertyExpression = new SimpleFunctionExpression(
238
240
  extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE),
239
241
  );
242
+ } else if (
243
+ parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
244
+ parentNode.mappingData.entityMappedProperty?.subType
245
+ ) {
246
+ parentPropertyExpression = new SimpleFunctionExpression(
247
+ extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE),
248
+ );
249
+ currentExpression.parametersValues.push(parentPropertyExpression);
250
+ currentExpression = parentPropertyExpression;
251
+ parentPropertyExpression = new AbstractPropertyExpression('');
252
+ propertyExpression_setFunc(
253
+ parentPropertyExpression,
254
+ PropertyExplicitReference.create(
255
+ guaranteeNonNullable(parentNode.property),
256
+ ),
257
+ );
258
+ currentNode = parentNode;
259
+ parentNode = treeData.nodes.get(parentNode.parentId);
240
260
  } else {
241
261
  parentPropertyExpression = new AbstractPropertyExpression('');
242
262
  propertyExpression_setFunc(
@@ -262,7 +282,11 @@ export const buildPropertyExpressionFromExplorerTreeNodeData = (
262
282
  }
263
283
  currentExpression = parentPropertyExpression;
264
284
  currentNode = parentNode;
265
- parentNode = treeData.nodes.get(parentNode.parentId);
285
+ parentNode =
286
+ parentNode instanceof QueryBuilderExplorerTreePropertyNodeData ||
287
+ parentNode instanceof QueryBuilderExplorerTreeSubTypeNodeData
288
+ ? treeData.nodes.get(parentNode.parentId)
289
+ : undefined;
266
290
  if (
267
291
  !parentNode &&
268
292
  (currentNode instanceof QueryBuilderExplorerTreePropertyNodeData ||
@@ -277,7 +301,7 @@ export const buildPropertyExpressionFromExplorerTreeNodeData = (
277
301
  }
278
302
  }
279
303
  currentExpression.parametersValues.push(projectionColumnLambdaVariable);
280
- if (currentExpression instanceof SimpleFunctionExpression) {
304
+ if (currentNode && currentExpression instanceof SimpleFunctionExpression) {
281
305
  const subclass = new InstanceValue(
282
306
  Multiplicity.ONE,
283
307
  GenericTypeExplicitReference.create(new GenericType(currentNode.type)),
@@ -444,13 +468,32 @@ export const getQueryBuilderPropertyNodeData = (
444
468
  ) {
445
469
  return undefined;
446
470
  }
471
+ const _subclasses =
472
+ property.genericType.value.rawType instanceof Class
473
+ ? getAllSubclasses(property.genericType.value.rawType)
474
+ : [];
475
+ const subClass = mappingNodeData.entityMappedProperty?.subType
476
+ ? _subclasses.find(
477
+ (c) => c.path === mappingNodeData.entityMappedProperty?.subType,
478
+ )
479
+ : undefined;
447
480
  const propertyNode = new QueryBuilderExplorerTreePropertyNodeData(
448
- generateExplorerTreePropertyNodeID(
449
- parentNode instanceof QueryBuilderExplorerTreeRootNodeData
450
- ? ''
451
- : parentNode.id,
452
- property.name,
453
- ),
481
+ subClass
482
+ ? generateExplorerTreeSubtypeNodeID(
483
+ generateExplorerTreePropertyNodeID(
484
+ parentNode instanceof QueryBuilderExplorerTreeRootNodeData
485
+ ? ''
486
+ : parentNode.id,
487
+ property.name,
488
+ ),
489
+ subClass.path,
490
+ )
491
+ : generateExplorerTreePropertyNodeID(
492
+ parentNode instanceof QueryBuilderExplorerTreeRootNodeData
493
+ ? ''
494
+ : parentNode.id,
495
+ property.name,
496
+ ),
454
497
  property.name,
455
498
  `${
456
499
  parentNode instanceof QueryBuilderExplorerTreeRootNodeData
@@ -461,6 +504,9 @@ export const getQueryBuilderPropertyNodeData = (
461
504
  parentNode.id,
462
505
  isPartOfDerivedPropertyBranch,
463
506
  mappingNodeData,
507
+ // Inorder to cast the properties to the right subType based on what mapping analysis
508
+ // returns we assign the type of the property node to the mapped subClass
509
+ subClass,
464
510
  );
465
511
  if (propertyNode.type instanceof Class) {
466
512
  propertyNode.childrenIds =
@@ -302,6 +302,16 @@ export const addQueryBuilderPropertyNode = (
302
302
  parentExplorerTreeNode.parentId,
303
303
  );
304
304
  }
305
+ if (
306
+ parentExplorerTreeNode instanceof
307
+ QueryBuilderExplorerTreePropertyNodeData &&
308
+ parentExplorerTreeNode.mappingData.entityMappedProperty?.subType &&
309
+ parentExplorerTreeNode.type instanceof Class
310
+ ) {
311
+ subType = PackageableElementExplicitReference.create(
312
+ parentExplorerTreeNode.type,
313
+ );
314
+ }
305
315
  if (
306
316
  parentExplorerTreeNode instanceof QueryBuilderExplorerTreePropertyNodeData
307
317
  ) {
@@ -23,7 +23,6 @@ import {
23
23
  AbstractPropertyExpression,
24
24
  INTERNAL__UnknownValueSpecification,
25
25
  LambdaFunctionInstanceValue,
26
- type PrimitiveInstanceValue,
27
26
  type SimpleFunctionExpression,
28
27
  type ValueSpecification,
29
28
  } from '@finos/legend-graph';
@@ -42,7 +41,7 @@ export abstract class QueryBuilderAggregateCalendarFunction
42
41
  {
43
42
  dateColumn?: AbstractPropertyExpression | undefined;
44
43
  calendarType!: QUERY_BUILDER_CALENDAR_TYPE;
45
- endDate!: PrimitiveInstanceValue;
44
+ endDate!: ValueSpecification;
46
45
  lambdaParameterName: string = DEFAULT_LAMBDA_VARIABLE_NAME;
47
46
 
48
47
  constructor() {
@@ -122,7 +121,7 @@ export abstract class QueryBuilderAggregateCalendarFunction
122
121
  this.calendarType = val;
123
122
  }
124
123
 
125
- setEndDate(val: PrimitiveInstanceValue): void {
124
+ setEndDate(val: ValueSpecification): void {
126
125
  this.endDate = val;
127
126
  }
128
127
 
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import {
18
- type ValueSpecification,
18
+ ValueSpecification,
19
19
  SimpleFunctionExpression,
20
20
  extractElementNameFromPath,
21
21
  matchFunctionName,
@@ -44,7 +44,7 @@ export const buildCalendarFunctionExpression = (
44
44
  calendarFunctionFullPath: string,
45
45
  dateColumn: AbstractPropertyExpression | undefined,
46
46
  calendarType: QUERY_BUILDER_CALENDAR_TYPE,
47
- endDate: PrimitiveInstanceValue,
47
+ endDate: ValueSpecification,
48
48
  targetColumn:
49
49
  | AbstractPropertyExpression
50
50
  | INTERNAL__UnknownValueSpecification,
@@ -165,15 +165,16 @@ export const updateAggregateColumnState = (
165
165
 
166
166
  const endDate = guaranteeType(
167
167
  expression.parametersValues[2],
168
- PrimitiveInstanceValue,
168
+ ValueSpecification,
169
169
  `Can't process ${extractElementNameFromPath(
170
170
  calendarFunctionFullPath,
171
171
  )}() expression: only support ${extractElementNameFromPath(
172
172
  calendarFunctionFullPath,
173
- )}() with third parameter as PrimitiveInstancevalue`,
173
+ )}() with third parameter as ValueSpecification`,
174
174
  );
175
175
  assertTrue(
176
- endDate.genericType.value.rawType.name === PRIMITIVE_TYPE.STRICTDATE ||
176
+ endDate.genericType?.value.rawType.name === PRIMITIVE_TYPE.STRICTDATE ||
177
+ endDate.genericType?.value.rawType.name === PRIMITIVE_TYPE.DATE ||
177
178
  dateColumn.func.value.genericType.value.rawType.name ===
178
179
  PRIMITIVE_TYPE.DATE,
179
180
 
@@ -181,7 +182,7 @@ export const updateAggregateColumnState = (
181
182
  calendarFunctionFullPath,
182
183
  )}() expression: only support ${extractElementNameFromPath(
183
184
  calendarFunctionFullPath,
184
- )}() with third parameter of type StrictDate`,
185
+ )}() with third parameter of type Date`,
185
186
  );
186
187
 
187
188
  calendarFunction.calendarType = calendarTypeParameter