@finos/legend-query-builder 4.14.35 → 4.14.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. package/lib/__lib__/QueryBuilderDocumentation.d.ts +2 -1
  2. package/lib/__lib__/QueryBuilderDocumentation.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderDocumentation.js +1 -0
  4. package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
  5. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  6. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  7. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  8. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  9. package/lib/components/QueryBuilder.d.ts.map +1 -1
  10. package/lib/components/QueryBuilder.js +55 -19
  11. package/lib/components/QueryBuilder.js.map +1 -1
  12. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  13. package/lib/components/QueryBuilderConstantExpressionPanel.js +30 -13
  14. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  15. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  16. package/lib/components/QueryBuilderPropertyExpressionEditor.js +2 -1
  17. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  18. package/lib/components/QueryBuilderSideBar.d.ts +0 -16
  19. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  20. package/lib/components/QueryBuilderSideBar.js +32 -104
  21. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  22. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  23. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +2 -1
  24. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  26. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +50 -5
  27. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  29. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +2 -1
  30. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  31. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  32. package/lib/components/filter/QueryBuilderFilterPanel.js +2 -1
  33. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  34. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  35. package/lib/components/result/QueryBuilderResultPanel.js +18 -6
  36. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  37. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  38. package/lib/components/shared/BasicValueSpecificationEditor.js +62 -28
  39. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  40. package/lib/components/shared/CustomDatePicker.d.ts +1 -0
  41. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  42. package/lib/components/shared/CustomDatePicker.js +13 -9
  43. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  44. package/lib/components/shared/QueryBuilderVariableSelector.d.ts +1 -0
  45. package/lib/components/shared/QueryBuilderVariableSelector.d.ts.map +1 -1
  46. package/lib/components/shared/QueryBuilderVariableSelector.js +2 -2
  47. package/lib/components/shared/QueryBuilderVariableSelector.js.map +1 -1
  48. package/lib/components/workflows/ClassQueryBuilder.d.ts.map +1 -1
  49. package/lib/components/workflows/ClassQueryBuilder.js +19 -16
  50. package/lib/components/workflows/ClassQueryBuilder.js.map +1 -1
  51. package/lib/components/workflows/MappingQueryBuilder.d.ts.map +1 -1
  52. package/lib/components/workflows/MappingQueryBuilder.js +18 -15
  53. package/lib/components/workflows/MappingQueryBuilder.js.map +1 -1
  54. package/lib/components/workflows/ServiceQueryBuilder.d.ts.map +1 -1
  55. package/lib/components/workflows/ServiceQueryBuilder.js +13 -10
  56. package/lib/components/workflows/ServiceQueryBuilder.js.map +1 -1
  57. package/lib/index.css +2 -2
  58. package/lib/index.css.map +1 -1
  59. package/lib/index.d.ts +2 -1
  60. package/lib/index.d.ts.map +1 -1
  61. package/lib/index.js +1 -0
  62. package/lib/index.js.map +1 -1
  63. package/lib/package.json +1 -1
  64. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  65. package/lib/stores/QueryBuilderConstantsState.js +2 -1
  66. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  67. package/lib/stores/QueryBuilderPropertyEditorState.d.ts +1 -1
  68. package/lib/stores/QueryBuilderPropertyEditorState.d.ts.map +1 -1
  69. package/lib/stores/QueryBuilderPropertyEditorState.js +12 -34
  70. package/lib/stores/QueryBuilderPropertyEditorState.js.map +1 -1
  71. package/lib/stores/QueryBuilderState.d.ts +3 -0
  72. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  73. package/lib/stores/QueryBuilderState.js +15 -1
  74. package/lib/stores/QueryBuilderState.js.map +1 -1
  75. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts +2 -1
  76. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
  77. package/lib/stores/QueryBuilderValueSpecificationHelper.js +23 -1
  78. package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
  79. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +29 -0
  80. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  81. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts +2 -0
  82. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts.map +1 -1
  83. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js +2 -0
  84. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  85. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +2 -0
  86. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  87. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +6 -0
  88. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  89. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +2 -0
  90. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  91. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +15 -0
  92. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  93. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +3 -0
  94. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  95. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +42 -3
  96. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  97. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.d.ts.map +1 -1
  98. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js +6 -5
  99. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js.map +1 -1
  100. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.d.ts.map +1 -1
  101. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js +6 -5
  102. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js.map +1 -1
  103. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
  104. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js +8 -37
  105. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
  106. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
  107. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js +7 -10
  108. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
  109. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
  110. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js +7 -10
  111. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
  112. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.d.ts.map +1 -1
  113. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js +6 -5
  114. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js.map +1 -1
  115. package/lib/stores/filter/QueryBuilderFilterState.d.ts +3 -0
  116. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  117. package/lib/stores/filter/QueryBuilderFilterState.js +30 -2
  118. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  119. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
  120. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +5 -4
  121. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
  122. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
  123. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +5 -4
  124. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
  125. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
  126. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +7 -35
  127. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
  128. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
  129. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +6 -8
  130. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
  131. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  132. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +6 -8
  133. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
  134. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
  135. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +6 -8
  136. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
  137. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
  138. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +6 -8
  139. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
  140. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
  141. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +5 -4
  142. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
  143. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts +5 -0
  144. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts.map +1 -1
  145. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js +7 -0
  146. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js.map +1 -1
  147. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +1 -1
  148. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
  149. package/lib/stores/shared/ValueSpecificationEditorHelper.js +20 -10
  150. package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
  151. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts +0 -2
  152. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -1
  153. package/lib/stores/watermark/QueryBuilderWatermarkState.js +0 -6
  154. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -1
  155. package/lib/stores/workflows/MappingQueryBuilderState.d.ts +2 -2
  156. package/lib/stores/workflows/MappingQueryBuilderState.d.ts.map +1 -1
  157. package/lib/stores/workflows/MappingQueryBuilderState.js +2 -1
  158. package/lib/stores/workflows/MappingQueryBuilderState.js.map +1 -1
  159. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts +2 -2
  160. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts.map +1 -1
  161. package/lib/stores/workflows/ServiceQueryBuilderState.js +2 -1
  162. package/lib/stores/workflows/ServiceQueryBuilderState.js.map +1 -1
  163. package/package.json +4 -4
  164. package/src/__lib__/QueryBuilderDocumentation.ts +1 -0
  165. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  166. package/src/components/QueryBuilder.tsx +179 -54
  167. package/src/components/QueryBuilderConstantExpressionPanel.tsx +36 -14
  168. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +2 -0
  169. package/src/components/QueryBuilderSideBar.tsx +138 -339
  170. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +6 -1
  171. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +139 -1
  172. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +17 -0
  173. package/src/components/filter/QueryBuilderFilterPanel.tsx +6 -0
  174. package/src/components/result/QueryBuilderResultPanel.tsx +63 -6
  175. package/src/components/shared/BasicValueSpecificationEditor.tsx +96 -34
  176. package/src/components/shared/CustomDatePicker.tsx +18 -11
  177. package/src/components/shared/QueryBuilderVariableSelector.tsx +2 -2
  178. package/src/components/workflows/ClassQueryBuilder.tsx +79 -77
  179. package/src/components/workflows/MappingQueryBuilder.tsx +75 -76
  180. package/src/components/workflows/ServiceQueryBuilder.tsx +71 -70
  181. package/src/index.ts +2 -1
  182. package/src/stores/QueryBuilderConstantsState.ts +2 -0
  183. package/src/stores/QueryBuilderPropertyEditorState.ts +15 -53
  184. package/src/stores/QueryBuilderState.ts +23 -1
  185. package/src/stores/QueryBuilderValueSpecificationHelper.ts +32 -0
  186. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +39 -0
  187. package/src/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.ts +4 -0
  188. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +8 -0
  189. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +32 -0
  190. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +59 -0
  191. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.ts +5 -5
  192. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.ts +5 -5
  193. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.ts +10 -69
  194. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.ts +7 -18
  195. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.ts +7 -18
  196. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.ts +5 -5
  197. package/src/stores/filter/QueryBuilderFilterState.ts +48 -2
  198. package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +5 -5
  199. package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +5 -5
  200. package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +10 -71
  201. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +6 -14
  202. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +6 -14
  203. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +6 -14
  204. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +6 -14
  205. package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +5 -5
  206. package/src/stores/query-workflow/QueryBuilderWorkFlowState.ts +10 -0
  207. package/src/stores/shared/ValueSpecificationEditorHelper.ts +32 -16
  208. package/src/stores/watermark/QueryBuilderWatermarkState.ts +0 -7
  209. package/src/stores/workflows/MappingQueryBuilderState.ts +7 -1
  210. package/src/stores/workflows/ServiceQueryBuilderState.ts +6 -1
  211. package/tsconfig.json +0 -1
  212. package/lib/components/watermark/QueryBuilderWatermark.d.ts +0 -22
  213. package/lib/components/watermark/QueryBuilderWatermark.d.ts.map +0 -1
  214. package/lib/components/watermark/QueryBuilderWatermark.js +0 -83
  215. package/lib/components/watermark/QueryBuilderWatermark.js.map +0 -1
  216. package/src/components/watermark/QueryBuilderWatermark.tsx +0 -218
