@finos/legend-query-builder 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderConstantExpressionPanel.js +3 -3
  3. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  4. package/lib/components/QueryBuilderParametersPanel.js +2 -2
  5. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  6. package/lib/components/QueryBuilderPropertyExpressionEditor.js +5 -6
  7. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  8. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  9. package/lib/components/QueryBuilderResultPanel.js +7 -12
  10. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  11. package/lib/components/QueryBuilder_LegendApplicationPlugin.d.ts.map +1 -1
  12. package/lib/components/QueryBuilder_LegendApplicationPlugin.js +1 -0
  13. package/lib/components/QueryBuilder_LegendApplicationPlugin.js.map +1 -1
  14. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  15. package/lib/components/explorer/QueryBuilderExplorerPanel.js +6 -6
  16. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  17. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  18. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +3 -5
  19. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  20. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
  21. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +5 -6
  22. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
  23. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +1 -1
  24. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  25. package/lib/components/filter/QueryBuilderFilterPanel.js +1 -1
  26. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  27. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  28. package/lib/components/shared/BasicValueSpecificationEditor.js +87 -76
  29. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  30. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  31. package/lib/components/shared/CustomDatePicker.js +13 -14
  32. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  33. package/lib/components/watermark/QueryBuilderWatermark.d.ts.map +1 -1
  34. package/lib/components/watermark/QueryBuilderWatermark.js +1 -1
  35. package/lib/components/watermark/QueryBuilderWatermark.js.map +1 -1
  36. package/lib/graphManager/QueryBuilderSupportedFunctions.d.ts +1 -0
  37. package/lib/graphManager/QueryBuilderSupportedFunctions.d.ts.map +1 -1
  38. package/lib/graphManager/QueryBuilderSupportedFunctions.js +1 -0
  39. package/lib/graphManager/QueryBuilderSupportedFunctions.js.map +1 -1
  40. package/lib/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js.map +1 -1
  41. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts +8 -8
  42. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts.map +1 -1
  43. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js +17 -26
  44. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js.map +1 -1
  45. package/lib/index.css +1 -17
  46. package/lib/index.css.map +1 -1
  47. package/lib/package.json +12 -11
  48. package/lib/stores/QueryBuilderChangeDetectionState.d.ts +4 -4
  49. package/lib/stores/QueryBuilderChangeDetectionState.d.ts.map +1 -1
  50. package/lib/stores/QueryBuilderChangeDetectionState.js +9 -9
  51. package/lib/stores/QueryBuilderChangeDetectionState.js.map +1 -1
  52. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  53. package/lib/stores/QueryBuilderConstantsState.js +4 -4
  54. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  55. package/lib/stores/QueryBuilderPropertyEditorState.d.ts +2 -3
  56. package/lib/stores/QueryBuilderPropertyEditorState.d.ts.map +1 -1
  57. package/lib/stores/QueryBuilderPropertyEditorState.js +9 -12
  58. package/lib/stores/QueryBuilderPropertyEditorState.js.map +1 -1
  59. package/lib/stores/QueryBuilderState.d.ts +4 -2
  60. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  61. package/lib/stores/QueryBuilderState.js +7 -7
  62. package/lib/stores/QueryBuilderState.js.map +1 -1
  63. package/lib/stores/QueryBuilderStateBuilder.d.ts +2 -2
  64. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  65. package/lib/stores/QueryBuilderStateBuilder.js +10 -12
  66. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  67. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js +1 -1
  68. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js.map +1 -1
  69. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts +9 -1
  70. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
  71. package/lib/stores/QueryBuilderValueSpecificationHelper.js +22 -1
  72. package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
  73. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.d.ts.map +1 -1
  74. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.js +2 -2
  75. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.js.map +1 -1
  76. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +1 -1
  77. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  78. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts +1 -1
  79. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts.map +1 -1
  80. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js +22 -15
  81. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js.map +1 -1
  82. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.d.ts.map +1 -1
  83. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js +2 -1
  84. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js.map +1 -1
  85. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.d.ts.map +1 -1
  86. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js +2 -1
  87. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js.map +1 -1
  88. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
  89. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js +6 -3
  90. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
  91. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
  92. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js +4 -2
  93. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
  94. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
  95. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js +4 -2
  96. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
  97. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.d.ts.map +1 -1
  98. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js +2 -1
  99. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js.map +1 -1
  100. package/lib/stores/filter/QueryBuilderFilterState.js +2 -2
  101. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  102. package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts.map +1 -1
  103. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +1 -14
  104. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
  105. package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
  106. package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js +9 -2
  107. package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js.map +1 -1
  108. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
  109. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +1 -1
  110. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
  111. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
  112. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +1 -1
  113. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
  114. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
  115. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +4 -3
  116. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
  117. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
  118. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +2 -2
  119. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
  120. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  121. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +2 -2
  122. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
  123. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
  124. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +2 -2
  125. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
  126. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
  127. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +2 -2
  128. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
  129. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
  130. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +1 -1
  131. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
  132. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts.map +1 -1
  133. package/lib/stores/milestoning/QueryBuilderMilestoningState.js +3 -3
  134. package/lib/stores/milestoning/QueryBuilderMilestoningState.js.map +1 -1
  135. package/lib/stores/shared/LambdaParameterState.d.ts +2 -2
  136. package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
  137. package/lib/stores/shared/LambdaParameterState.js +5 -5
  138. package/lib/stores/shared/LambdaParameterState.js.map +1 -1
  139. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +4 -4
  140. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
  141. package/lib/stores/shared/ValueSpecificationEditorHelper.js +11 -15
  142. package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
  143. package/lib/stores/shared/ValueSpecificationModifierHelper.d.ts +8 -8
  144. package/lib/stores/shared/ValueSpecificationModifierHelper.d.ts.map +1 -1
  145. package/lib/stores/shared/ValueSpecificationModifierHelper.js +20 -17
  146. package/lib/stores/shared/ValueSpecificationModifierHelper.js.map +1 -1
  147. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -1
  148. package/lib/stores/watermark/QueryBuilderWatermarkState.js +1 -1
  149. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -1
  150. package/package.json +19 -18
  151. package/src/components/QueryBuilderConstantExpressionPanel.tsx +3 -1
  152. package/src/components/QueryBuilderParametersPanel.tsx +2 -2
  153. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +6 -6
  154. package/src/components/QueryBuilderResultPanel.tsx +18 -14
  155. package/src/components/QueryBuilder_LegendApplicationPlugin.ts +1 -0
  156. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +10 -11
  157. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +7 -5
  158. package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +9 -6
  159. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +1 -1
  160. package/src/components/filter/QueryBuilderFilterPanel.tsx +1 -1
  161. package/src/components/shared/BasicValueSpecificationEditor.tsx +180 -106
  162. package/src/components/shared/CustomDatePicker.tsx +54 -26
  163. package/src/components/watermark/QueryBuilderWatermark.tsx +1 -3
  164. package/src/graphManager/QueryBuilderSupportedFunctions.ts +4 -0
  165. package/src/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.ts +1 -1
  166. package/src/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts +67 -68
  167. package/src/stores/QueryBuilderChangeDetectionState.ts +13 -11
  168. package/src/stores/QueryBuilderConstantsState.ts +4 -3
  169. package/src/stores/QueryBuilderPropertyEditorState.ts +17 -13
  170. package/src/stores/QueryBuilderState.ts +7 -9
  171. package/src/stores/QueryBuilderStateBuilder.ts +10 -12
  172. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +1 -1
  173. package/src/stores/QueryBuilderValueSpecificationHelper.ts +36 -0
  174. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeUtil.ts +10 -2
  175. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -1
  176. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.ts +26 -20
  177. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.ts +2 -0
  178. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.ts +2 -0
  179. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.ts +14 -3
  180. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.ts +4 -0
  181. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.ts +4 -0
  182. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.ts +2 -0
  183. package/src/stores/filter/QueryBuilderFilterState.ts +2 -2
  184. package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +0 -20
  185. package/src/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.ts +17 -4
  186. package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +1 -0
  187. package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +1 -0
  188. package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +12 -3
  189. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +2 -0
  190. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +2 -0
  191. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +2 -0
  192. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +2 -0
  193. package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +1 -0
  194. package/src/stores/milestoning/QueryBuilderMilestoningState.ts +3 -9
  195. package/src/stores/shared/LambdaParameterState.ts +9 -5
  196. package/src/stores/shared/ValueSpecificationEditorHelper.ts +24 -9
  197. package/src/stores/shared/ValueSpecificationModifierHelper.ts +42 -20
  198. package/src/stores/watermark/QueryBuilderWatermarkState.ts +1 -4
