@finos/legend-query-builder 4.6.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderConstantExpressionPanel.js +39 -9
  3. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  4. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  5. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  6. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  7. package/lib/components/shared/BasicValueSpecificationEditor.js +1 -1
  8. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  9. package/lib/components/shared/LambdaEditor.d.ts +11 -0
  10. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  11. package/lib/components/shared/LambdaEditor.js +3 -3
  12. package/lib/components/shared/LambdaEditor.js.map +1 -1
  13. package/lib/components/shared/QueryBuilderVariableSelector.d.ts +9 -2
  14. package/lib/components/shared/QueryBuilderVariableSelector.d.ts.map +1 -1
  15. package/lib/components/shared/QueryBuilderVariableSelector.js +39 -28
  16. package/lib/components/shared/QueryBuilderVariableSelector.js.map +1 -1
  17. package/lib/index.css +1 -17
  18. package/lib/index.css.map +1 -1
  19. package/lib/package.json +1 -1
  20. package/lib/stores/QueryBuilderConfig.d.ts +2 -1
  21. package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
  22. package/lib/stores/QueryBuilderConfig.js +1 -0
  23. package/lib/stores/QueryBuilderConfig.js.map +1 -1
  24. package/lib/stores/QueryBuilderConstantsState.d.ts +23 -6
  25. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  26. package/lib/stores/QueryBuilderConstantsState.js +96 -9
  27. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  28. package/lib/stores/QueryBuilderStateBuilder.js +1 -1
  29. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  30. package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
  31. package/lib/stores/QueryBuilderValueSpecificationBuilder.js +14 -4
  32. package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
  33. package/package.json +5 -5
  34. package/src/components/QueryBuilderConstantExpressionPanel.tsx +79 -6
  35. package/src/components/QueryBuilderParametersPanel.tsx +0 -1
  36. package/src/components/shared/BasicValueSpecificationEditor.tsx +3 -6
  37. package/src/components/shared/LambdaEditor.tsx +4 -2
  38. package/src/components/shared/QueryBuilderVariableSelector.tsx +191 -93
  39. package/src/stores/QueryBuilderConfig.ts +1 -0
  40. package/src/stores/QueryBuilderConstantsState.ts +146 -10
  41. package/src/stores/QueryBuilderStateBuilder.ts +1 -1
  42. package/src/stores/QueryBuilderValueSpecificationBuilder.ts +31 -3
@@ -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,25 +42,30 @@ import {
41
42
  Multiplicity,
42
43
  isValidIdentifier,
43
44
  } from '@finos/legend-graph';
44
- import { generateEnumerableNameFromToken } from '@finos/legend-shared';
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
52
  import {
49
53
  type QueryBuilderConstantExpressionState,
50
54
  QueryBuilderSimpleConstantExpressionState,
55
+ QueryBuilderCalculatedConstantExpressionState,
51
56
  } from '../stores/QueryBuilderConstantsState.js';
52
57
  import { buildDefaultInstanceValue } from '../stores/shared/ValueSpecificationEditorHelper.js';
53
58
  import { BasicValueSpecificationEditor } from './shared/BasicValueSpecificationEditor.js';
54
- import { VariableViewer } from './shared/QueryBuilderVariableSelector.js';
55
59
  import { QUERY_BUILDER_TEST_ID } from '../__lib__/QueryBuilderTesting.js';
56
60
  import { QUERY_BUILDER_DOCUMENTATION_KEY } from '../__lib__/QueryBuilderDocumentation.js';
57
- import React, { useState } from 'react';
61
+ import React, { useMemo, useState } from 'react';
58
62
  import { variableExpression_setName } from '../stores/shared/ValueSpecificationModifierHelper.js';
63
+ import { LambdaEditor_PopUp } from './shared/LambdaEditor.js';
64
+ import { VariableViewer } from './shared/QueryBuilderVariableSelector.js';
59
65
 
60
66
  // NOTE: We currently only allow constant variables for primitive types of multiplicity ONE.
61
67
  // This is why we don't show multiplicity in the editor.
