@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.
- package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
- package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +2 -0
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +38 -33
- package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +12 -5
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/index.css +16 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderState.d.ts +6 -1
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +3 -0
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts +17 -6
- package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryFunctionsExplorerState.js +142 -59
- package/lib/stores/explorer/QueryFunctionsExplorerState.js.map +1 -1
- package/package.json +6 -6
- package/src/__lib__/QueryBuilderTesting.ts +2 -0
- package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +63 -70
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +23 -11
- package/src/index.ts +1 -0
- package/src/stores/QueryBuilderState.ts +12 -0
- 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
|
-
|
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
|
-
|
69
|
-
|
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 {
|
77
|
-
const documentation =
|
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
|
-
{
|
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
|
-
{
|
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
|
-
{
|
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
|
-
|
152
|
-
|
153
|
-
|
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
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
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 =
|
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.
|
293
|
-
ConcreteFunctionDefinition && (
|
287
|
+
{node.functionAnalysisInfo && (
|
294
288
|
<QueryBuilderFunctionInfoTooltip
|
295
|
-
|
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
|
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
|
-
|
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
|
-
|
506
|
-
|
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.
|
525
|
-
|
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
|
-
|
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.
|
549
|
-
|
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
|
-
|
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
|
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
|
-
}${
|
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}${
|
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,
|