@@ -32,6 +32,7 @@ import {
32
32
  FilledWindowMaximizeIcon,
33
33
  BasePopover,
34
34
  PanelFormSection,
35
+ CalculateIcon,
35
36
  } from '@finos/legend-art';
36
37
  import {
37
38
  type Enum,
@@ -53,6 +54,8 @@ import {
53
54
  getEnumValue,
54
55
  getMultiplicityDescription,
55
56
  type ObserverContext,
57
+ matchFunctionName,
58
+ isSubType,
56
59
  } from '@finos/legend-graph';
57
60
  import {
58
61
  type DebouncedFunc,
@@ -62,6 +65,7 @@ import {
62
65
  returnUndefOnError,
63
66
  uniq,
64
67
  parseCSVString,
68
+ guaranteeIsNumber,
65
69
  } from '@finos/legend-shared';
66
70
  import { flowResult } from 'mobx';
67
71
  import { observer } from 'mobx-react-lite';
@@ -72,6 +76,9 @@ import {
72
76
  instanceValue_setValues,
73
77
  } from '../../stores/shared/ValueSpecificationModifierHelper.js';
74
78
  import { CustomDatePicker } from './CustomDatePicker.js';
79
+ import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graphManager/QueryBuilderSupportedFunctions.js';
80
+ import { simplifyValueExpression } from '../../stores/QueryBuilderValueSpecificationHelper.js';
81
+ import { evaluate } from 'mathjs';
75
82
 
76
83
  type TypeCheckOption = {
77
84
  expectedType: Type;
@@ -210,6 +217,7 @@ const StringPrimitiveInstanceValueEditor = observer(
210
217
  cleanUpReloadValues?: () => void;
211
218
  }
212
219
  | undefined;
220
+ obseverContext: ObserverContext;
213
221
  }) => {
214
222
  const {
215
223
  valueSpecification,
@@ -217,12 +225,13 @@ const StringPrimitiveInstanceValueEditor = observer(
217
225
  resetValue,
218
226
  setValueSpecification,
219
227
  selectorConfig,
228
+ obseverContext,
220
229
  } = props;
221
230
  const useSelector = Boolean(selectorConfig);
222
231
  const applicationStore = useApplicationStore();
223
232
  const value = valueSpecification.values[0] as string;
224
233
  const updateValueSpec = (val: string): void => {
225
- instanceValue_setValue(valueSpecification, val, 0);
234
+ instanceValue_setValue(valueSpecification, val, 0, obseverContext);
226
235
  setValueSpecification(valueSpecification);
227
236
  };
228
237
  const changeInputValue: React.ChangeEventHandler<HTMLInputElement> = (
@@ -316,12 +325,18 @@ const BooleanPrimitiveInstanceValueEditor = observer(
316
325
  className?: string | undefined;
317
326
  resetValue: () => void;
318
327
  setValueSpecification: (val: ValueSpecification) => void;
328
+ obseverContext: ObserverContext;
319
329
  }) => {
320
- const { valueSpecification, className, resetValue, setValueSpecification } =
321
- props;
330
+ const {
331
+ valueSpecification,
332
+ className,
333
+ resetValue,
334
+ setValueSpecification,
335
+ obseverContext,
336
+ } = props;
322
337
  const value = valueSpecification.values[0] as boolean;
323
338
  const toggleValue = (): void => {
324
- instanceValue_setValue(valueSpecification, !value, 0);
339
+ instanceValue_setValue(valueSpecification, !value, 0, obseverContext);
325
340
  setValueSpecification(valueSpecification);
326
341
  };
327
342
 
@@ -354,6 +369,7 @@ const NumberPrimitiveInstanceValueEditor = observer(
354
369
  className?: string | undefined;
355
370
  resetValue: () => void;
356
371
  setValueSpecification: (val: ValueSpecification) => void;
372
+ obseverContext: ObserverContext;
357
373
  }) => {
358
374
  const {
359
375
  valueSpecification,
@@ -361,96 +377,95 @@ const NumberPrimitiveInstanceValueEditor = observer(
361
377
  className,
362
378
  resetValue,
363
379
  setValueSpecification,
380
+ obseverContext,
364
381
  } = props;
382
+ const [value, setValue] = useState(
383
+ (valueSpecification.values[0] as number).toString(),
384
+ );
385
+ const inputRef = useRef<HTMLInputElement>(null);
386
+ const numericValue = isInteger
387
+ ? Number.parseInt(Number(value).toString(), 10)
388
+ : Number(value);
365
389
 
366
- const DECIMAL_POINT = '.';
367
- const NEGATIVE_SIGN = '-';
368
-
369
- // NOTE: Although we want to allow the user to type
370
- // '-' and '.' for negative and decimal numbers respectively,
371
- // we want to check for when user leaves the input to not
372
- // leave the number value at an invalid state (i.e. if
373
- // user just left '-' without an actual number)
374
- const onBlur = (): void => {
375
- if (valueSpecification.values[0] === NEGATIVE_SIGN) {
376
- instanceValue_setValue(valueSpecification, 0, 0);
377
- }
378
- const numberInputValue = valueSpecification.values[0] as string;
379
- if (
380
- numberInputValue.length > 0 &&
381
- numberInputValue.at(-1) === DECIMAL_POINT
382
- ) {
383
- instanceValue_setValue(
384
- valueSpecification,
385
- parseInt(
386
- numberInputValue.substring(0, numberInputValue.length - 1),
387
- 10,
388
- ),
389
- 0,
390
- );
390
+ const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
391
+ setValue(event.target.value);
392
+ };
393
+
394
+ // Support expression evaluation
395
+ const calculateExpression = (): void => {
396
+ if (isNaN(numericValue)) {
397
+ try {
398
+ const calculatedValue = guaranteeIsNumber(evaluate(value));
399
+ setValue(
400
+ isInteger
401
+ ? Number.parseInt(calculatedValue.toString(), 10).toString()
402
+ : Number(calculatedValue).toString(),
403
+ );
404
+ } catch {
405
+ setValue((valueSpecification.values[0] as number).toString());
406
+ }
407
+ } else {
408
+ setValue(numericValue.toString());
391
409
  }
392
- const val = isInteger
393
- ? parseInt(numberInputValue, 10)
394
- : parseFloat(numberInputValue);
395
- instanceValue_setValue(valueSpecification, val, 0);
396
- setValueSpecification(valueSpecification);
397
410
  };
398
411
 
399
- const value = valueSpecification.values[0] as number;
400
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
401
- const valueIsDecimalPoint =
402
- (event.nativeEvent as InputEvent).data === DECIMAL_POINT;
412
+ const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
413
+ if (event.code === 'Enter') {
414
+ calculateExpression();
415
+ inputRef.current?.focus();
416
+ } else if (event.code === 'Escape') {
417
+ inputRef.current?.select();
418
+ }
419
+ };
403
420
 
404
- const valueIsNegativeSymbol =
405
- (event.nativeEvent as InputEvent).data === NEGATIVE_SIGN;
421
+ useEffect(() => {
422
+ setValue((valueSpecification.values[0] as number).toString());
423
+ }, [valueSpecification]);
406
424
 
425
+ useEffect(() => {
407
426
  if (
408
- !isInteger &&
409
- valueIsDecimalPoint &&
410
- value.toString().length > 0 &&
411
- !value.toString().includes(DECIMAL_POINT)
412
- ) {
413
- instanceValue_setValue(
414
- valueSpecification,
415
- valueSpecification.values[0] + DECIMAL_POINT,
416
- 0,
417
- );
418
- return;
419
- }
420
- if (
421
- value.toString().includes(DECIMAL_POINT) &&
422
- (event.nativeEvent as InputEvent).data === '0'
427
+ !isNaN(numericValue) &&
428
+ numericValue !== valueSpecification.values[0]
423
429
  ) {
424
430
  instanceValue_setValue(
425
431
  valueSpecification,
426
- `${valueSpecification.values[0]}0`,
432
+ numericValue,
427
433
  0,
434
+ obseverContext,
428
435
  );
429
436
  setValueSpecification(valueSpecification);
430
- return;
431
437
  }
432
-
433
- let inputVal = isInteger
434
- ? parseInt(event.target.value, 10)
435
- : parseFloat(event.target.value);
436
- inputVal = isNaN(inputVal) ? 0 : inputVal;
437
-
438
- valueIsNegativeSymbol
439
- ? instanceValue_setValue(valueSpecification, NEGATIVE_SIGN, 0)
440
- : instanceValue_setValue(valueSpecification, inputVal, 0);
441
- setValueSpecification(valueSpecification);
442
- };
438
+ }, [
439
+ numericValue,
440
+ valueSpecification,
441
+ setValueSpecification,
442
+ obseverContext,
443
+ ]);
443
444
 
444
445
  return (
445
446
  <div className={clsx('value-spec-editor', className)}>
446
- <input
447
- className="panel__content__form__section__input value-spec-editor__input"
448
- spellCheck={false}
449
- type="text"
450
- value={value}
451
- onBlur={onBlur}
452
- onChange={changeValue}
453
- />
447
+ <div className="value-spec-editor__number__input-container">
448
+ <input
449
+ ref={inputRef}
450
+ className="panel__content__form__section__input value-spec-editor__input value-spec-editor__number__input"
451
+ spellCheck={false}
452
+ type="text" // NOTE: we leave this as text so that we can support expression evaluation
453
+ inputMode="numeric"
454
+ value={value}
455
+ onChange={changeValue}
456
+ onBlur={calculateExpression}
457
+ onKeyDown={onKeyDown}
458
+ />
459
+ <div className="value-spec-editor__number__actions">
460
+ <button
461
+ className="value-spec-editor__number__action"
462
+ title="Evaluate Expression (Enter)"
463
+ onClick={calculateExpression}
464
+ >
465
+ <CalculateIcon />
466
+ </button>
467
+ </div>
468
+ </div>
454
469
  <button
455
470
  className="value-spec-editor__reset-btn"
456
471
  title="Reset"
@@ -469,9 +484,15 @@ const EnumValueInstanceValueEditor = observer(
469
484
  className?: string | undefined;
470
485
  setValueSpecification: (val: ValueSpecification) => void;
471
486
  resetValue: () => void;
487
+ obseverContext: ObserverContext;
472
488
  }) => {
473
- const { valueSpecification, className, resetValue, setValueSpecification } =
474
- props;
489
+ const {
490
+ valueSpecification,
491
+ className,
492
+ resetValue,
493
+ setValueSpecification,
494
+ obseverContext,
495
+ } = props;
475
496
  const enumValueRef = guaranteeNonNullable(valueSpecification.values[0]);
476
497
  const enumValue = enumValueRef.value;
477
498
  const options = enumValue._OWNER.values.map((value) => ({
@@ -483,6 +504,7 @@ const EnumValueInstanceValueEditor = observer(
483
504
  valueSpecification,
484
505
  EnumValueExplicitReference.create(val.value),
485
506
  0,
507
+ obseverContext,
486
508
  );
487
509
  setValueSpecification(valueSpecification);
488
510
  };
@@ -536,9 +558,10 @@ const setCollectionValue = (
536
558
  valueSpecification: CollectionInstanceValue,
537
559
  expectedType: Type,
538
560
  value: string,
561
+ obseverContext: ObserverContext,
539
562
  ): void => {
540
563
  if (value.trim().length === 0) {
541
- instanceValue_setValues(valueSpecification, []);
564
+ instanceValue_setValues(valueSpecification, [], obseverContext);
542
565
  return;
543
566
  }
544
567
  let result: unknown[] = [];
@@ -559,7 +582,11 @@ const setCollectionValue = (
559
582
  new GenericType(expectedType),
560
583
  ),
561
584
  );
562
- instanceValue_setValues(primitiveInstanceValue, [item.toString()]);
585
+ instanceValue_setValues(
586
+ primitiveInstanceValue,
587
+ [item.toString()],
588
+ obseverContext,
589
+ );
563
590
  return primitiveInstanceValue;
564
591
  })
565
592
  .filter(isNonNullable);
@@ -580,7 +607,11 @@ const setCollectionValue = (
580
607
  new GenericType(expectedType),
581
608
  ),
582
609
  );
583
- instanceValue_setValues(primitiveInstanceValue, [item]);
610
+ instanceValue_setValues(
611
+ primitiveInstanceValue,
612
+ [item],
613
+ obseverContext,
614
+ );
584
615
  return primitiveInstanceValue;
585
616
  })
586
617
  .filter(isNonNullable);
@@ -602,14 +633,16 @@ const setCollectionValue = (
602
633
  const enumValueInstanceValue = new EnumValueInstanceValue(
603
634
  GenericTypeExplicitReference.create(new GenericType(expectedType)),
604
635
  );
605
- instanceValue_setValues(enumValueInstanceValue, [
606
- EnumValueExplicitReference.create(_enum),
607
- ]);
636
+ instanceValue_setValues(
637
+ enumValueInstanceValue,
638
+ [EnumValueExplicitReference.create(_enum)],
639
+ obseverContext,
640
+ );
608
641
  return enumValueInstanceValue;
609
642
  })
610
643
  .filter(isNonNullable);
611
644
  }
