@finos/legend-query-builder 4.5.1 → 4.7.0
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.
- 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>
|