62
- const QueryBuilderConstantExpressionEditor = observer(
68
+ const QueryBuilderSimpleConstantExpressionEditor = observer(
63
69
  (props: { constantState: QueryBuilderSimpleConstantExpressionState }) => {
64
70
  const { constantState } = props;
65
71
  const queryBuilderState = constantState.queryBuilderState;
@@ -208,6 +214,35 @@ const QueryBuilderConstantExpressionEditor = observer(
208
214
  },
209
215
  );
210
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
+
211
246
  export const QueryBuilderConstantExpressionPanel = observer(
212
247
  (props: { queryBuilderState: QueryBuilderState }) => {
213
248
  const { queryBuilderState } = props;
@@ -248,10 +283,41 @@ export const QueryBuilderConstantExpressionPanel = observer(
248
283
  val: QueryBuilderConstantExpressionState,
249
284
  ): React.ReactNode => {
250
285
  if (val instanceof QueryBuilderSimpleConstantExpressionState) {
251
- return <QueryBuilderConstantExpressionEditor constantState={val} />;
286
+ return (
287
+ <QueryBuilderSimpleConstantExpressionEditor constantState={val} />
288
+ );
289
+ } else if (val instanceof QueryBuilderCalculatedConstantExpressionState) {
290
+ return (
291
+ <QuerryBuilderCalculatedConstantExpressionEditor
292
+ constantState={val}
293
+ />
294
+ );
252
295
  }
253
296
  return null;
254
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
+ };
255
321
 
256
322
  return (
257
323
  <div
@@ -290,13 +356,20 @@ export const QueryBuilderConstantExpressionPanel = observer(
290
356
  key={constState.uuid}
291
357
  queryBuilderState={queryBuilderState}
292
358
  variable={constState.variable}
293
- constantValue={constState.value}
359
+ value={{
360
+ val:
361
+ constState instanceof
362
+ QueryBuilderSimpleConstantExpressionState
363
+ ? constState.value
364
+ : undefined,
365
+ }}
294
366
  actions={{
295
367
  editVariable: () =>
296
368
  constantState.setSelectedConstant(constState),
297
369
  deleteVariable: () =>
298
370
  constantState.removeConstant(constState),
299
371
  }}
372
+ extraContextMenuActions={getExtraContextMenu(constState)}
300
373
  isReadOnly={isReadOnly}
301
374
  />
302
375
  ))}
@@ -266,7 +266,6 @@ export const QueryBuilderParametersPanel = observer(
266
266
  parmaterState.mockParameterValue();
267
267
  }
268
268
  };
269
-
270
269
  return (
271
270
  <div
272
271
  data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PARAMETERS}
@@ -871,12 +871,9 @@ const CollectionValueInstanceValueEditor = observer(
871
871
  onClick={enableEdit}
872
872
  title="Click to edit"
873
873
  >
874
- <input
875
- className="value-spec-editor__list-editor__preview"
876
- spellCheck={false}
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>
@@ -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="Edit Lambda" />
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,19 +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 {
32
+ type VariableExpression,
27
33
  type ValueSpecification,
28
34
  SimpleFunctionExpression,
29
- type VariableExpression,
30
- INTERNAL__UnknownValueSpecification,
31
35
  } from '@finos/legend-graph';
32
36
  import { observer } from 'mobx-react-lite';
33
37
  import { useDrag } from 'react-dnd';
@@ -39,59 +43,121 @@ import {
39
43
  VariableInfoTooltip,
40
44
  } from './BasicValueSpecificationEditor.js';
41
45
  import { buildDatePickerOption } from './CustomDatePicker.js';
46
+ import { QueryBuilderSimpleConstantExpressionState } from '../../stores/QueryBuilderConstantsState.js';
47
+ import { forwardRef, useState } from 'react';
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
+ };
42
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
+ );
43
111
  export const VariableViewer = observer(
44
112
  (props: {
45
113
  variable: VariableExpression;
46
114
  queryBuilderState: QueryBuilderState;
47
115
  isReadOnly: boolean;
48
- constantValue?: ValueSpecification | undefined;
116
+ value?: {
117
+ val: ValueSpecification | undefined;
118
+ };
49
119
  actions?: {
50
120
  editVariable: () => void;
51
121
  deleteVariable: () => void;
52
122
  };
123
+ extraContextMenuActions?:
124
+ | {
125
+ key: string;
126
+ label: string;
127
+ handler: () => void;
128
+ }[]
129
+ | undefined;
53
130
  }) => {
54
- const { variable, constantValue, actions, isReadOnly, queryBuilderState } =
55
- props;
56
-
57
- const getNameOfValue = (value: ValueSpecification): string | undefined => {
58
- if (value instanceof SimpleFunctionExpression) {
59
- const possibleDateLabel = buildDatePickerOption(
60
- value,
61
- queryBuilderState.applicationStore,
62
- ).label;
63
- if (possibleDateLabel) {
64
- return possibleDateLabel;
65
- }
66
- } else if (value instanceof INTERNAL__UnknownValueSpecification) {
67
- return '(calculated)';
68
- }
69
- return getValueSpecificationStringValue(value);
70
- };
71
- const constantValueString = constantValue
72
- ? 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)
73
147
  : undefined;
74
148
  const name = variable.name;
75
- const variableType = variable.genericType?.value.rawType;
76
- const typeName = variableType?.name;
77
- const isVariableUsed = queryBuilderState.isVariableUsed(variable);
149
+ const variableTypeName =
150
+ variable.genericType?.value.rawType.name ??
151
+ (isConstant ? CALCULATED : undefined);
78
152
  const deleteDisabled = isReadOnly || isVariableUsed;
79
153
  const deleteTitle = isVariableUsed ? 'Used in query' : 'Remove';
80
-
81
- const isEditDisabled =
82
- isReadOnly ||
83
- constantValue instanceof INTERNAL__UnknownValueSpecification;
84
-
85
- const editMessage =
86
- constantValue instanceof INTERNAL__UnknownValueSpecification
87
- ? 'Calculated constants can only be edited via text mode'
88
- : 'Edit';
89
154
  const editVariable = (): void => {
90
155
  actions?.editVariable();
91
156
  };
92
157
  const deleteVariable = (): void => {
93
158
  actions?.deleteVariable();
94
159
  };
160
+
95
161
  const [, dragConnector, dragPreviewConnector] = useDrag(
96
162
  () => ({
97
163
  type: QUERY_BUILDER_VARIABLE_DND_TYPE,
@@ -103,69 +169,96 @@ export const VariableViewer = observer(
103
169
 
104
170
  return (
105
171
  <div className="query-builder__variables__variable" ref={dragConnector}>
106
- <DragPreviewLayer
107
- labelGetter={(item: QueryBuilderVariableDragSource): string =>
108
- item.variable.name === '' ? '(unknown)' : item.variable.name
172
+ <ContextMenu
173
+ content={
174
+ <QueryBuilderVariableContextMenu
175
+ variable={variable}
176
+ variableInUse={isVariableUsed}
177
+ actions={actions}
178
+ extraContextMenuActions={extraContextMenuActions}
179
+ />
109
180
  }
110
- types={[QUERY_BUILDER_VARIABLE_DND_TYPE]}
111
- />
112
- <div
113
- onClick={editVariable}
114
- className="query-builder__variables__variable__content"
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}
115
189
  >
116
- <div className="query-builder__variables__variable__icon">
117
- <div className="query-builder__variables__variable-icon">
118
- {constantValue ? (
119
- <div className="icon query-builder__variables__variable-icon">
120
- C
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
+ )}
121
224
  </div>
122
225
  ) : (
123
- <DollarIcon />
226
+ <div className="query-builder__variables__variable__type">
227
+ <div className="query-builder__variables__variable__type__label">
228
+ {variableTypeName ?? 'unknown'}
229
+ </div>
230
+ </div>
124
231
  )}
125
232
  </div>
126
233
  </div>
127
- <div className="query-builder__variables__variable__label">
128
- {name}
129
- {constantValueString ? (
130
- <div className="query-builder__constants__value">
131
- {constantValueString}
132
- </div>
133
- ) : (
134
- <div className="query-builder__variables__variable__type">
135
- <div className="query-builder__variables__variable__type__label">
136
- {typeName ?? 'unknown'}
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 />
137
257
  </div>
138
- </div>
139
- )}
140
- </div>
141
- </div>
142
- {actions && (
143
- <div className="query-builder__variables__variable__actions">
144
- <button
145
- className="query-builder__variables__variable__action"
146
- tabIndex={-1}
147
- disabled={isEditDisabled}
148
- onClick={editVariable}
149
- title={editMessage}
150
- >
151
- <PencilIcon />
152
- </button>
153
- <button
154
- className="query-builder__variables__variable__action"
155
- tabIndex={-1}
156
- onClick={deleteVariable}
157
- disabled={deleteDisabled}
158
- title={deleteTitle}
159
- >
160
- <TimesIcon />
161
- </button>
162
- <VariableInfoTooltip variable={variable}>
163
- <div className="query-builder__variables__variable__action value-spec-editor__variable__info">
164
- <InfoCircleIcon />
165
- </div>
166
- </VariableInfoTooltip>
167
- </div>
168
- )}
258
+ </VariableInfoTooltip>
259
+ </div>
260
+ )}
261
+ </ContextMenu>
169
262
  </div>
170
263
  );
171
264
  },
@@ -177,7 +270,6 @@ export const VariableSelector = observer(
177
270
  filterBy?: (variableExpression: VariableExpression) => boolean;
178
271
  }) => {
179
272
  const { queryBuilderState, filterBy } = props;
180
- const isReadOnly = !queryBuilderState.isQuerySupported;
181
273
  const filteredParameterStates =
182
274
  queryBuilderState.parametersState.parameterStates.filter((p) =>
183
275
  filterBy ? filterBy(p.parameter) : true,
@@ -197,7 +289,7 @@ export const VariableSelector = observer(
197
289
  <VariableViewer
198
290
  key={pState.uuid}
199
291
  variable={pState.parameter}
200
- isReadOnly={isReadOnly}
292
+ isReadOnly={true}
201
293
  queryBuilderState={queryBuilderState}
202
294
  />
203
295
  ))}
@@ -208,9 +300,15 @@ export const VariableSelector = observer(
208
300
  <VariableViewer
209
301
  key={constantState.uuid}
210
302
  variable={constantState.variable}
211
- constantValue={constantState.value}
303
+ value={{
304
+ val:
305
+ constantState instanceof
306
+ QueryBuilderSimpleConstantExpressionState
307
+ ? constantState.value
308
+ : undefined,
309
+ }}
212
310
  queryBuilderState={queryBuilderState}
213
- isReadOnly={isReadOnly}
311
+ isReadOnly={true}
214
312
  />
215
313
  ))}
216
314
  </PanelFormListItems>
@@ -17,6 +17,7 @@
17
17
  export enum QUERY_BUILDER_SOURCE_ID_LABEL {
18
18
  QUERY_BUILDER = 'query-builder',
19
19
  PROJECTION = 'projection',
20
+ CONSTANT = 'constant',
20
21
  }
21
22
 
22
23
  export const DEFAULT_LAMBDA_VARIABLE_NAME = 'x';