612
- instanceValue_setValues(valueSpecification, result);
645
+ instanceValue_setValues(valueSpecification, result, obseverContext);
613
646
  };
614
647
 
615
648
  const COLLECTION_PREVIEW_CHAR_LIMIT = 50;
@@ -622,6 +655,7 @@ const CollectionValueInstanceValueEditor = observer(
622
655
  className?: string | undefined;
623
656
  resetValue: () => void;
624
657
  setValueSpecification: (val: ValueSpecification) => void;
658
+ obseverContext: ObserverContext;
625
659
  }) => {
626
660
  const {
627
661
  valueSpecification,
@@ -629,6 +663,7 @@ const CollectionValueInstanceValueEditor = observer(
629
663
  className,
630
664
  resetValue,
631
665
  setValueSpecification,
666
+ obseverContext,
632
667
  } = props;
633
668
  const inputRef = useRef<HTMLInputElement>(null);
634
669
  const [text, setText] = useState(stringifyValue(valueSpecification.values));
@@ -653,7 +688,12 @@ const CollectionValueInstanceValueEditor = observer(
653
688
  const saveEdit = (): void => {
654
689
  setEditable(false);
655
690
  setShowAdvancedEditorPopover(false);
656
- setCollectionValue(valueSpecification, expectedType, text);
691
+ setCollectionValue(
692
+ valueSpecification,
693
+ expectedType,
694
+ text,
695
+ obseverContext,
696
+ );
657
697
  setText(stringifyValue(valueSpecification.values));
658
698
  setValueSpecification(valueSpecification);
659
699
  };
@@ -849,6 +889,7 @@ export const BasicValueSpecificationEditor: React.FC<{
849
889
  className={className}
850
890
  resetValue={resetValue}
851
891
  selectorConfig={selectorConfig}
892
+ obseverContext={obseverContext}
852
893
  />
853
894
  );
854
895
  case PRIMITIVE_TYPE.BOOLEAN:
@@ -858,6 +899,7 @@ export const BasicValueSpecificationEditor: React.FC<{
858
899
  setValueSpecification={setValueSpecification}
859
900
  className={className}
860
901
  resetValue={resetValue}
902
+ obseverContext={obseverContext}
861
903
  />
862
904
  );
863
905
  case PRIMITIVE_TYPE.NUMBER:
@@ -872,6 +914,7 @@ export const BasicValueSpecificationEditor: React.FC<{
872
914
  setValueSpecification={setValueSpecification}
873
915
  className={className}
874
916
  resetValue={resetValue}
917
+ obseverContext={obseverContext}
875
918
  />
876
919
  );
877
920
  case PRIMITIVE_TYPE.DATE:
@@ -899,6 +942,7 @@ export const BasicValueSpecificationEditor: React.FC<{
899
942
  className={className}
900
943
  resetValue={resetValue}
901
944
  setValueSpecification={setValueSpecification}
945
+ obseverContext={obseverContext}
902
946
  />
903
947
  );
904
948
  } else if (
@@ -916,6 +960,7 @@ export const BasicValueSpecificationEditor: React.FC<{
916
960
  className={className}
917
961
  resetValue={resetValue}
918
962
  setValueSpecification={setValueSpecification}
963
+ obseverContext={obseverContext}
919
964
  />
920
965
  );
921
966
  }
@@ -940,26 +985,55 @@ export const BasicValueSpecificationEditor: React.FC<{
940
985
  resetValue={resetValue}
941
986
  />
942
987
  );
943
- } else if (
944
- valueSpecification instanceof SimpleFunctionExpression &&
945
- [
946
- PRIMITIVE_TYPE.DATE.toString(),
947
- PRIMITIVE_TYPE.STRICTDATE.toString(),
948
- PRIMITIVE_TYPE.DATETIME.toString(),
949
- PRIMITIVE_TYPE.LATESTDATE.toString(),
950
- ].includes(typeCheckOption.expectedType.path)
951
- ) {
952
- return (
953
- <DateInstanceValueEditor
954
- valueSpecification={valueSpecification}
955
- graph={graph}
956
- obseverContext={obseverContext}
957
- typeCheckOption={typeCheckOption}
958
- className={className}
959
- setValueSpecification={setValueSpecification}
960
- resetValue={resetValue}
961
- />
962
- );
988
+ } else if (valueSpecification instanceof SimpleFunctionExpression) {
989
+ if (isSubType(typeCheckOption.expectedType, PrimitiveType.DATE)) {
990
+ return (
991
+ <DateInstanceValueEditor
992
+ valueSpecification={valueSpecification}
993
+ graph={graph}
994
+ obseverContext={obseverContext}
995
+ typeCheckOption={typeCheckOption}
996
+ className={className}
997
+ setValueSpecification={setValueSpecification}
998
+ resetValue={resetValue}
999
+ />
1000
+ );
1001
+ } else if (
1002
+ // TODO: think of other ways we could make use of this code path where we can simplify
1003
+ // an expression value to simple value, not just handling minus() function only
1004
+ isSubType(typeCheckOption.expectedType, PrimitiveType.NUMBER) &&
1005
+ matchFunctionName(
1006
+ valueSpecification.functionName,
1007
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.MINUS,
1008
+ )
1009
+ ) {
1010
+ const simplifiedValue = simplifyValueExpression(
1011
+ valueSpecification,
1012
+ obseverContext,
1013
+ );
1014
+ if (
1015
+ simplifiedValue instanceof PrimitiveInstanceValue &&
1016
+ isSubType(
1017
+ simplifiedValue.genericType.value.rawType,
1018
+ PrimitiveType.NUMBER,
1019
+ )
1020
+ ) {
1021
+ return (
1022
+ <NumberPrimitiveInstanceValueEditor
1023
+ valueSpecification={simplifiedValue}
1024
+ isInteger={
1025
+ simplifiedValue.genericType.value.rawType ===
1026
+ PrimitiveType.INTEGER
1027
+ }
1028
+ setValueSpecification={setValueSpecification}
1029
+ className={className}
1030
+ resetValue={resetValue}
1031
+ obseverContext={obseverContext}
1032
+ />
1033
+ );
1034
+ }
1035
+ }
963
1036
  }
1037
+
964
1038
  return <UnsupportedValueSpecificationEditor />;
965
1039
  };
