@finos/legend-query-builder 4.5.1 → 4.7.0
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 +1 -0
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderConstantExpressionPanel.js +46 -9
- package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
- package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +1 -1
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
- package/lib/components/shared/BasicValueSpecificationEditor.js +2 -2
- package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
- package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
- package/lib/components/shared/CustomDatePicker.js +6 -2
- package/lib/components/shared/CustomDatePicker.js.map +1 -1
- package/lib/components/shared/LambdaEditor.d.ts +11 -0
- package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
- package/lib/components/shared/LambdaEditor.js +3 -3
- package/lib/components/shared/LambdaEditor.js.map +1 -1
- package/lib/components/shared/QueryBuilderVariableSelector.d.ts +9 -2
- package/lib/components/shared/QueryBuilderVariableSelector.d.ts.map +1 -1
- package/lib/components/shared/QueryBuilderVariableSelector.js +38 -19
- package/lib/components/shared/QueryBuilderVariableSelector.js.map +1 -1
- package/lib/index.css +1 -17
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderConfig.d.ts +2 -1
- package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConfig.js +1 -0
- package/lib/stores/QueryBuilderConfig.js.map +1 -1
- package/lib/stores/QueryBuilderConstantsState.d.ts +26 -2
- package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConstantsState.js +107 -5
- package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
- package/lib/stores/QueryBuilderStateBuilder.d.ts +1 -1
- package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
- package/lib/stores/QueryBuilderStateBuilder.js +9 -4
- package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js +14 -3
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
- package/package.json +5 -5
- package/src/__lib__/QueryBuilderTesting.ts +1 -0
- package/src/components/QueryBuilderConstantExpressionPanel.tsx +95 -13
- package/src/components/QueryBuilderParametersPanel.tsx +0 -1
- package/src/components/QueryBuilderResultPanel.tsx +4 -1
- package/src/components/shared/BasicValueSpecificationEditor.tsx +4 -7
- package/src/components/shared/CustomDatePicker.tsx +6 -7
- package/src/components/shared/LambdaEditor.tsx +4 -2
- package/src/components/shared/QueryBuilderVariableSelector.tsx +192 -83
- package/src/stores/QueryBuilderConfig.ts +1 -0
- package/src/stores/QueryBuilderConstantsState.ts +175 -5
- package/src/stores/QueryBuilderStateBuilder.ts +20 -8
- package/src/stores/QueryBuilderValueSpecificationBuilder.ts +31 -3
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@finos/legend-query-builder",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.7.0",
|
4
4
|
"description": "Legend query builder core",
|
5
5
|
"keywords": [
|
6
6
|
"legend",
|
@@ -42,10 +42,10 @@
|
|
42
42
|
"test:watch": "jest --watch"
|
43
43
|
},
|
44
44
|
"dependencies": {
|
45
|
-
"@finos/legend-application": "15.0.
|
46
|
-
"@finos/legend-art": "7.0.
|
47
|
-
"@finos/legend-graph": "31.2.
|
48
|
-
"@finos/legend-lego": "1.1.
|
45
|
+
"@finos/legend-application": "15.0.41",
|
46
|
+
"@finos/legend-art": "7.0.41",
|
47
|
+
"@finos/legend-graph": "31.2.2",
|
48
|
+
"@finos/legend-lego": "1.1.30",
|
49
49
|
"@finos/legend-server-depot": "6.0.29",
|
50
50
|
"@finos/legend-shared": "10.0.25",
|
51
51
|
"@finos/legend-storage": "3.0.75",
|
@@ -27,6 +27,7 @@ export enum QUERY_BUILDER_TEST_ID {
|
|
27
27
|
QUERY_BUILDER_EXPLORER = 'query__builder__explorer',
|
28
28
|
QUERY_BUILDER_PROPERTY_SEARCH_PANEL = 'query__builder__property__search__panel',
|
29
29
|
QUERY_BUILDER_RESULT_PANEL = 'query__builder__result__panel',
|
30
|
+
QUERY_BUILDER_RESULT_ANALYTICS = 'query__builder__result__analytics',
|
30
31
|
QUERY_BUILDER_PARAMETERS = 'query-builder__parameters',
|
31
32
|
QUERY_BUILDER_CONSTANTS = 'query-builder__constants',
|
32
33
|
}
|
@@ -21,6 +21,7 @@ import {
|
|
21
21
|
} from '@finos/legend-lego/graph-editor';
|
22
22
|
import {
|
23
23
|
BlankPanelPlaceholder,
|
24
|
+
clsx,
|
24
25
|
CustomSelectorInput,
|
25
26
|
Dialog,
|
26
27
|
InfoCircleIcon,
|
@@ -41,23 +42,31 @@ import {
|
|
41
42
|
Multiplicity,
|
42
43
|
isValidIdentifier,
|
43
44
|
} from '@finos/legend-graph';
|
44
|
-
import {
|
45
|
+
import {
|
46
|
+
debounce,
|
47
|
+
generateEnumerableNameFromToken,
|
48
|
+
} from '@finos/legend-shared';
|
45
49
|
import { observer } from 'mobx-react-lite';
|
46
50
|
import { DEFAULT_CONSTANT_VARIABLE_NAME } from '../stores/QueryBuilderConfig.js';
|
47
51
|
import type { QueryBuilderState } from '../stores/QueryBuilderState.js';
|
48
|
-
import {
|
52
|
+
import {
|
53
|
+
type QueryBuilderConstantExpressionState,
|
54
|
+
QueryBuilderSimpleConstantExpressionState,
|
55
|
+
QueryBuilderCalculatedConstantExpressionState,
|
56
|
+
} from '../stores/QueryBuilderConstantsState.js';
|
49
57
|
import { buildDefaultInstanceValue } from '../stores/shared/ValueSpecificationEditorHelper.js';
|
50
58
|
import { BasicValueSpecificationEditor } from './shared/BasicValueSpecificationEditor.js';
|
51
|
-
import { VariableViewer } from './shared/QueryBuilderVariableSelector.js';
|
52
59
|
import { QUERY_BUILDER_TEST_ID } from '../__lib__/QueryBuilderTesting.js';
|
53
60
|
import { QUERY_BUILDER_DOCUMENTATION_KEY } from '../__lib__/QueryBuilderDocumentation.js';
|
54
|
-
import { useState } from 'react';
|
61
|
+
import React, { useMemo, useState } from 'react';
|
55
62
|
import { variableExpression_setName } from '../stores/shared/ValueSpecificationModifierHelper.js';
|
63
|
+
import { LambdaEditor_PopUp } from './shared/LambdaEditor.js';
|
64
|
+
import { VariableViewer } from './shared/QueryBuilderVariableSelector.js';
|
56
65
|
|
57
66
|
// NOTE: We currently only allow constant variables for primitive types of multiplicity ONE.
|
58
67
|
// This is why we don't show multiplicity in the editor.
|
59
|
-
const
|
60
|
-
(props: { constantState:
|
68
|
+
const QueryBuilderSimpleConstantExpressionEditor = observer(
|
69
|
+
(props: { constantState: QueryBuilderSimpleConstantExpressionState }) => {
|
61
70
|
const { constantState } = props;
|
62
71
|
const queryBuilderState = constantState.queryBuilderState;
|
63
72
|
const applicationStore = queryBuilderState.applicationStore;
|
@@ -205,6 +214,35 @@ const QueryBuilderConstantExpressionEditor = observer(
|
|
205
214
|
},
|
206
215
|
);
|
207
216
|
|
217
|
+
const QuerryBuilderCalculatedConstantExpressionEditor = observer(
|
218
|
+
(props: { constantState: QueryBuilderCalculatedConstantExpressionState }) => {
|
219
|
+
const { constantState } = props;
|
220
|
+
const queryBuilderState = constantState.queryBuilderState;
|
221
|
+
const lambdaState = constantState.lambdaState;
|
222
|
+
const closePopUp = (): void =>
|
223
|
+
queryBuilderState.constantState.setSelectedConstant(undefined);
|
224
|
+
const debouncedTransformStringToLambda = useMemo(
|
225
|
+
() =>
|
226
|
+
debounce(() => lambdaState.convertLambdaGrammarStringToObject(), 1000),
|
227
|
+
[lambdaState],
|
228
|
+
);
|
229
|
+
const canDrop = true;
|
230
|
+
return (
|
231
|
+
<>
|
232
|
+
<div className="lambda-editor" />
|
233
|
+
<LambdaEditor_PopUp
|
234
|
+
title={`Edit Constant ${constantState.variable.name}`}
|
235
|
+
className={clsx({ 'lambda-editor--dnd-match': canDrop })}
|
236
|
+
disabled={false}
|
237
|
+
lambdaEditorState={lambdaState}
|
238
|
+
transformStringToLambda={debouncedTransformStringToLambda}
|
239
|
+
onClose={closePopUp}
|
240
|
+
/>
|
241
|
+
</>
|
242
|
+
);
|
243
|
+
},
|
244
|
+
);
|
245
|
+
|
208
246
|
export const QueryBuilderConstantExpressionPanel = observer(
|
209
247
|
(props: { queryBuilderState: QueryBuilderState }) => {
|
210
248
|
const { queryBuilderState } = props;
|
@@ -232,7 +270,7 @@ export const QueryBuilderConstantExpressionPanel = observer(
|
|
232
270
|
Multiplicity.ONE,
|
233
271
|
);
|
234
272
|
variableEx.genericType = defaultVal.genericType;
|
235
|
-
const constState = new
|
273
|
+
const constState = new QueryBuilderSimpleConstantExpressionState(
|
236
274
|
queryBuilderState,
|
237
275
|
variableEx,
|
238
276
|
defaultVal,
|
@@ -241,6 +279,46 @@ export const QueryBuilderConstantExpressionPanel = observer(
|
|
241
279
|
}
|
242
280
|
};
|
243
281
|
|
282
|
+
const renderConstantModal = (
|
283
|
+
val: QueryBuilderConstantExpressionState,
|
284
|
+
): React.ReactNode => {
|
285
|
+
if (val instanceof QueryBuilderSimpleConstantExpressionState) {
|
286
|
+
return (
|
287
|
+
<QueryBuilderSimpleConstantExpressionEditor constantState={val} />
|
288
|
+
);
|
289
|
+
} else if (val instanceof QueryBuilderCalculatedConstantExpressionState) {
|
290
|
+
return (
|
291
|
+
<QuerryBuilderCalculatedConstantExpressionEditor
|
292
|
+
constantState={val}
|
293
|
+
/>
|
294
|
+
);
|
295
|
+
}
|
296
|
+
return null;
|
297
|
+
};
|
298
|
+
const getExtraContextMenu = (
|
299
|
+
val: QueryBuilderConstantExpressionState,
|
300
|
+
):
|
301
|
+
| {
|
302
|
+
key: string;
|
303
|
+
label: string;
|
304
|
+
handler: () => void;
|
305
|
+
}[]
|
306
|
+
| undefined => {
|
307
|
+
if (val instanceof QueryBuilderSimpleConstantExpressionState) {
|
308
|
+
return [
|
309
|
+
{
|
310
|
+
key: 'convert-to-derivation',
|
311
|
+
label: 'Convert To Derivation',
|
312
|
+
handler: () =>
|
313
|
+
constantState.queryBuilderState.constantState.convertToCalculated(
|
314
|
+
val,
|
315
|
+
),
|
316
|
+
},
|
317
|
+
];
|
318
|
+
}
|
319
|
+
return undefined;
|
320
|
+
};
|
321
|
+
|
244
322
|
return (
|
245
323
|
<div
|
246
324
|
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_CONSTANTS}
|
@@ -278,13 +356,20 @@ export const QueryBuilderConstantExpressionPanel = observer(
|
|
278
356
|
key={constState.uuid}
|
279
357
|
queryBuilderState={queryBuilderState}
|
280
358
|
variable={constState.variable}
|
281
|
-
|
359
|
+
value={{
|
360
|
+
val:
|
361
|
+
constState instanceof
|
362
|
+
QueryBuilderSimpleConstantExpressionState
|
363
|
+
? constState.value
|
364
|
+
: undefined,
|
365
|
+
}}
|
282
366
|
actions={{
|
283
367
|
editVariable: () =>
|
284
368
|
constantState.setSelectedConstant(constState),
|
285
369
|
deleteVariable: () =>
|
286
370
|
constantState.removeConstant(constState),
|
287
371
|
}}
|
372
|
+
extraContextMenuActions={getExtraContextMenu(constState)}
|
288
373
|
isReadOnly={isReadOnly}
|
289
374
|
/>
|
290
375
|
))}
|
@@ -300,11 +385,8 @@ export const QueryBuilderConstantExpressionPanel = observer(
|
|
300
385
|
)}
|
301
386
|
</>
|
302
387
|
</div>
|
303
|
-
{constantState.selectedConstant &&
|
304
|
-
|
305
|
-
constantState={constantState.selectedConstant}
|
306
|
-
/>
|
307
|
-
)}
|
388
|
+
{constantState.selectedConstant &&
|
389
|
+
renderConstantModal(constantState.selectedConstant)}
|
308
390
|
</div>
|
309
391
|
);
|
310
392
|
},
|
@@ -1069,7 +1069,10 @@ export const QueryBuilderResultPanel = observer(
|
|
1069
1069
|
</div>
|
1070
1070
|
)}
|
1071
1071
|
|
1072
|
-
<div
|
1072
|
+
<div
|
1073
|
+
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_ANALYTICS}
|
1074
|
+
className="query-builder__result__analytics"
|
1075
|
+
>
|
1073
1076
|
{resultDescription ?? ''}
|
1074
1077
|
</div>
|
1075
1078
|
{executionResult && resultState.checkForStaleResults && (
|
@@ -121,7 +121,7 @@ export const VariableInfoTooltip: React.FC<{
|
|
121
121
|
Type
|
122
122
|
</div>
|
123
123
|
<div className="value-spec-paramater__tooltip__item__value">
|
124
|
-
{type?.name ?? ''}
|
124
|
+
{type?.name ?? '(unknown)'}
|
125
125
|
</div>
|
126
126
|
</div>
|
127
127
|
<div className="value-spec-paramater__tooltip__item">
|
@@ -871,12 +871,9 @@ const CollectionValueInstanceValueEditor = observer(
|
|
871
871
|
onClick={enableEdit}
|
872
872
|
title="Click to edit"
|
873
873
|
>
|
874
|
-
<
|
875
|
-
|
876
|
-
|
877
|
-
value={previewText}
|
878
|
-
disabled={true}
|
879
|
-
/>
|
874
|
+
<div className="value-spec-editor__list-editor__preview">
|
875
|
+
{previewText}
|
876
|
+
</div>
|
880
877
|
<button className="value-spec-editor__list-editor__edit-icon">
|
881
878
|
<PencilIcon />
|
882
879
|
</button>
|
@@ -840,22 +840,21 @@ const AbsoluteTimeValueSpecificationEditor: React.FC<{
|
|
840
840
|
const updateAbsoluteTimeValue: React.ChangeEventHandler<HTMLInputElement> = (
|
841
841
|
event,
|
842
842
|
) => {
|
843
|
+
//
|
844
|
+
const value = new Date(event.target.value).getUTCSeconds()
|
845
|
+
? event.target.value
|
846
|
+
: `${event.target.value}:00`;
|
843
847
|
if (valueSpecification instanceof SimpleFunctionExpression) {
|
844
848
|
setValueSpecification(
|
845
849
|
buildPrimitiveInstanceValue(
|
846
850
|
graph,
|
847
851
|
PRIMITIVE_TYPE.DATETIME,
|
848
|
-
|
852
|
+
value,
|
849
853
|
observerContext,
|
850
854
|
),
|
851
855
|
);
|
852
856
|
} else {
|
853
|
-
instanceValue_setValue(
|
854
|
-
valueSpecification,
|
855
|
-
event.target.value,
|
856
|
-
0,
|
857
|
-
observerContext,
|
858
|
-
);
|
857
|
+
instanceValue_setValue(valueSpecification, value, 0, observerContext);
|
859
858
|
if (
|
860
859
|
valueSpecification.genericType.value.rawType.path !==
|
861
860
|
PRIMITIVE_TYPE.DATETIME
|
@@ -419,8 +419,9 @@ const LambdaEditor_Inner = observer(
|
|
419
419
|
},
|
420
420
|
);
|
421
421
|
|
422
|
-
const LambdaEditor_PopUp = observer(
|
422
|
+
export const LambdaEditor_PopUp = observer(
|
423
423
|
(props: {
|
424
|
+
title?: string | undefined;
|
424
425
|
className?: string | undefined;
|
425
426
|
disabled: boolean;
|
426
427
|
lambdaEditorState: LambdaEditorState;
|
@@ -432,6 +433,7 @@ const LambdaEditor_PopUp = observer(
|
|
432
433
|
disabled,
|
433
434
|
lambdaEditorState,
|
434
435
|
transformStringToLambda,
|
436
|
+
title,
|
435
437
|
onClose,
|
436
438
|
} = props;
|
437
439
|
const applicationStore = useApplicationStore();
|
@@ -607,7 +609,7 @@ const LambdaEditor_PopUp = observer(
|
|
607
609
|
)}
|
608
610
|
>
|
609
611
|
<ModalHeader>
|
610
|
-
<ModalTitle title=
|
612
|
+
<ModalTitle title={title ?? 'Edit Lambda'} />
|
611
613
|
{lambdaEditorState.parserError && (
|
612
614
|
<div className="modal__title__error-badge">
|
613
615
|
Failed to parse lambda
|
@@ -15,18 +15,23 @@
|
|
15
15
|
*/
|
16
16
|
|
17
17
|
import {
|
18
|
+
CalculatorIcon,
|
19
|
+
ContextMenu,
|
18
20
|
DollarIcon,
|
19
21
|
DragPreviewLayer,
|
20
22
|
InfoCircleIcon,
|
23
|
+
MenuContent,
|
24
|
+
MenuContentItem,
|
21
25
|
PanelFormListItems,
|
22
26
|
PencilIcon,
|
23
27
|
TimesIcon,
|
28
|
+
clsx,
|
24
29
|
useDragPreviewLayer,
|
25
30
|
} from '@finos/legend-art';
|
26
31
|
import {
|
27
|
-
SimpleFunctionExpression,
|
28
|
-
type ValueSpecification,
|
29
32
|
type VariableExpression,
|
33
|
+
type ValueSpecification,
|
34
|
+
SimpleFunctionExpression,
|
30
35
|
} from '@finos/legend-graph';
|
31
36
|
import { observer } from 'mobx-react-lite';
|
32
37
|
import { useDrag } from 'react-dnd';
|
@@ -38,41 +43,112 @@ import {
|
|
38
43
|
VariableInfoTooltip,
|
39
44
|
} from './BasicValueSpecificationEditor.js';
|
40
45
|
import { buildDatePickerOption } from './CustomDatePicker.js';
|
46
|
+
import { QueryBuilderSimpleConstantExpressionState } from '../../stores/QueryBuilderConstantsState.js';
|
47
|
+
import { forwardRef, useState } from 'react';
|
41
48
|
|
49
|
+
const CALCULATED = '(calculated)';
|
50
|
+
|
51
|
+
const getNameOfValue = (
|
52
|
+
value: ValueSpecification,
|
53
|
+
queryBuilderState: QueryBuilderState,
|
54
|
+
): string | undefined => {
|
55
|
+
if (value instanceof SimpleFunctionExpression) {
|
56
|
+
const possibleDateLabel = buildDatePickerOption(
|
57
|
+
value,
|
58
|
+
queryBuilderState.applicationStore,
|
59
|
+
).label;
|
60
|
+
if (possibleDateLabel) {
|
61
|
+
return possibleDateLabel;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
return getValueSpecificationStringValue(value);
|
65
|
+
};
|
66
|
+
|
67
|
+
const QueryBuilderVariableContextMenu = observer(
|
68
|
+
forwardRef<
|
69
|
+
HTMLDivElement,
|
70
|
+
{
|
71
|
+
variable: VariableExpression;
|
72
|
+
variableInUse: boolean;
|
73
|
+
actions?:
|
74
|
+
| {
|
75
|
+
editVariable: () => void;
|
76
|
+
deleteVariable: () => void;
|
77
|
+
}
|
78
|
+
| undefined;
|
79
|
+
extraContextMenuActions?:
|
80
|
+
| {
|
81
|
+
key: string;
|
82
|
+
label: string;
|
83
|
+
handler: () => void;
|
84
|
+
}[]
|
85
|
+
| undefined;
|
86
|
+
}
|
87
|
+
>(function QueryBuilderVariableContextMenu(props, ref) {
|
88
|
+
const { actions, extraContextMenuActions, variableInUse } = props;
|
89
|
+
return (
|
90
|
+
<MenuContent ref={ref}>
|
91
|
+
{extraContextMenuActions?.map((action) => (
|
92
|
+
<MenuContentItem onClick={action.handler} key={action.key}>
|
93
|
+
{action.label}
|
94
|
+
</MenuContentItem>
|
95
|
+
))}
|
96
|
+
{actions?.editVariable && (
|
97
|
+
<MenuContentItem onClick={actions.editVariable}>Edit</MenuContentItem>
|
98
|
+
)}
|
99
|
+
{actions?.deleteVariable && (
|
100
|
+
<MenuContentItem
|
101
|
+
disabled={variableInUse}
|
102
|
+
onClick={actions.deleteVariable}
|
103
|
+
>
|
104
|
+
Remove
|
105
|
+
</MenuContentItem>
|
106
|
+
)}
|
107
|
+
</MenuContent>
|
108
|
+
);
|
109
|
+
}),
|
110
|
+
);
|
42
111
|
export const VariableViewer = observer(
|
43
112
|
(props: {
|
44
113
|
variable: VariableExpression;
|
45
114
|
queryBuilderState: QueryBuilderState;
|
46
115
|
isReadOnly: boolean;
|
47
|
-
|
116
|
+
value?: {
|
117
|
+
val: ValueSpecification | undefined;
|
118
|
+
};
|
48
119
|
actions?: {
|
49
120
|
editVariable: () => void;
|
50
121
|
deleteVariable: () => void;
|
51
122
|
};
|
123
|
+
extraContextMenuActions?:
|
124
|
+
| {
|
125
|
+
key: string;
|
126
|
+
label: string;
|
127
|
+
handler: () => void;
|
128
|
+
}[]
|
129
|
+
| undefined;
|
52
130
|
}) => {
|
53
|
-
const {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
const valueString = constantValue
|
70
|
-
? getNameOfValue(constantValue)
|
131
|
+
const {
|
132
|
+
variable,
|
133
|
+
value,
|
134
|
+
actions,
|
135
|
+
isReadOnly,
|
136
|
+
queryBuilderState,
|
137
|
+
extraContextMenuActions,
|
138
|
+
} = props;
|
139
|
+
const isVariableUsed = queryBuilderState.isVariableUsed(variable);
|
140
|
+
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
|
141
|
+
useState(false);
|
142
|
+
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
143
|
+
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
144
|
+
const isConstant = Boolean(value);
|
145
|
+
const constantValueString = value?.val
|
146
|
+
? getNameOfValue(value.val, queryBuilderState)
|
71
147
|
: undefined;
|
72
148
|
const name = variable.name;
|
73
|
-
const
|
74
|
-
|
75
|
-
|
149
|
+
const variableTypeName =
|
150
|
+
variable.genericType?.value.rawType.name ??
|
151
|
+
(isConstant ? CALCULATED : undefined);
|
76
152
|
const deleteDisabled = isReadOnly || isVariableUsed;
|
77
153
|
const deleteTitle = isVariableUsed ? 'Used in query' : 'Remove';
|
78
154
|
const editVariable = (): void => {
|
@@ -81,6 +157,7 @@ export const VariableViewer = observer(
|
|
81
157
|
const deleteVariable = (): void => {
|
82
158
|
actions?.deleteVariable();
|
83
159
|
};
|
160
|
+
|
84
161
|
const [, dragConnector, dragPreviewConnector] = useDrag(
|
85
162
|
() => ({
|
86
163
|
type: QUERY_BUILDER_VARIABLE_DND_TYPE,
|
@@ -92,69 +169,96 @@ export const VariableViewer = observer(
|
|
92
169
|
|
93
170
|
return (
|
94
171
|
<div className="query-builder__variables__variable" ref={dragConnector}>
|
95
|
-
<
|
96
|
-
|
97
|
-
|
172
|
+
<ContextMenu
|
173
|
+
content={
|
174
|
+
<QueryBuilderVariableContextMenu
|
175
|
+
variable={variable}
|
176
|
+
variableInUse={isVariableUsed}
|
177
|
+
actions={actions}
|
178
|
+
extraContextMenuActions={extraContextMenuActions}
|
179
|
+
/>
|
98
180
|
}
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
181
|
+
disabled={isReadOnly || !actions}
|
182
|
+
className={clsx('query-builder__variables__variable__context-menu', {
|
183
|
+
'query-builder__variables__variable--selected-from-context-menu':
|
184
|
+
isSelectedFromContextMenu,
|
185
|
+
})}
|
186
|
+
menuProps={{ elevation: 7 }}
|
187
|
+
onOpen={onContextMenuOpen}
|
188
|
+
onClose={onContextMenuClose}
|
104
189
|
>
|
105
|
-
<
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
190
|
+
<DragPreviewLayer
|
191
|
+
labelGetter={(item: QueryBuilderVariableDragSource): string =>
|
192
|
+
item.variable.name === '' ? '(unknown)' : item.variable.name
|
193
|
+
}
|
194
|
+
types={[QUERY_BUILDER_VARIABLE_DND_TYPE]}
|
195
|
+
/>
|
196
|
+
<div
|
197
|
+
onClick={editVariable}
|
198
|
+
className="query-builder__variables__variable__content"
|
199
|
+
>
|
200
|
+
<div className="query-builder__variables__variable__icon">
|
201
|
+
<div className="query-builder__variables__variable-icon">
|
202
|
+
{isConstant ? (
|
203
|
+
<div className="icon query-builder__variables__variable-icon">
|
204
|
+
C
|
205
|
+
</div>
|
206
|
+
) : (
|
207
|
+
<DollarIcon />
|
208
|
+
)}
|
209
|
+
</div>
|
210
|
+
</div>
|
211
|
+
<div className="query-builder__variables__variable__label">
|
212
|
+
{name}
|
213
|
+
{isConstant ? (
|
214
|
+
<div
|
215
|
+
className={clsx('query-builder__constants__value', {
|
216
|
+
'query-builder__constants__value--icon':
|
217
|
+
!constantValueString,
|
218
|
+
})}
|
219
|
+
>
|
220
|
+
{constantValueString}
|
221
|
+
{!constantValueString && (
|
222
|
+
<CalculatorIcon title="Calculated Constant" />
|
223
|
+
)}
|
110
224
|
</div>
|
111
225
|
) : (
|
112
|
-
<
|
226
|
+
<div className="query-builder__variables__variable__type">
|
227
|
+
<div className="query-builder__variables__variable__type__label">
|
228
|
+
{variableTypeName ?? 'unknown'}
|
229
|
+
</div>
|
230
|
+
</div>
|
113
231
|
)}
|
114
232
|
</div>
|
115
233
|
</div>
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
{
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
234
|
+
{actions && (
|
235
|
+
<div className="query-builder__variables__variable__actions">
|
236
|
+
<button
|
237
|
+
className="query-builder__variables__variable__action"
|
238
|
+
tabIndex={-1}
|
239
|
+
disabled={isReadOnly}
|
240
|
+
onClick={editVariable}
|
241
|
+
title="Edit"
|
242
|
+
>
|
243
|
+
<PencilIcon />
|
244
|
+
</button>
|
245
|
+
<button
|
246
|
+
className="query-builder__variables__variable__action"
|
247
|
+
tabIndex={-1}
|
248
|
+
onClick={deleteVariable}
|
249
|
+
disabled={deleteDisabled}
|
250
|
+
title={deleteTitle}
|
251
|
+
>
|
252
|
+
<TimesIcon />
|
253
|
+
</button>
|
254
|
+
<VariableInfoTooltip variable={variable}>
|
255
|
+
<div className="query-builder__variables__variable__action value-spec-editor__variable__info">
|
256
|
+
<InfoCircleIcon />
|
126
257
|
</div>
|
127
|
-
</
|
128
|
-
|
129
|
-
|
130
|
-
</
|
131
|
-
{actions && (
|
132
|
-
<div className="query-builder__variables__variable__actions">
|
133
|
-
<button
|
134
|
-
className="query-builder__variables__variable__action"
|
135
|
-
tabIndex={-1}
|
136
|
-
disabled={isReadOnly}
|
137
|
-
onClick={editVariable}
|
138
|
-
title="Edit"
|
139
|
-
>
|
140
|
-
<PencilIcon />
|
141
|
-
</button>
|
142
|
-
<button
|
143
|
-
className="query-builder__variables__variable__action"
|
144
|
-
tabIndex={-1}
|
145
|
-
onClick={deleteVariable}
|
146
|
-
disabled={deleteDisabled}
|
147
|
-
title={deleteTitle}
|
148
|
-
>
|
149
|
-
<TimesIcon />
|
150
|
-
</button>
|
151
|
-
<VariableInfoTooltip variable={variable}>
|
152
|
-
<div className="query-builder__variables__variable__action value-spec-editor__variable__info">
|
153
|
-
<InfoCircleIcon />
|
154
|
-
</div>
|
155
|
-
</VariableInfoTooltip>
|
156
|
-
</div>
|
157
|
-
)}
|
258
|
+
</VariableInfoTooltip>
|
259
|
+
</div>
|
260
|
+
)}
|
261
|
+
</ContextMenu>
|
158
262
|
</div>
|
159
263
|
);
|
160
264
|
},
|
@@ -166,7 +270,6 @@ export const VariableSelector = observer(
|
|
166
270
|
filterBy?: (variableExpression: VariableExpression) => boolean;
|
167
271
|
}) => {
|
168
272
|
const { queryBuilderState, filterBy } = props;
|
169
|
-
const isReadOnly = !queryBuilderState.isQuerySupported;
|
170
273
|
const filteredParameterStates =
|
171
274
|
queryBuilderState.parametersState.parameterStates.filter((p) =>
|
172
275
|
filterBy ? filterBy(p.parameter) : true,
|
@@ -186,7 +289,7 @@ export const VariableSelector = observer(
|
|
186
289
|
<VariableViewer
|
187
290
|
key={pState.uuid}
|
188
291
|
variable={pState.parameter}
|
189
|
-
isReadOnly={
|
292
|
+
isReadOnly={true}
|
190
293
|
queryBuilderState={queryBuilderState}
|
191
294
|
/>
|
192
295
|
))}
|
@@ -197,9 +300,15 @@ export const VariableSelector = observer(
|
|
197
300
|
<VariableViewer
|
198
301
|
key={constantState.uuid}
|
199
302
|
variable={constantState.variable}
|
200
|
-
|
303
|
+
value={{
|
304
|
+
val:
|
305
|
+
constantState instanceof
|
306
|
+
QueryBuilderSimpleConstantExpressionState
|
307
|
+
? constantState.value
|
308
|
+
: undefined,
|
309
|
+
}}
|
201
310
|
queryBuilderState={queryBuilderState}
|
202
|
-
isReadOnly={
|
311
|
+
isReadOnly={true}
|
203
312
|
/>
|
204
313
|
))}
|
205
314
|
</PanelFormListItems>
|