@@ -32,10 +32,15 @@ import {
32
32
  MenuContentItem,
33
33
  ModalFooterButton,
34
34
  InputWithInlineValidation,
35
+ PanelDivider,
36
+ PanelDropZone,
37
+ PanelFormSection,
35
38
  } from '@finos/legend-art';
36
39
  import { SortColumnState } from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
37
40
  import {
38
41
  addUniqueEntry,
42
+ clone,
43
+ deepClone,
39
44
  deleteEntry,
40
45
  guaranteeNonNullable,
41
46
  } from '@finos/legend-shared';
@@ -43,9 +48,23 @@ import { useApplicationStore } from '@finos/legend-application';
43
48
  import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
44
49
  import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
45
50
  import { COLUMN_SORT_TYPE } from '../../graph/QueryBuilderMetaModelConst.js';
46
- import { useEffect, useState } from 'react';
51
+ import { useCallback, useEffect, useState } from 'react';
47
52
  import type { QueryBuilderProjectionColumnState } from '../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
48
53
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
54
+ import { VariableSelector } from '../shared/QueryBuilderVariableSelector.js';
55
+ import {
56
+ type ValueSpecification,
57
+ type VariableExpression,
58
+ PrimitiveType,
59
+ Multiplicity,
60
+ areMultiplicitiesEqual,
61
+ } from '@finos/legend-graph';
62
+ import {
63
+ BasicValueSpecificationEditor,
64
+ QUERY_BUILDER_VARIABLE_DND_TYPE,
65
+ type QueryBuilderVariableDragSource,
66
+ } from '../shared/BasicValueSpecificationEditor.js';
67
+ import { useDrop } from 'react-dnd';
49
68
 