@@ -258,16 +258,20 @@ const buildPureDateFunctionExpression = (
258
258
  new GenericType(graph.getType(DAY_OF_WEEK)),
259
259
  ),
260
260
  );
261
- instanceValue_setValues(dayOfWeekEnumIntanceValue, [
262
- ...dayOfWeekEnumIntanceValue.values,
263
- EnumValueExplicitReference.create(
264
- guaranteeNonNullable(
265
- graph
266
- .getEnumeration(DAY_OF_WEEK)
267
- .values.filter((e) => e.name === datePickerOption.day)[0],
261
+ instanceValue_setValues(
262
+ dayOfWeekEnumIntanceValue,
263
+ [
264
+ ...dayOfWeekEnumIntanceValue.values,
265
+ EnumValueExplicitReference.create(
266
+ guaranteeNonNullable(
267
+ graph
268
+ .getEnumeration(DAY_OF_WEEK)
269
+ .values.filter((e) => e.name === datePickerOption.day)[0],
270
+ ),
268
271
  ),
269
- ),
270
- ]);
272
+ ],
273
+ observerContext,
274
+ );
271
275
  functionExpression_addParameterValue(
272
276
  previousFridaySFE,
273
277
  dayOfWeekEnumIntanceValue,
@@ -454,6 +458,7 @@ const buildPureAdjustDateFunction = (
454
458
  graph,
455
459
  PRIMITIVE_TYPE.INTEGER,
456
460
  customDateOption.duration,
461
+ observerContext,
457
462
  ),
458
463
  observerContext,
459
464
  );
@@ -463,14 +468,14 @@ const buildPureAdjustDateFunction = (
463
468
  observerContext,
464
469
  );
465
470
  } else {
466
- const adjustmentInstanceValue = buildPrimitiveInstanceValue(
467
- graph,
468
- PRIMITIVE_TYPE.INTEGER,
469
- customDateOption.duration,
470
- );
471
471
  functionExpression_addParameterValue(
472
472
  dateAdjustSimpleFunctionExpression,
473
- adjustmentInstanceValue,
473
+ buildPrimitiveInstanceValue(
474
+ graph,
475
+ PRIMITIVE_TYPE.INTEGER,
476
+ customDateOption.duration,
477
+ observerContext,
478
+ ),
474
479
  observerContext,
475
480
  );
476
481
  }
