@finos/legend-query-builder 4.9.2 → 4.9.4

Sign up to get free protection for your applications and to get access to all the features.
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