@finos/legend-query-builder 4.15.3 → 4.15.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +2 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
  6. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +38 -33
  7. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +12 -5
  10. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  11. package/lib/index.css +16 -0
  12. package/lib/index.d.ts +1 -1
  13. package/lib/index.d.ts.map +1 -1
  14. package/lib/index.js.map +1 -1
  15. package/lib/package.json +1 -1
  16. package/lib/stores/QueryBuilderState.d.ts +6 -1
  17. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  18. package/lib/stores/QueryBuilderState.js +3 -0
  19. package/lib/stores/QueryBuilderState.js.map +1 -1
  20. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts +17 -6
  21. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts.map +1 -1
  22. package/lib/stores/explorer/QueryFunctionsExplorerState.js +142 -59
  23. package/lib/stores/explorer/QueryFunctionsExplorerState.js.map +1 -1
  24. package/package.json +6 -6
  25. package/src/__lib__/QueryBuilderTesting.ts +2 -0
  26. package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +63 -70
  27. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +23 -11
  28. package/src/index.ts +1 -0
  29. package/src/stores/QueryBuilderState.ts +12 -0
  30. package/src/stores/explorer/QueryFunctionsExplorerState.ts +227 -94
@@ -44,16 +44,14 @@ import {
44
44
  import {
45
45
  type QueryBuilderFunctionsExplorerTreeNodeData,
46
46
  type QueryBuilderFunctionsExplorerDragSource,
47
- generateFunctionsExplorerTreeNodeData,
48
47
  getFunctionsExplorerTreeNodeChildren,
49
48
  QUERY_BUILDER_FUNCTION_DND_TYPE,
49
+ generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo,
50
50
  } from '../../stores/explorer/QueryFunctionsExplorerState.js';
51
51
  import { useDrag } from 'react-dnd';
52
52
  import {
53
- ConcreteFunctionDefinition,
54
- generateFunctionPrettyName,
53
+ type FunctionAnalysisInfo,
55
54
  getElementRootPackage,
56
- Package,
57
55
  ROOT_PACKAGE_NAME,
58
56
  getMultiplicityDescription,
59
57
  CORE_PURE_PATH,
@@ -61,20 +59,22 @@ import {
61
59
  } from '@finos/legend-graph';
62
60
  import type { QueryBuilderState } from '../../stores/QueryBuilderState.js';
63
61
  import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
62
+ import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
64
63
 
65
64
  const isDependencyTreeNode = (
66
65
  node: QueryBuilderFunctionsExplorerTreeNodeData,
67
66
  ): boolean =>
68
- getElementRootPackage(node.packageableElement).name ===
69
- ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT;
67
+ node.package !== undefined &&
68
+ getElementRootPackage(node.package).name ===
69
+ ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT;
70
70
 
71
71
  const QueryBuilderFunctionInfoTooltip: React.FC<{
72
- element: ConcreteFunctionDefinition;
73
72
  children: React.ReactElement;
74
73
  placement?: TooltipPlacement | undefined;
74
+ functionInfo: FunctionAnalysisInfo;
75
75
  }> = (props) => {
76
- const { element, children, placement } = props;
77
- const documentation = element.taggedValues
76
+ const { children, placement, functionInfo } = props;
77
+ const documentation = functionInfo.taggedValues
78
78
  .filter(
79
79
  (taggedValue) =>
80
80
  taggedValue.tag.ownerReference.value.path ===
@@ -83,6 +83,23 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
83
83
  )
84
84
  .map((taggedValue) => taggedValue.value);
85
85
 
86
+ const generateParameterCallString = (): string => {
87
+ if (
88
+ functionInfo.parameterInfoList.length &&
89
+ functionInfo.parameterInfoList.length > 0
90
+ ) {
91
+ return functionInfo.parameterInfoList
92
+ .map(
93
+ (param) =>
94
+ `${param.name}: ${
95
+ param.type
96
+ }${getMultiplicityDescription(param.multiplicity)}`,
97
+ )
98
+ .join('; ');
99
+ }
100
+ return '';
101
+ };
102
+
86
103
  return (
87
104
  <Tooltip
88
105
  arrow={true}
@@ -102,7 +119,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
102
119
  Function Name
103
120
  </div>
104
121
  <div className="query-builder__tooltip__item__value">
105
- {element.path}
122
+ {functionInfo.functionPath}
106
123
  </div>
107
124
  </div>
108
125
  <div className="query-builder__tooltip__item">
@@ -110,14 +127,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
110
127
  Parameters
111
128
  </div>
112
129
  <div className="query-builder__tooltip__item__value">
113
- {element.parameters
114
- .map(
115
- (param) =>
116
- `${param.name}: ${
117
- param.type.value.name
118
- }${getMultiplicityDescription(param.multiplicity)}`,
119
- )
120
- .join('; ')}
130
+ {generateParameterCallString()}
121
131
  </div>
122
132
  </div>
123
133
  {Boolean(documentation.length) && (
@@ -135,7 +145,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
135
145
  Return Type
136
146
  </div>
137
147
  <div className="query-builder__tooltip__item__value">
138
- {element.returnType.value.name}
148
+ {functionInfo.returnType}
139
149
  </div>
140
150
  </div>
141
151
  </div>
@@ -147,20 +157,10 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
147
157
  };
148
158
 
149
159
  const QueryBuilderFunctionsExplorerListEntry = observer(
150
- (props: {
151
- queryBuilderState: QueryBuilderState;
152
- element: ConcreteFunctionDefinition;
153
- rootPackageName: ROOT_PACKAGE_NAME;
154
- }) => {
155
- const { queryBuilderState, element, rootPackageName } = props;
156
- const node = generateFunctionsExplorerTreeNodeData(
157
- queryBuilderState,
158
- element,
159
- rootPackageName,
160
- );
161
- const functionPrettyName = generateFunctionPrettyName(element, {
162
- fullPath: true,
163
- });
160
+ (props: { element: FunctionAnalysisInfo }) => {
161
+ const { element } = props;
162
+ const node =
163
+ generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo(element);
164
164
  const [, dragConnector, dragPreviewConnector] = useDrag(
165
165
  () => ({
166
166
  type: QUERY_BUILDER_FUNCTION_DND_TYPE,
@@ -183,15 +183,13 @@ const QueryBuilderFunctionsExplorerListEntry = observer(
183
183
  </div>
184
184
  <div
185
185
  className="query-builder__functions-explorer__function__label"
186
- title={functionPrettyName}
186
+ title={element.functionPrettyName}
187
187
  >
188
- {functionPrettyName}
188
+ {element.functionPrettyName}
189
189
  </div>
190
190
  </div>
191
191
  <div className="query-builder__functions-explorer__function__actions">
192
- <QueryBuilderFunctionInfoTooltip
193
- element={node.packageableElement as ConcreteFunctionDefinition}
194
- >
192
+ <QueryBuilderFunctionInfoTooltip functionInfo={element}>
195
193
  <div className="query-builder__functions-explorer__function__action query-builder__functions-explorer__function__node__info">
196
194
  <InfoCircleIcon />
197
195
  </div>
@@ -212,11 +210,11 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
212
210
  >,
213
211
  ) => {
214
212
  const { node, level, stepPaddingInRem, onNodeSelect } = props;
215
- const isPackage = node.packageableElement instanceof Package;
216
- const name =
217
- node.packageableElement instanceof ConcreteFunctionDefinition
218
- ? generateFunctionPrettyName(node.packageableElement)
219
- : node.packageableElement.name;
213
+ const name = node.functionAnalysisInfo
214
+ ? node.functionAnalysisInfo.functionPrettyName.split(
215
+ `${node.functionAnalysisInfo.packagePath}::`,
216
+ )[1]
217
+ : (node.package?.name ?? '');
220
218
  const isExpandable = Boolean(node.childrenIds.length);
221
219
  const nodeExpandIcon = isExpandable ? (
222
220
  node.isOpen ? (
@@ -231,7 +229,7 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
231
229
  const iconPackageColor = isDependencyTreeNode(node)
232
230
  ? 'color--dependency'
233
231
  : '';
234
- const nodeTypeIcon = isPackage ? (
232
+ const nodeTypeIcon = node.package ? (
235
233
  node.isOpen ? (
236
234
  <FolderOpenIcon className={iconPackageColor} />
237
235
  ) : (
@@ -248,10 +246,7 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
248
246
  }>(
249
247
  () => ({
250
248
  type: QUERY_BUILDER_FUNCTION_DND_TYPE,
251
- item: () =>
252
- node.packageableElement instanceof ConcreteFunctionDefinition
253
- ? { node }
254
- : {},
249
+ item: () => (node.functionAnalysisInfo ? { node } : {}),
255
250
  }),
256
251
  [node],
257
252
  );
@@ -289,10 +284,9 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
289
284
  {name}
290
285
  </div>
291
286
  <div className="query-builder__functions-explorer__tree__node__actions">
292
- {node.packageableElement instanceof
293
- ConcreteFunctionDefinition && (
287
+ {node.functionAnalysisInfo && (
294
288
  <QueryBuilderFunctionInfoTooltip
295
- element={node.packageableElement}
289
+ functionInfo={node.functionAnalysisInfo}
296
290
  >
297
291
  <div className="query-builder__functions-explorer__tree__node__action query-builder__functions-explorer__tree__node__info">
298
292
  <InfoCircleIcon />
@@ -331,6 +325,7 @@ const QueryBuilderPackableElementExplorerTree = observer(
331
325
  const dependencyTreeData = queryFunctionsState.getTreeData(
332
326
  ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT,
333
327
  );
328
+
334
329
  const onDependencyTreeSelect = (
335
330
  node: QueryBuilderFunctionsExplorerTreeNodeData,
336
331
  ): void => {
@@ -431,6 +426,10 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
431
426
  setShowDependencyFuncions(!showDependencyFuncions);
432
427
  };
433
428
 
429
+ useEffect(() => {
430
+ queryFunctionsState.initializeTreeData();
431
+ }, [queryFunctionsState]);
432
+
434
433
  useEffect(() => {
435
434
  QueryBuilderTelemetryHelper.logEvent_RenderPanelFunctionExplorer(
436
435
  queryBuilderState.applicationStore.telemetryService,
@@ -438,7 +437,10 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
438
437
  }, [queryBuilderState.applicationStore]);
439
438
 
440
439
  return (
441
- <div className="panel query-builder__functions-explorer">
440
+ <div
441
+ data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FUNCTIONS}
442
+ className="panel query-builder__functions-explorer"
443
+ >
442
444
  <div className="panel__header">
443
445
  <div className="panel__header__title">
444
446
  <div className="panel__header__title__label">functions</div>
@@ -494,16 +496,13 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
494
496
  labelGetter={(
495
497
  item: QueryBuilderFunctionsExplorerDragSource,
496
498
  ): string =>
497
- generateFunctionPrettyName(
498
- item.node.packageableElement as ConcreteFunctionDefinition,
499
- { fullPath: true },
500
- )
499
+ item.node.functionAnalysisInfo?.functionPrettyName ?? ''
501
500
  }
502
501
  types={[QUERY_BUILDER_FUNCTION_DND_TYPE]}
503
502
  />
504
503
  {((showDependencyFuncions &&
505
- (!queryFunctionsState.dependencyTreeData ||
506
- queryFunctionsState.dependencyTreeData.rootIds.length === 0)) ||
504
+ queryFunctionsState.dependencyFunctionExplorerStates.length ===
505
+ 0) ||
507
506
  !showDependencyFuncions) &&
508
507
  queryFunctionsState.treeData?.rootIds.length === 0 && (
509
508
  <BlankPanelContent>
@@ -521,8 +520,8 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
521
520
  />
522
521
  )}
523
522
  {showDependencyFuncions &&
524
- queryFunctionsState.dependencyTreeData &&
525
- queryFunctionsState.dependencyTreeData.rootIds.length !== 0 && (
523
+ queryFunctionsState.dependencyFunctionExplorerStates.length !==
524
+ 0 && (
526
525
  <QueryBuilderPackableElementExplorerTree
527
526
  queryBuilderState={queryBuilderState}
528
527
  rootPackageName={ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT}
@@ -538,15 +537,13 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
538
537
  (funcExplorerState) => (
539
538
  <QueryBuilderFunctionsExplorerListEntry
540
539
  key={funcExplorerState.uuid}
541
- queryBuilderState={queryBuilderState}
542
- element={funcExplorerState.concreteFunctionDefinition}
543
- rootPackageName={ROOT_PACKAGE_NAME.MAIN}
540
+ element={funcExplorerState.functionAnalysisInfo}
544
541
  />
545
542
  ),
546
543
  )}
547
544
  {showDependencyFuncions &&
548
- queryFunctionsState.dependencyTreeData &&
549
- queryFunctionsState.dependencyTreeData.rootIds.length !== 0 && (
545
+ queryFunctionsState.dependencyFunctionExplorerStates.length >
546
+ 0 && (
550
547
  <>
551
548
  {queryFunctionsState.treeData?.rootIds.length !== 0 && (
552
549
  <div className="query-builder__functions-explorer__separator" />
@@ -555,11 +552,7 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
555
552
  (funcExplorerState) => (
556
553
  <QueryBuilderFunctionsExplorerListEntry
557
554
  key={funcExplorerState.uuid}
558
- queryBuilderState={queryBuilderState}
559
- element={funcExplorerState.concreteFunctionDefinition}
560
- rootPackageName={
561
- ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT
562
- }
555
+ element={funcExplorerState.functionAnalysisInfo}
563
556
  />
564
557
  ),
565
558
  )}
@@ -71,8 +71,7 @@ import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
71
71
  import { flowResult } from 'mobx';
72
72
  import { useApplicationStore } from '@finos/legend-application';
73
73
  import {
74
- type ConcreteFunctionDefinition,
75
- generateFunctionCallString,
74
+ type ValueSpecification,
76
75
  LAMBDA_PIPE,
77
76
  VARIABLE_REFERENCE_TOKEN,
78
77
  AbstractPropertyExpression,
@@ -81,12 +80,12 @@ import {
81
80
  PropertyExplicitReference,
82
81
  VariableExpression,
83
82
  Multiplicity,
84
- type ValueSpecification,
85
83
  PrimitiveType,
86
84
  GenericType,
87
85
  GenericTypeExplicitReference,
88
86
  observe_PrimitiveInstanceValue,
89
87
  PrimitiveInstanceValue,
88
+ generateFunctionCallStringFromFunctionAnalysisInfo,
90
89
  } from '@finos/legend-graph';
91
90
  import {
92
91
  type QueryBuilderFunctionsExplorerDragSource,
@@ -239,13 +238,20 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
239
238
  }`,
240
239
  );
241
240
  } else if (type === QUERY_BUILDER_FUNCTION_DND_TYPE) {
241
+ const functionAnalysisInfo = (
242
+ item as QueryBuilderFunctionsExplorerDragSource
243
+ ).node.functionAnalysisInfo;
244
+ const functionPrettyName = functionAnalysisInfo
245
+ ? generateFunctionCallStringFromFunctionAnalysisInfo(
246
+ projectionColumnState.tdsState.queryBuilderState
247
+ .graphManagerState.graph,
248
+ functionAnalysisInfo,
249
+ )
250
+ : '';
242
251
  projectionColumnState.derivationLambdaEditorState.setLambdaString(
243
252
  `${
244
253
  projectionColumnState.derivationLambdaEditorState.lambdaString
245
- }${`${generateFunctionCallString(
246
- (item as QueryBuilderFunctionsExplorerDragSource).node
247
- .packageableElement as ConcreteFunctionDefinition,
248
- )}`}`,
254
+ }${functionPrettyName}`,
249
255
  );
250
256
  } else {
251
257
  projectionColumnState.derivationLambdaEditorState.setLambdaString(
@@ -1262,11 +1268,17 @@ export const QueryBuilderTDSPanel = observer(
1262
1268
  { addDummyParameter: true },
1263
1269
  ),
1264
1270
  );
1271
+ const functionAnalysisInfo = (
1272
+ item as QueryBuilderFunctionsExplorerDragSource
1273
+ ).node.functionAnalysisInfo;
1274
+ const functionPrettyName = functionAnalysisInfo
1275
+ ? generateFunctionCallStringFromFunctionAnalysisInfo(
1276
+ tdsState.queryBuilderState.graphManagerState.graph,
1277
+ functionAnalysisInfo,
1278
+ )
1279
+ : '';
1265
1280
  derivationProjectionColumn.derivationLambdaEditorState.setLambdaString(
1266
- `${DEFAULT_LAMBDA_VARIABLE_NAME}${LAMBDA_PIPE}${generateFunctionCallString(
1267
- (item as QueryBuilderFunctionsExplorerDragSource).node
1268
- .packageableElement as ConcreteFunctionDefinition,
1269
- )}`,
1281
+ `${DEFAULT_LAMBDA_VARIABLE_NAME}${LAMBDA_PIPE}${functionPrettyName} `,
1270
1282
  );
1271
1283
  tdsState.addColumn(derivationProjectionColumn);
1272
1284
  break;
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ export { QueryBuilder } from './components/QueryBuilder.js';
34
34
  export { QUERY_BUILDER_COMPONENT_ELEMENT_ID } from './components/QueryBuilderComponentElement.js';
35
35
  export {
36
36
  type QueryableSourceInfo as QuerySDLC,
37
+ type QueryBuilderExtraFunctionAnalysisInfo,
37
38
  QueryBuilderState,
38
39
  QUERY_BUILDER_LAMBDA_WRITER_MODE,
39
40
  INTERNAL__BasicQueryBuilderState,
@@ -56,6 +56,7 @@ import {
56
56
  type Type,
57
57
  type QueryGridConfig,
58
58
  type QueryExecutionContext,
59
+ type FunctionAnalysisInfo,
59
60
  GRAPH_MANAGER_EVENT,
60
61
  CompilationError,
61
62
  extractSourceInformationCoordinates,
@@ -117,6 +118,11 @@ export type QueryableClassMappingRuntimeInfo = QueryableSourceInfo & {
117
118
  runtime: string;
118
119
  };
119
120
 
121
+ export type QueryBuilderExtraFunctionAnalysisInfo = {
122
+ functionInfoMap: Map<string, FunctionAnalysisInfo>;
123
+ dependencyFunctionInfoMap: Map<string, FunctionAnalysisInfo>;
124
+ };
125
+
120
126
  export enum QUERY_BUILDER_LAMBDA_WRITER_MODE {
121
127
  STANDARD = 'STANDARD',
122
128
  TYPED_FETCH_STRUCTURE = 'TYPED_FETCH_STRUCTURE',
@@ -832,6 +838,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
832
838
  );
833
839
  }
834
840
 
841
+ buildFunctionAnalysisInfo():
842
+ | QueryBuilderExtraFunctionAnalysisInfo
843
+ | undefined {
844
+ return undefined;
845
+ }
846
+
835
847
  /**
836
848
  * This method can be used to simplify the current query builder state
837
849
  * to a basic one that can be used for testing or some special operations,