@@ -479,17 +484,21 @@ const buildPureAdjustDateFunction = (
479
484
  new GenericType(graph.getType(DURATION_UNIT)),
480
485
  ),
481
486
  );
482
- instanceValue_setValues(durationUnitEnumIntanceValue, [
483
- ...durationUnitEnumIntanceValue.values,
484
- EnumValueExplicitReference.create(
485
- guaranteeNonNullable(
486
- buildPureDurationEnumValue(
487
- guaranteeNonNullable(customDateOption.unit),
488
- graph,
487
+ instanceValue_setValues(
488
+ durationUnitEnumIntanceValue,
489
+ [
490
+ ...durationUnitEnumIntanceValue.values,
491
+ EnumValueExplicitReference.create(
492
+ guaranteeNonNullable(
493
+ buildPureDurationEnumValue(
494
+ guaranteeNonNullable(customDateOption.unit),
495
+ graph,
496
+ ),
489
497
  ),
490
498
  ),
491
- ),
492
- ]);
499
+ ],
500
+ observerContext,
501
+ );
493
502
  functionExpression_addParameterValue(
494
503
  dateAdjustSimpleFunctionExpression,
495
504
  durationUnitEnumIntanceValue,
@@ -699,12 +708,14 @@ const AbsoluteDateValueSpecificationEditor: React.FC<{
699
708
  graph: PureModel;
700
709
  setValueSpecification: (val: ValueSpecification) => void;
701
710
  setDatePickerOption: (datePickerOption: DatePickerOption) => void;
711
+ observerContext: ObserverContext;
702
712
  }> = (props) => {
703
713
  const {
704
714
  valueSpecification,
705
715
  graph,
706
716
  setValueSpecification,
707
717
  setDatePickerOption,
718
+ observerContext,
708
719
  } = props;
709
720
  const inputRef = useRef<HTMLInputElement>(null);
710
721
  const absoluteDateValue =
@@ -720,10 +731,16 @@ const AbsoluteDateValueSpecificationEditor: React.FC<{
720
731
  graph,
721
732
  PRIMITIVE_TYPE.STRICTDATE,
722
733
  event.target.value,
734
+ observerContext,
723
735
  ),
724
736
  );
725
737
  } else if (valueSpecification instanceof InstanceValue) {
726
- instanceValue_setValue(valueSpecification, event.target.value, 0);
738
+ instanceValue_setValue(
739
+ valueSpecification,
740
+ event.target.value,
741
+ 0,
742
+ observerContext,
743
+ );
727
744
  if (
728
745
  valueSpecification.genericType.value.rawType.path !==
729
746
  PRIMITIVE_TYPE.STRICTDATE
@@ -768,12 +785,14 @@ const AbsoluteTimeValueSpecificationEditor: React.FC<{
768
785
  graph: PureModel;
769
786
  setValueSpecification: (val: ValueSpecification) => void;
770
787
  setDatePickerOption: (datePickerOption: DatePickerOption) => void;
788
+ observerContext: ObserverContext;
771
789
  }> = (props) => {
772
790
  const {
773
791
  valueSpecification,
774
792
  graph,
775
793
  setValueSpecification,
776
794
  setDatePickerOption,
795
+ observerContext,
777
796
  } = props;
778
797
  const inputRef = useRef<HTMLInputElement>(null);
779
798
  const absoluteTimeValue =
@@ -789,10 +808,16 @@ const AbsoluteTimeValueSpecificationEditor: React.FC<{
789
808
  graph,
790
809
  PRIMITIVE_TYPE.DATETIME,
791
810
  event.target.value,
811
+ observerContext,
792
812
  ),
793
813
  );
794
814
  } else {
795
- instanceValue_setValue(valueSpecification, event.target.value, 0);
815
+ instanceValue_setValue(
816
+ valueSpecification,
817
+ event.target.value,
818
+ 0,
819
+ observerContext,
820
+ );
796
821
  if (
797
822
  valueSpecification.genericType.value.rawType.path !==
798
823
  PRIMITIVE_TYPE.DATETIME
@@ -1213,6 +1238,7 @@ export const CustomDatePicker: React.FC<{
1213
1238
  graph,
1214
1239
  PRIMITIVE_TYPE.LATESTDATE,
1215
1240
  event.target.value,
1241
+ observerContext,
1216
1242
  ),
1217
1243
  );
1218
1244
  } else if (
@@ -1255,6 +1281,7 @@ export const CustomDatePicker: React.FC<{
1255
1281
  valueSpecification={valueSpecification}
1256
1282
  setValueSpecification={setValueSpecification}
1257
1283
  setDatePickerOption={setDatePickerOption}
1284
+ observerContext={observerContext}
1258
1285
  />
1259
1286
  );
1260
1287
  case CUSTOM_DATE_PICKER_OPTION.ABSOLUTE_TIME:
@@ -1264,6 +1291,7 @@ export const CustomDatePicker: React.FC<{
1264
1291
  valueSpecification={valueSpecification}
1265
1292
  setValueSpecification={setValueSpecification}
1266
1293
  setDatePickerOption={setDatePickerOption}
1294
+ observerContext={observerContext}
1267
1295
  />
1268
1296
  );
1269
1297
  case CUSTOM_DATE_PICKER_OPTION.CUSTOM_DATE:
@@ -106,9 +106,7 @@ const WatermarkValueEditor = observer(
106
106
  watermarkState.setValue(val);
107
107
  }}
108
108
  graph={graph}
109
- obseverContext={
110
- watermarkState.queryBuilderState.observableContext
111
- }
109
+ obseverContext={watermarkState.queryBuilderState.observerContext}
112
110
  typeCheckOption={{
113
111
  expectedType: PrimitiveType.STRING,
114
112
  }}