50
69
  const ColumnSortEditor = observer(
51
70
  (props: {
@@ -246,6 +265,10 @@ export const QueryResultModifierModal = observer(
246
265
  const [slice, setSlice] = useState<
247
266
  [number | undefined, number | undefined]
248
267
  >(stateSlice ?? [undefined, undefined]);
268
+ const watermarkState = tdsState.queryBuilderState.watermarkState;
269
+ const [watermarkValue, setWatermarkValue] = useState(
270
+ deepClone(watermarkState.value),
271
+ );
249
272
 
250
273
  // Sync temp state with tdsState when modal is opened/closed
251
274
  useEffect(() => {
@@ -253,8 +276,10 @@ export const QueryResultModifierModal = observer(
253
276
  setDistinct(stateDistinct);
254
277
  setLimitResults(stateLimitResults);
255
278
  setSlice(stateSlice ?? [undefined, undefined]);
279
+ setWatermarkValue(deepClone(watermarkState.value));
256
280
  }, [
257
281
  resultSetModifierState.showModal,
282
+ watermarkState.value,
258
283
  stateSortColumns,
259
284
  stateDistinct,
260
285
  stateLimitResults,
@@ -273,6 +298,7 @@ export const QueryResultModifierModal = observer(
273
298
  resultSetModifierState.setSlice(undefined);
274
299
  }
275
300
  resultSetModifierState.setShowModal(false);
301
+ watermarkState.setValue(watermarkValue);
276
302
  };
277
303
 
278
304
  const handleLimitResultsChange: React.ChangeEventHandler<
@@ -321,6 +347,50 @@ export const QueryResultModifierModal = observer(
321
347
  slice[1] !== undefined &&
322
348
  slice[0] >= slice[1]);
323
349
 
350
+ // watermark
351
+ const isParamaterCompatibleWithWaterMark = (
352
+ parameter: VariableExpression,
353
+ ): boolean =>
354
+ PrimitiveType.STRING === parameter.genericType?.value.rawType &&
355
+ areMultiplicitiesEqual(parameter.multiplicity, Multiplicity.ONE);
356
+ const handleDrop = useCallback(
357
+ (item: QueryBuilderVariableDragSource): void => {
358
+ setWatermarkValue(item.variable);
359
+ },
360
+ [setWatermarkValue],
361
+ );
362
+ const toggleWatermark = (): void => {
363
+ if (watermarkValue) {
364
+ setWatermarkValue(undefined);
365
+ } else {
366
+ setWatermarkValue(watermarkState.getDefaultValue());
367
+ }
368
+ };
369
+ const [{ isParameterValueDragOver }, dropTargetConnector] = useDrop<
370
+ QueryBuilderVariableDragSource,
371
+ void,
372
+ { isParameterValueDragOver: boolean }
373
+ >(
374
+ () => ({
375
+ accept: [QUERY_BUILDER_VARIABLE_DND_TYPE],
376
+ drop: (item, monitor): void => {
377
+ if (
378
+ !monitor.didDrop() &&
379
+ // Only allows parameters with muliplicity 1 and type string
380
+ isParamaterCompatibleWithWaterMark(item.variable)
381
+ ) {
382
+ handleDrop(item);
383
+ } // prevent drop event propagation to accomondate for nested DnD
384
+ },
385
+ collect: (monitor) => ({
386
+ isParameterValueDragOver: monitor.isOver({
387
+ shallow: true,
388
+ }),
389
+ }),
390
+ }),
391
+ [handleDrop],
392
+ );
393
+
324
394
  return (
325
395
  <Dialog
326
396
  open={Boolean(resultSetModifierState.showModal)}
@@ -428,6 +498,74 @@ export const QueryResultModifierModal = observer(
428
498
  </div>
429
499
  </div>
430
500
  </div>
501
+ <>
502
+ <PanelFormSection>
503
+ <label className="panel__content__form__section__header__label">
504
+ Watermark
505
+ </label>
506
+ <button
507
+ className={clsx(
508
+ 'panel__content__form__section__toggler',
509
+ 'panel__content__form__section__toggler__btn',
510
+ {
511
+ 'panel__content__form__section__toggler__btn--toggled':
512
+ watermarkValue,
513
+ },
514
+ )}
515
+ onClick={toggleWatermark}
516
+ tabIndex={-1}
517
+ >
518
+ {watermarkValue ? <CheckSquareIcon /> : <SquareIcon />}
519
+ <div className="panel__content__form__section__toggler__prompt">
520
+ Enable Watermark
521
+ </div>
522
+ </button>
523
+ </PanelFormSection>
524
+ {watermarkValue && (
525
+ <>
526
+ <PanelFormSection>
527
+ <div className="query-builder__variable-editor">
528
+ <PanelDropZone
529
+ isDragOver={isParameterValueDragOver}
530
+ dropTargetConnector={dropTargetConnector}
531
+ >
532
+ <BasicValueSpecificationEditor
533
+ valueSpecification={watermarkValue}
534
+ setValueSpecification={(
535
+ val: ValueSpecification,
536
+ ): void => {
537
+ setWatermarkValue(clone(val));
538
+ }}
539
+ graph={
540
+ watermarkState.queryBuilderState.graphManagerState
541
+ .graph
542
+ }
543
+ obseverContext={
544
+ watermarkState.queryBuilderState.observerContext
545
+ }
546
+ typeCheckOption={{
547
+ expectedType: PrimitiveType.STRING,
548
+ }}
549
+ resetValue={() =>
550
+ setWatermarkValue(
551
+ watermarkState.getDefaultValue(),
552
+ )
553
+ }
554
+ isConstant={watermarkState.queryBuilderState.constantState.isValueSpecConstant(
555
+ watermarkValue,
556
+ )}
557
+ />
558
+ </PanelDropZone>
559
+ </div>
560
+ </PanelFormSection>
561
+ <PanelDivider />
562
+ <VariableSelector
563
+ filterBy={isParamaterCompatibleWithWaterMark}
564
+ queryBuilderState={tdsState.queryBuilderState}
565
+ />
566
+ </>
567
+ )}
568
+ </>
431
569
  </div>
432
570
  </ModalBody>
433
571
  <ModalFooter>
@@ -116,6 +116,7 @@ import {
116
116
  QueryBuilderDerivationInfoTooltip,
117
117
  QueryBuilderPropertyInfoTooltip,
118
118
  } from '../shared/QueryBuilderPropertyInfoTooltip.js';
119
+ import { getNameOfValueSpecification } from '../shared/QueryBuilderVariableSelector.js';
119
120
 
120
121
  const QueryBuilderProjectionColumnContextMenu = observer(
121
122
  forwardRef<
@@ -1214,6 +1215,22 @@ export const QueryBuilderTDSPanel = observer(
1214
1215
  </div>
1215
1216
  </div>
1216
1217
  )}
1218
+ {tdsState.queryBuilderState.watermarkState.value && (
1219
+ <div className="query-builder__projection__result-modifier-prompt__group">
1220
+ <div className="query-builder__projection__result-modifier-prompt__group__label">
1221
+ Watermark
1222
+ </div>
1223
+ <div
1224
+ className="query-builder__projection__result-modifier-prompt__group__content"
1225
+ onClick={openResultSetModifierEditor}
1226
+ >
1227
+ {getNameOfValueSpecification(
1228
+ tdsState.queryBuilderState.watermarkState.value,
1229
+ tdsState.queryBuilderState,
1230
+ )}
1231
+ </div>
1232
+ </div>
1233
+ )}
1217
1234
  </div>
1218
1235
  <div className="query-builder__projection__toolbar__actions">
1219
1236
  <button
@@ -111,6 +111,7 @@ import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetry
111
111
  import { getPropertyChainName } from '../../stores/QueryBuilderPropertyEditorState.js';
112
112
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
113
113
  import { buildPropertyExpressionChain } from '../../stores/QueryBuilderValueSpecificationBuilderHelper.js';
114
+ import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
114
115
 
115
116
  const isCollectionProperty = (
116
117
  propertyExpression: AbstractPropertyExpression,
@@ -1479,6 +1480,11 @@ export const QueryBuilderFilterPanel = observer(
1479
1480
  <div className="panel__header">
1480
1481
  <div className="panel__header__title">
1481
1482
  <div className="panel__header__title__label">filter</div>
1483
+ {filterState.allValidationIssues.length !== 0 && (
1484
+ <QueryBuilderPanelIssueCountBadge
1485
+ issues={filterState.allValidationIssues}
1486
+ />
1487
+ )}
1482
1488
  </div>
1483
1489
 
1484
1490
  <div className="panel__header__actions">
@@ -37,6 +37,12 @@ import {
37
37
  PanelDivider,
38
38
  SquareIcon,
39
39
  CheckSquareIcon,
40
+ MenuContentItemIcon,
41
+ MenuContentItemLabel,
42
+ ChartIcon,
43
+ CsvIcon,
44
+ DebugIcon,
45
+ ReportIcon,
40
46
  } from '@finos/legend-art';
41
47
  import { observer } from 'mobx-react-lite';
42
48
  import { flowResult } from 'mobx';
@@ -306,6 +312,28 @@ export const QueryBuilderResultPanel = observer(
306
312
  !queryBuilderState.isLocalModeEnabled,
307
313
  );
308
314
  };
315
+
316
+ const extraExportMenuContentItems = applicationStore.pluginManager
317
+ .getApplicationPlugins()
318
+ .flatMap(
319
+ (plugin) =>
320
+ (
321
+ plugin as QueryBuilder_LegendApplicationPlugin_Extension
322
+ ).getExtraQueryBuilderExportMenuActionConfigurations?.() ?? [],
323
+ )
324
+ .map((item) => (
325
+ <MenuContentItem
326
+ key={item.key}
327
+ title={item.title ?? ''}
328
+ onClick={() => {
329
+ item.onClick(queryBuilderState);
330
+ }}
331
+ >
332
+ {item.icon && <MenuContentItemIcon>{item.icon}</MenuContentItemIcon>}
333
+ <MenuContentItemLabel>{item.label}</MenuContentItemLabel>
334
+ </MenuContentItem>
335
+ ));
336
+
309
337
  return (
310
338
  <div
311
339
  data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_PANEL}
@@ -490,14 +518,22 @@ export const QueryBuilderResultPanel = observer(
490
518
  onClick={generatePlan}
491
519
  disabled={isRunQueryDisabled}
492
520
  >
493
- Generate Plan
521
+ <MenuContentItemIcon>
522
+ <ReportIcon />
523
+ </MenuContentItemIcon>
524
+ <MenuContentItemLabel>
525
+ Generate Plan
526
+ </MenuContentItemLabel>
494
527
  </MenuContentItem>
495
528
  <MenuContentItem
496
529
  className="btn__dropdown-combo__option"
497
530
  onClick={debugPlanGeneration}
498
531
  disabled={isRunQueryDisabled}
499
532
  >
500
- Debug
533
+ <MenuContentItemIcon>
534
+ <DebugIcon />
535
+ </MenuContentItemIcon>
536
+ <MenuContentItemLabel>Debug</MenuContentItemLabel>
501
537
  </MenuContentItem>
502
538
  </MenuContent>
503
539
  }
@@ -522,14 +558,15 @@ export const QueryBuilderResultPanel = observer(
522
558
  ).map((format) => (
523
559
  <MenuContentItem
524
560
  key={format}
525
- className="query-builder__result__export__dropdown__menu__item"
526
561
  onClick={(): void => confirmExport(format)}
527
562
  >
528
- {format}
563
+ <MenuContentItemIcon>
564
+ <CsvIcon />
565
+ </MenuContentItemIcon>
566
+ <MenuContentItemLabel>{format}</MenuContentItemLabel>
529
567
  </MenuContentItem>
530
568
  ))}
531
569
  <MenuContentItem
532
- className="query-builder__result__export__dropdown__menu__item"
533
570
  onClick={(): void =>
534
571
  resultState.setIsQueryUsageViewerOpened(true)
535
572
  }
@@ -538,8 +575,12 @@ export const QueryBuilderResultPanel = observer(
538
575
  !isExtraQueryUsageOptionsConfigured
539
576
  }
540
577
  >
541
- Query Code Snippets...
578
+ <MenuContentItemIcon>
579
+ <ChartIcon />
580
+ </MenuContentItemIcon>
581
+ <MenuContentItemLabel>Others...</MenuContentItemLabel>
542
582
  </MenuContentItem>
583
+ {extraExportMenuContentItems}
543
584
  </MenuContent>
544
585
  }
545
586
  menuProps={{
@@ -558,6 +599,22 @@ export const QueryBuilderResultPanel = observer(
558
599
  {resultState.isQueryUsageViewerOpened && (
559
600
  <QueryUsageViewer resultState={resultState} />
560
601
  )}
602
+ {applicationStore.pluginManager
603
+ .getApplicationPlugins()
604
+ .flatMap(
605
+ (plugin) =>
606
+ (
607
+ plugin as QueryBuilder_LegendApplicationPlugin_Extension
608
+ ).getExtraQueryBuilderExportMenuActionConfigurations?.() ??
609
+ [],
610
+ )
611
+ .map((item) => (
612
+ <div key={item.key}>
613
+ {item.renderExtraComponent
614
+ ? item.renderExtraComponent(queryBuilderState)
615
+ : undefined}
616
+ </div>
617
+ ))}
561
618
  </div>
562
619
  </div>
563
620
  <PanelContent>
@@ -33,6 +33,7 @@ import {
33
33
  BasePopover,
34
34
  PanelFormSection,
35
35
  CalculateIcon,
36
+ InputWithInlineValidation,
36
37
  } from '@finos/legend-art';
37
38
  import {
38
39
  type Enum,
@@ -67,6 +68,7 @@ import {
67
68
  parseCSVString,
68
69
  guaranteeIsNumber,
69
70
  csvStringify,
71
+ guaranteeType,
70
72
  } from '@finos/legend-shared';
71
73
  import { flowResult } from 'mobx';
72
74
  import { observer } from 'mobx-react-lite';
@@ -83,7 +85,10 @@ import {
83
85
  } from '../../stores/shared/ValueSpecificationModifierHelper.js';
84
86
  import { CustomDatePicker } from './CustomDatePicker.js';
85
87
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
86
- import { simplifyValueExpression } from '../../stores/QueryBuilderValueSpecificationHelper.js';
88
+ import {
89
+ isValidInstanceValue,
90
+ simplifyValueExpression,
91
+ } from '../../stores/QueryBuilderValueSpecificationHelper.js';
87
92
  import { evaluate } from 'mathjs';
88
93
  import { isUsedDateFunctionSupportedInFormMode } from '../../stores/QueryBuilderStateBuilder.js';
89
94
 
@@ -240,7 +245,7 @@ const StringPrimitiveInstanceValueEditor = observer(
240
245
  } = props;
241
246
  const useSelector = Boolean(selectorConfig);
242
247
  const applicationStore = useApplicationStore();
243
- const value = valueSpecification.values[0] as string;
248
+ const value = valueSpecification.values[0] as string | null;
244
249
  const updateValueSpec = (val: string): void => {
245
250
  instanceValue_setValue(valueSpecification, val, 0, obseverContext);
246
251
  setValueSpecification(valueSpecification);
@@ -295,8 +300,8 @@ const StringPrimitiveInstanceValueEditor = observer(
295
300
  className="value-spec-editor__enum-selector"
296
301
  options={queryOptions}
297
302
  onChange={changeValue}
298
- value={selectedValue}
299
- inputValue={value}
303
+ value={selectedValue.label === '' ? '' : selectedValue}
304
+ inputValue={value ?? ''}
300
305
  onInputChange={handleInputChange}
301
306
  darkMode={
302
307
  !applicationStore.layoutService
@@ -308,15 +313,22 @@ const StringPrimitiveInstanceValueEditor = observer(
308
313
  components={{
309
314
  DropdownIndicator: null,
310
315
  }}
316
+ hasError={!isValidInstanceValue(valueSpecification)}
317
+ placeholder={value === '' ? '(empty)' : undefined}
311
318
  />
312
319
  ) : (
313
- <input
320
+ <InputWithInlineValidation
314
321
  className="panel__content__form__section__input value-spec-editor__input"
315
322
  spellCheck={false}
316
- value={value}
323
+ value={value ?? ''}
317
324
  placeholder={value === '' ? '(empty)' : undefined}
318
325
  onChange={changeInputValue}
319
326
  ref={ref}
327
+ error={
328
+ !isValidInstanceValue(valueSpecification)
329
+ ? 'Invalid String value'
330
+ : undefined
331
+ }
320
332
  />
321
333
  )}
322
334
  <button
@@ -397,26 +409,37 @@ const NumberPrimitiveInstanceValueEditor = observer(
397
409
  obseverContext,
398
410
  } = props;
399
411
  const [value, setValue] = useState(
400
- (valueSpecification.values[0] as number).toString(),
412
+ valueSpecification.values[0] === null
413
+ ? ''
414
+ : (valueSpecification.values[0] as number).toString(),
401
415
  );
402
416
  const inputRef = useRef<HTMLInputElement>(null);
403
417
  useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);
404
- const numericValue = isInteger
405
- ? Number.parseInt(Number(value).toString(), 10)
406
- : Number(value);
418
+ const numericValue = value
419
+ ? isInteger
420
+ ? Number.parseInt(Number(value).toString(), 10)
421
+ : Number(value)
422
+ : null;
407
423
 
408
424
  const updateValueSpecIfValid = (val: string): void => {
409
- const parsedValue = isInteger
410
- ? Number.parseInt(Number(val).toString(), 10)
411
- : Number(val);
412
- if (!isNaN(parsedValue) && parsedValue !== valueSpecification.values[0]) {
413
- instanceValue_setValue(
414
- valueSpecification,
415
- parsedValue,
416
- 0,
417
- obseverContext,
418
- );
419
- setValueSpecification(valueSpecification);
425
+ if (val) {
426
+ const parsedValue = isInteger
427
+ ? Number.parseInt(Number(val).toString(), 10)
428
+ : Number(val);
429
+ if (
430
+ !isNaN(parsedValue) &&
431
+ parsedValue !== valueSpecification.values[0]
432
+ ) {
433
+ instanceValue_setValue(
434
+ valueSpecification,
435
+ parsedValue,
436
+ 0,
437
+ obseverContext,
438
+ );
439
+ setValueSpecification(valueSpecification);
440
+ }
441
+ } else {
442
+ resetValue();
420
443
  }
421
444
  };
422
445
 
@@ -429,20 +452,29 @@ const NumberPrimitiveInstanceValueEditor = observer(
429
452
 
430
453
  // Support expression evaluation
431
454
  const calculateExpression = (): void => {
432
- if (isNaN(numericValue)) {
455
+ if (numericValue !== null && isNaN(numericValue)) {
456
+ // If the value is not a number, try to evaluate it as an expression
433
457
  try {
434
458
  const calculatedValue = guaranteeIsNumber(evaluate(value));
435
459
  updateValueSpecIfValid(calculatedValue.toString());
436
460
  setValue(calculatedValue.toString());
437
461
  } catch {
438
- updateValueSpecIfValid(
439
- (valueSpecification.values[0] as number).toString(),
440
- );
441
- setValue((valueSpecification.values[0] as number).toString());
462
+ // If we fail to evaluate the expression, we just keep the previous value
463
+ const prevValue =
464
+ valueSpecification.values[0] !== null &&
465
+ valueSpecification.values[0] !== undefined
466
+ ? valueSpecification.values[0].toString()
467
+ : '';
468
+ updateValueSpecIfValid(prevValue);
469
+ setValue(prevValue);
442
470
  }
443
- } else {
471
+ } else if (numericValue !== null) {
472
+ // If numericValue is a number, update the value spec
444
473
  updateValueSpecIfValid(numericValue.toString());
445
474
  setValue(numericValue.toString());
475
+ } else {
476
+ // If numericValue is null, reset the value spec
477
+ resetValue();
446
478
  }
447
479
  };
448
480
 
@@ -457,10 +489,15 @@ const NumberPrimitiveInstanceValueEditor = observer(
457
489
 
458
490
  useEffect(() => {
459
491
  if (
492
+ numericValue !== null &&
460
493
  !isNaN(numericValue) &&
461
494
  numericValue !== valueSpecification.values[0]
462
495
  ) {
463
- setValue((valueSpecification.values[0] as number).toString());
496
+ const valueFromValueSpec =
497
+ valueSpecification.values[0] !== null
498
+ ? (valueSpecification.values[0] as number).toString()
499
+ : '';
500
+ setValue(valueFromValueSpec);
464
501
  }
465
502
  }, [numericValue, valueSpecification]);
466
503
 
@@ -469,7 +506,15 @@ const NumberPrimitiveInstanceValueEditor = observer(
469
506
  <div className="value-spec-editor__number__input-container">
470
507
  <input
471
508
  ref={inputRef}
472
- className="panel__content__form__section__input value-spec-editor__input value-spec-editor__number__input"
509
+ className={clsx(
510
+ 'panel__content__form__section__input',
511
+ 'value-spec-editor__input',
512
+ 'value-spec-editor__number__input',
513
+ {
514
+ 'value-spec-editor__number__input--error':
515
+ !isValidInstanceValue(valueSpecification),
516
+ },
517
+ )}
473
518
  spellCheck={false}
474
519
  type="text" // NOTE: we leave this as text so that we can support expression evaluation
475
520
  inputMode="numeric"
@@ -517,9 +562,15 @@ const EnumValueInstanceValueEditor = observer(
517
562
  obseverContext,
518
563
  } = props;
519
564
  const applicationStore = useApplicationStore();
520
- const enumValueRef = guaranteeNonNullable(valueSpecification.values[0]);
521
- const enumValue = enumValueRef.value;
522
- const options = enumValue._OWNER.values.map((value) => ({
565
+ const enumType = guaranteeType(
566
+ valueSpecification.genericType?.value.rawType,
567
+ Enumeration,
568
+ );
569
+ const enumValue =
570
+ valueSpecification.values[0] === undefined
571
+ ? null
572
+ : valueSpecification.values[0].value;
573
+ const options = enumType.values.map((value) => ({
523
574
  label: value.name,
524
575
  value: value,
525
576
  }));
@@ -539,10 +590,12 @@ const EnumValueInstanceValueEditor = observer(
539
590
  className="value-spec-editor__enum-selector"
540
591
  options={options}
541
592
  onChange={changeValue}
542
- value={{ value: enumValue, label: enumValue.name }}
593
+ value={enumValue ? { value: enumValue, label: enumValue.name } : null}
543
594
  darkMode={
544
595
  !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
545
596
  }
597
+ hasError={!isValidInstanceValue(valueSpecification)}
598
+ placeholder="Select value"
546
599
  />
547
600
  <button
548
601
  className="value-spec-editor__reset-btn"
@@ -899,7 +952,12 @@ const CollectionValueInstanceValueEditor = observer(
899
952
  onClick={enableEdit}
900
953
  title="Click to edit"
901
954
  >
902
- <div className="value-spec-editor__list-editor__preview">
955
+ <div
956
+ className={clsx('value-spec-editor__list-editor__preview', {
957
+ 'value-spec-editor__list-editor__preview--error':
958
+ !isValidInstanceValue(valueSpecification),
959
+ })}
960
+ >
903
961
  {previewText}
904
962
  </div>
905
963
  <button className="value-spec-editor__list-editor__edit-icon">
@@ -941,6 +999,10 @@ const DateInstanceValueEditor = observer(
941
999
  observerContext={obseverContext}
942
1000
  typeCheckOption={typeCheckOption}
943
1001
  setValueSpecification={setValueSpecification}
1002
+ hasError={
1003
+ valueSpecification instanceof PrimitiveInstanceValue &&
1004
+ !isValidInstanceValue(valueSpecification)
1005
+ }
944
1006
  />
945
1007
  <button
946
1008
  className="value-spec-editor__reset-btn"