@finos/legend-query-builder 4.14.18 → 4.14.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. package/lib/components/QueryBuilder.d.ts.map +1 -1
  2. package/lib/components/QueryBuilder.js +5 -3
  3. package/lib/components/QueryBuilder.js.map +1 -1
  4. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  5. package/lib/components/QueryBuilderConstantExpressionPanel.js +71 -45
  6. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  7. package/lib/components/QueryBuilderDiffPanel.d.ts.map +1 -1
  8. package/lib/components/QueryBuilderDiffPanel.js +2 -1
  9. package/lib/components/QueryBuilderDiffPanel.js.map +1 -1
  10. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  11. package/lib/components/QueryBuilderParametersPanel.js +25 -26
  12. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  13. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +11 -2
  14. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  15. package/lib/components/QueryBuilderPropertyExpressionEditor.js +35 -10
  16. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  17. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  18. package/lib/components/QueryBuilderSideBar.js +6 -1
  19. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  20. package/lib/components/QueryBuilderTextEditor.d.ts.map +1 -1
  21. package/lib/components/QueryBuilderTextEditor.js +3 -3
  22. package/lib/components/QueryBuilderTextEditor.js.map +1 -1
  23. package/lib/components/QueryLoader.d.ts.map +1 -1
  24. package/lib/components/QueryLoader.js +90 -39
  25. package/lib/components/QueryLoader.js.map +1 -1
  26. package/lib/components/QueryUsageViewer.d.ts.map +1 -1
  27. package/lib/components/QueryUsageViewer.js +2 -2
  28. package/lib/components/QueryUsageViewer.js.map +1 -1
  29. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +2 -0
  30. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
  31. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +19 -2
  32. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  33. package/lib/components/data-access/DataAccessOverview.d.ts.map +1 -1
  34. package/lib/components/data-access/DataAccessOverview.js +6 -1
  35. package/lib/components/data-access/DataAccessOverview.js.map +1 -1
  36. package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
  37. package/lib/components/execution-plan/ExecutionPlanViewer.js +6 -6
  38. package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
  39. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  40. package/lib/components/explorer/QueryBuilderExplorerPanel.js +3 -2
  41. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  42. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  43. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +3 -2
  44. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  45. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
  46. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js +6 -3
  47. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js.map +1 -1
  48. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  49. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +4 -3
  50. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  51. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  52. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +11 -22
  53. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  54. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  55. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +2 -2
  56. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  57. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  58. package/lib/components/result/QueryBuilderResultPanel.js +2 -1
  59. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  60. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  61. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +5 -1
  62. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  63. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  64. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +11 -2
  65. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  66. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  67. package/lib/components/shared/BasicValueSpecificationEditor.js +25 -22
  68. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  69. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  70. package/lib/components/shared/CustomDatePicker.js +8 -5
  71. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  72. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  73. package/lib/components/shared/LambdaEditor.js +17 -3
  74. package/lib/components/shared/LambdaEditor.js.map +1 -1
  75. package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -1
  76. package/lib/components/shared/LambdaParameterValuesEditor.js +2 -2
  77. package/lib/components/shared/LambdaParameterValuesEditor.js.map +1 -1
  78. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +6 -0
  79. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
  80. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +40 -3
  81. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
  82. package/lib/components/watermark/QueryBuilderWatermark.d.ts.map +1 -1
  83. package/lib/components/watermark/QueryBuilderWatermark.js +28 -12
  84. package/lib/components/watermark/QueryBuilderWatermark.js.map +1 -1
  85. package/lib/index.css +17 -1
  86. package/lib/index.css.map +1 -1
  87. package/lib/package.json +1 -1
  88. package/lib/stores/QueryBuilderConstantsState.d.ts +1 -0
  89. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  90. package/lib/stores/QueryBuilderConstantsState.js +7 -1
  91. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  92. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +24 -1
  93. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  94. package/lib/stores/QueryLoaderState.d.ts +14 -4
  95. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  96. package/lib/stores/QueryLoaderState.js +35 -5
  97. package/lib/stores/QueryLoaderState.js.map +1 -1
  98. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts +1 -2
  99. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -1
  100. package/lib/stores/watermark/QueryBuilderWatermarkState.js +2 -12
  101. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -1
  102. package/package.json +8 -8
  103. package/src/components/QueryBuilder.tsx +14 -2
  104. package/src/components/QueryBuilderConstantExpressionPanel.tsx +145 -69
  105. package/src/components/QueryBuilderDiffPanel.tsx +10 -2
  106. package/src/components/QueryBuilderParametersPanel.tsx +42 -37
  107. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +87 -24
  108. package/src/components/QueryBuilderSideBar.tsx +20 -0
  109. package/src/components/QueryBuilderTextEditor.tsx +6 -4
  110. package/src/components/QueryLoader.tsx +291 -130
  111. package/src/components/QueryUsageViewer.tsx +7 -1
  112. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +40 -4
  113. package/src/components/data-access/DataAccessOverview.tsx +9 -1
  114. package/src/components/execution-plan/ExecutionPlanViewer.tsx +11 -8
  115. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +5 -2
  116. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +5 -2
  117. package/src/components/fetch-structure/QueryBuilderGraphFetchTreePanel.tsx +12 -5
  118. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +8 -4
  119. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +56 -72
  120. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +8 -2
  121. package/src/components/result/QueryBuilderResultPanel.tsx +8 -1
  122. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +6 -3
  123. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +14 -4
  124. package/src/components/shared/BasicValueSpecificationEditor.tsx +39 -25
  125. package/src/components/shared/CustomDatePicker.tsx +18 -5
  126. package/src/components/shared/LambdaEditor.tsx +27 -11
  127. package/src/components/shared/LambdaParameterValuesEditor.tsx +4 -1
  128. package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +115 -64
  129. package/src/components/watermark/QueryBuilderWatermark.tsx +60 -19
  130. package/src/stores/QueryBuilderConstantsState.ts +12 -0
  131. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +39 -1
  132. package/src/stores/QueryLoaderState.ts +64 -12
  133. package/src/stores/watermark/QueryBuilderWatermarkState.ts +2 -12
@@ -190,6 +190,7 @@ const VariableExpressionParameterEditor = observer(
190
190
 
191
191
  <button
192
192
  className="value-spec-editor__variable__reset-btn"
193
+ name="Reset"
193
194
  title="Reset"
194
195
  onClick={resetValue}
195
196
  >
@@ -310,6 +311,7 @@ const StringPrimitiveInstanceValueEditor = observer(
310
311
  )}
311
312
  <button
312
313
  className="value-spec-editor__reset-btn"
314
+ name="Reset"
313
315
  title="Reset"
314
316
  onClick={resetValue}
315
317
  >
@@ -353,6 +355,7 @@ const BooleanPrimitiveInstanceValueEditor = observer(
353
355
  </button>
354
356
  <button
355
357
  className="value-spec-editor__reset-btn"
358
+ name="Reset"
356
359
  title="Reset"
357
360
  onClick={resetValue}
358
361
  >
@@ -388,8 +391,26 @@ const NumberPrimitiveInstanceValueEditor = observer(
388
391
  ? Number.parseInt(Number(value).toString(), 10)
389
392
  : Number(value);
390
393
 
391
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
394
+ const updateValueSpecIfValid = (val: string): void => {
395
+ const parsedValue = isInteger
396
+ ? Number.parseInt(Number(val).toString(), 10)
397
+ : Number(val);
398
+ if (!isNaN(parsedValue) && parsedValue !== valueSpecification.values[0]) {
399
+ instanceValue_setValue(
400
+ valueSpecification,
401
+ parsedValue,
402
+ 0,
403
+ obseverContext,
404
+ );
405
+ setValueSpecification(valueSpecification);
406
+ }
407
+ };
408
+
409
+ const handleInputChange: React.ChangeEventHandler<HTMLInputElement> = (
410
+ event,
411
+ ) => {
392
412
  setValue(event.target.value);
413
+ updateValueSpecIfValid(event.target.value);
393
414
  };
394
415
 
395
416
  // Support expression evaluation
@@ -397,15 +418,16 @@ const NumberPrimitiveInstanceValueEditor = observer(
397
418
  if (isNaN(numericValue)) {
398
419
  try {
399
420
  const calculatedValue = guaranteeIsNumber(evaluate(value));
400
- setValue(
401
- isInteger
402
- ? Number.parseInt(calculatedValue.toString(), 10).toString()
403
- : Number(calculatedValue).toString(),
404
- );
421
+ updateValueSpecIfValid(calculatedValue.toString());
422
+ setValue(calculatedValue.toString());
405
423
  } catch {
424
+ updateValueSpecIfValid(
425
+ (valueSpecification.values[0] as number).toString(),
426
+ );
406
427
  setValue((valueSpecification.values[0] as number).toString());
407
428
  }
408
429
  } else {
430
+ updateValueSpecIfValid(numericValue.toString());
409
431
  setValue(numericValue.toString());
410
432
  }
411
433
  };
@@ -419,29 +441,14 @@ const NumberPrimitiveInstanceValueEditor = observer(
419
441
  }
420
442
  };
421
443
 
422
- useEffect(() => {
423
- setValue((valueSpecification.values[0] as number).toString());
424
- }, [valueSpecification]);
425
-
426
444
  useEffect(() => {
427
445
  if (
428
446
  !isNaN(numericValue) &&
429
447
  numericValue !== valueSpecification.values[0]
430
448
  ) {
431
- instanceValue_setValue(
432
- valueSpecification,
433
- numericValue,
434
- 0,
435
- obseverContext,
436
- );
437
- setValueSpecification(valueSpecification);
449
+ setValue((valueSpecification.values[0] as number).toString());
438
450
  }
439
- }, [
440
- numericValue,
441
- valueSpecification,
442
- setValueSpecification,
443
- obseverContext,
444
- ]);
451
+ }, [numericValue, valueSpecification]);
445
452
 
446
453
  return (
447
454
  <div className={clsx('value-spec-editor', className)}>
@@ -453,7 +460,7 @@ const NumberPrimitiveInstanceValueEditor = observer(
453
460
  type="text" // NOTE: we leave this as text so that we can support expression evaluation
454
461
  inputMode="numeric"
455
462
  value={value}
456
- onChange={changeValue}
463
+ onChange={handleInputChange}
457
464
  onBlur={calculateExpression}
458
465
  onKeyDown={onKeyDown}
459
466
  />
@@ -469,6 +476,7 @@ const NumberPrimitiveInstanceValueEditor = observer(
469
476
  </div>
470
477
  <button
471
478
  className="value-spec-editor__reset-btn"
479
+ name="Reset"
472
480
  title="Reset"
473
481
  onClick={resetValue}
474
482
  >
@@ -494,6 +502,7 @@ const EnumValueInstanceValueEditor = observer(
494
502
  setValueSpecification,
495
503
  obseverContext,
496
504
  } = props;
505
+ const applicationStore = useApplicationStore();
497
506
  const enumValueRef = guaranteeNonNullable(valueSpecification.values[0]);
498
507
  const enumValue = enumValueRef.value;
499
508
  const options = enumValue._OWNER.values.map((value) => ({
@@ -517,10 +526,13 @@ const EnumValueInstanceValueEditor = observer(
517
526
  options={options}
518
527
  onChange={changeValue}
519
528
  value={{ value: enumValue, label: enumValue.name }}
520
- darkMode={true}
529
+ darkMode={
530
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
531
+ }
521
532
  />
522
533
  <button
523
534
  className="value-spec-editor__reset-btn"
535
+ name="Reset"
524
536
  title="Reset"
525
537
  onClick={resetValue}
526
538
  >
@@ -857,6 +869,7 @@ const CollectionValueInstanceValueEditor = observer(
857
869
  </button>
858
870
  <button
859
871
  className="value-spec-editor__reset-btn"
872
+ name="Reset"
860
873
  title="Reset"
861
874
  onClick={resetValue}
862
875
  >
@@ -917,6 +930,7 @@ const DateInstanceValueEditor = observer(
917
930
  />
918
931
  <button
919
932
  className="value-spec-editor__reset-btn"
933
+ name="Reset"
920
934
  title="Reset"
921
935
  onClick={resetValue}
922
936
  >
@@ -913,6 +913,7 @@ const CustomDateInstanceValueEditor: React.FC<{
913
913
  setDatePickerOption,
914
914
  observerContext,
915
915
  } = props;
916
+ const applicationStore = useApplicationStore();
916
917
  const inputRef = useRef<HTMLInputElement>(null);
917
918
  const [durationValue, setDurationValue] = useState(
918
919
  customDateOptionValue.duration,
@@ -1015,7 +1016,9 @@ const CustomDateInstanceValueEditor: React.FC<{
1015
1016
  );
1016
1017
  }}
1017
1018
  value={{ value: unitValue, label: unitValue }}
1018
- darkMode={true}
1019
+ darkMode={
1020
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
1021
+ }
1019
1022
  />
1020
1023
  </div>
1021
1024
  <div className="value-spec-editor__date-picker__custom-date__input">
@@ -1038,7 +1041,9 @@ const CustomDateInstanceValueEditor: React.FC<{
1038
1041
  );
1039
1042
  }}
1040
1043
  value={{ value: directionValue, label: directionValue }}
1041
- darkMode={true}
1044
+ darkMode={
1045
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
1046
+ }
1042
1047
  />
1043
1048
  </div>
1044
1049
  <div className="value-spec-editor__date-picker__custom-date__input">
@@ -1058,7 +1063,9 @@ const CustomDateInstanceValueEditor: React.FC<{
1058
1063
  changeValue(durationValue, unitValue, directionValue, val.value);
1059
1064
  }}
1060
1065
  value={{ value: referenceMomentValue, label: referenceMomentValue }}
1061
- darkMode={true}
1066
+ darkMode={
1067
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
1068
+ }
1062
1069
  />
1063
1070
  </div>
1064
1071
  </div>
@@ -1079,6 +1086,7 @@ const CustomFirstDayOfValueSpecificationEditor: React.FC<{
1079
1086
  setValueSpecification,
1080
1087
  setDatePickerOption,
1081
1088
  } = props;
1089
+ const applicationStore = useApplicationStore();
1082
1090
  const selectorRef = useRef<SelectComponent>(null);
1083
1091
  const [unitValue, setUnitValue] = useState(
1084
1092
  customDateAdjustOptionValue instanceof CustomFirstDayOfOption
@@ -1130,7 +1138,9 @@ const CustomFirstDayOfValueSpecificationEditor: React.FC<{
1130
1138
  }
1131
1139
  }}
1132
1140
  value={unitValue ? { value: unitValue, label: unitValue } : null}
1133
- darkMode={true}
1141
+ darkMode={
1142
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
1143
+ }
1134
1144
  />
1135
1145
  </div>
1136
1146
  </div>
@@ -1151,6 +1161,7 @@ const CustomPreviousDayOfWeekValueSpecificationEditor: React.FC<{
1151
1161
  setValueSpecification,
1152
1162
  setDatePickerOption,
1153
1163
  } = props;
1164
+ const applicationStore = useApplicationStore();
1154
1165
  const selectorRef = useRef<SelectComponent>(null);
1155
1166
  const [dayOfWeekValue, setDayOfWeekValue] = useState(
1156
1167
  customDateAdjustOptionValue instanceof CustomPreviousDayOfWeekOption
@@ -1200,7 +1211,9 @@ const CustomPreviousDayOfWeekValueSpecificationEditor: React.FC<{
1200
1211
  ? { value: dayOfWeekValue, label: dayOfWeekValue }
1201
1212
  : null
1202
1213
  }
1203
- darkMode={true}
1214
+ darkMode={
1215
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
1216
+ }
1204
1217
  />
1205
1218
  </div>
1206
1219
  </div>
@@ -28,6 +28,7 @@ import {
28
28
  ModalFooter,
29
29
  ModalHeader,
30
30
  ModalTitle,
31
+ ModalFooterButton,
31
32
  } from '@finos/legend-art';
32
33
  import {
33
34
  disposeCodeEditor,
@@ -224,6 +225,21 @@ const LambdaEditor_Inner = observer(
224
225
  }
225
226
  }, [editor, isExpanded]);
226
227
 
228
+ // set styling when theme changes
229
+ useEffect(() => {
230
+ if (editor) {
231
+ editor.updateOptions({
232
+ theme: applicationStore.layoutService
233
+ .TEMPORARY__isLightColorThemeEnabled
234
+ ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
235
+ : CODE_EDITOR_THEME.DEFAULT_DARK,
236
+ });
237
+ }
238
+ }, [
239
+ editor,
240
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
241
+ ]);
242
+
227
243
  // set backdrop to force user to fix parser error when it happens
228
244
  useEffect(() => {
229
245
  if (parserError) {
@@ -605,7 +621,9 @@ const LambdaEditor_PopUp = observer(
605
621
  }}
606
622
  >
607
623
  <Modal
608
- darkMode={true}
624
+ darkMode={
625
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
626
+ }
609
627
  className={clsx(
610
628
  'editor-modal lambda-editor__popup__modal',
611
629
  {
@@ -639,19 +657,17 @@ const LambdaEditor_PopUp = observer(
639
657
  </div>
640
658
  </ModalBody>
641
659
  <ModalFooter>
642
- <button
643
- className="btn btn--dark btn--caution"
660
+ <ModalFooterButton
661
+ className="btn--caution"
662
+ text="Discard changes"
644
663
  onClick={discardChanges}
645
- >
646
- Discard changes
647
- </button>
648
- <button
649
- className="btn btn--dark"
664
+ />
665
+ <ModalFooterButton
666
+ text="Close"
650
667
  onClick={onClose}
651
668
  disabled={Boolean(lambdaEditorState.parserError)}
652
- >
653
- Close
654
- </button>
669
+ type="secondary"
670
+ />
655
671
  </ModalFooter>
656
672
  </Modal>
657
673
  </Dialog>
@@ -71,7 +71,9 @@ export const LambdaParameterValuesEditor = observer(
71
71
  }}
72
72
  >
73
73
  <Modal
74
- darkMode={true}
74
+ darkMode={
75
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
76
+ }
75
77
  className="editor-modal lambda-parameter-values__modal"
76
78
  >
77
79
  <ModalHeader title="Set Parameter Values" />
@@ -131,6 +133,7 @@ export const LambdaParameterValuesEditor = observer(
131
133
  inProgressText={isClosingAction ? 'Closing...' : undefined}
132
134
  onClick={close}
133
135
  text="Close"
136
+ type="secondary"
134
137
  />
135
138
  </ModalFooter>
136
139
  </Modal>
@@ -117,26 +117,18 @@ export const QueryBuilderTaggedValueInfoTooltip: React.FC<{
117
117
  );
118
118
  };
119
119
 
120
- export const QueryBuilderPropertyInfoTooltip: React.FC<{
120
+ const QueryBuilderBaseInfoTooltip: React.FC<{
121
121
  title: string;
122
- property: AbstractProperty;
123
- path: string;
124
- isMapped: boolean;
125
- children: React.ReactElement;
122
+ data: {
123
+ label: string;
124
+ value: string;
125
+ actionButton?: JSX.Element | undefined;
126
+ }[];
126
127
  placement?: TooltipPlacement | undefined;
127
- type?: Type | undefined;
128
- explorerState?: QueryBuilderExplorerState | undefined;
128
+ children: React.ReactElement;
129
+ footerElement?: React.ReactElement;
129
130
  }> = (props) => {
130
- const {
131
- title,
132
- property,
133
- path,
134
- isMapped,
135
- children,
136
- placement,
137
- type,
138
- explorerState,
139
- } = props;
131
+ const { title, data, placement, children, footerElement } = props;
140
132
 
141
133
  const [open, setIsOpen] = useState(false);
142
134
 
@@ -165,55 +157,18 @@ export const QueryBuilderPropertyInfoTooltip: React.FC<{
165
157
  title={
166
158
  <div className="query-builder__tooltip__content">
167
159
  <div className="query-builder__tooltip__header">{title}</div>
168
- <div className="query-builder__tooltip__item">
169
- <div className="query-builder__tooltip__item__label">Type</div>
170
- <div className="query-builder__tooltip__item__value">
171
- {type?.path ?? property.genericType.value.rawType.path}
172
- </div>
173
- </div>
174
- <div className="query-builder__tooltip__item">
175
- <div className="query-builder__tooltip__item__label">Path</div>
176
- <div className="query-builder__tooltip__item__value">
177
- {path}
178
- </div>
179
- {explorerState && (
180
- <div className="query-builder__tooltip__item__action">
181
- <button
182
- onClick={() => explorerState.highlightTreeNode(path)}
183
- title="Show in tree"
184
- >
185
- <ShareBoxIcon color="white" />
186
- </button>
160
+ {data.map((elem) => (
161
+ <div key={elem.label} className="query-builder__tooltip__item">
162
+ <div className="query-builder__tooltip__item__label">
163
+ {elem.label}
187
164
  </div>
188
- )}
189
- </div>
190
- <div className="query-builder__tooltip__item">
191
- <div className="query-builder__tooltip__item__label">
192
- Multiplicity
193
- </div>
194
- <div className="query-builder__tooltip__item__value">
195
- {getMultiplicityDescription(property.multiplicity)}
196
- </div>
197
- </div>
198
- <div className="query-builder__tooltip__item">
199
- <div className="query-builder__tooltip__item__label">
200
- Derived Property
201
- </div>
202
- <div className="query-builder__tooltip__item__value">
203
- {property instanceof DerivedProperty ? 'Yes' : 'No'}
204
- </div>
205
- </div>
206
- <div className="query-builder__tooltip__item">
207
- <div className="query-builder__tooltip__item__label">
208
- Mapped
209
- </div>
210
- <div className="query-builder__tooltip__item__value">
211
- {isMapped ? 'Yes' : 'No'}
165
+ <div className="query-builder__tooltip__item__value">
166
+ {elem.value}
167
+ </div>
168
+ {elem.actionButton}
212
169
  </div>
213
- </div>
214
- <QueryBuilderTaggedValueInfoTooltip
215
- taggedValues={property.taggedValues}
216
- />
170
+ ))}
171
+ {footerElement}
217
172
  </div>
218
173
  }
219
174
  >
@@ -223,3 +178,99 @@ export const QueryBuilderPropertyInfoTooltip: React.FC<{
223
178
  </ClickAwayListener>
224
179
  );
225
180
  };
181
+
182
+ export const QueryBuilderPropertyInfoTooltip: React.FC<{
183
+ title: string;
184
+ property: AbstractProperty;
185
+ path: string;
186
+ isMapped: boolean;
187
+ children: React.ReactElement;
188
+ placement?: TooltipPlacement | undefined;
189
+ type?: Type | undefined;
190
+ explorerState?: QueryBuilderExplorerState | undefined;
191
+ }> = (props) => {
192
+ const {
193
+ title,
194
+ property,
195
+ path,
196
+ isMapped,
197
+ children,
198
+ placement,
199
+ type,
200
+ explorerState,
201
+ } = props;
202
+
203
+ const data = [
204
+ {
205
+ label: 'Type',
206
+ value: type?.path ?? property.genericType.value.rawType.path,
207
+ },
208
+ {
209
+ label: 'Path',
210
+ value: path,
211
+ actionButton: explorerState ? (
212
+ <div className="query-builder__tooltip__item__action">
213
+ <button
214
+ onClick={() => explorerState.highlightTreeNode(path)}
215
+ title="Show in tree"
216
+ >
217
+ <ShareBoxIcon color="white" />
218
+ </button>
219
+ </div>
220
+ ) : undefined,
221
+ },
222
+ {
223
+ label: 'Multiplicity',
224
+ value: getMultiplicityDescription(property.multiplicity),
225
+ },
226
+ {
227
+ label: 'Derived Property',
228
+ value: property instanceof DerivedProperty ? 'Yes' : 'No',
229
+ },
230
+ {
231
+ label: 'Mapped',
232
+ value: isMapped ? 'Yes' : 'No',
233
+ },
234
+ ];
235
+
236
+ return (
237
+ <QueryBuilderBaseInfoTooltip
238
+ title={title}
239
+ data={data}
240
+ placement={placement}
241
+ footerElement={
242
+ <QueryBuilderTaggedValueInfoTooltip
243
+ taggedValues={property.taggedValues}
244
+ />
245
+ }
246
+ >
247
+ {children}
248
+ </QueryBuilderBaseInfoTooltip>
249
+ );
250
+ };
251
+
252
+ export const QueryBuilderDerivationInfoTooltip: React.FC<{
253
+ title: string;
254
+ children: React.ReactElement;
255
+ placement?: TooltipPlacement | undefined;
256
+ type?: Type | undefined;
257
+ }> = (props) => {
258
+ const { title, children, placement, type } = props;
259
+
260
+ const data = [
261
+ {
262
+ label: 'Type',
263
+ value: type?.path ?? 'undefined',
264
+ },
265
+ ];
266
+
267
+ return (
268
+ <QueryBuilderBaseInfoTooltip
269
+ title={title}
270
+ data={data}
271
+ placement={placement}
272
+ >
273
+ {children}
274
+ </QueryBuilderBaseInfoTooltip>
275
+ );
276
+ };
@@ -35,7 +35,7 @@ import {
35
35
  type ValueSpecification,
36
36
  } from '@finos/legend-graph';
37
37
  import { observer } from 'mobx-react-lite';
38
- import { useCallback } from 'react';
38
+ import { useCallback, useState } from 'react';
39
39
  import { useDrop } from 'react-dnd';
40
40
  import type { QueryBuilderState } from '../../stores/QueryBuilderState.js';
41
41
  import type { QueryBuilderWatermarkState } from '../../stores/watermark/QueryBuilderWatermarkState.js';
@@ -45,6 +45,7 @@ import {
45
45
  type QueryBuilderVariableDragSource,
46
46
  } from '../shared/BasicValueSpecificationEditor.js';
47
47
  import { VariableSelector } from '../shared/QueryBuilderVariableSelector.js';
48
+ import { clone, deepClone } from '@finos/legend-shared';
48
49
 
49
50
  const isParamaterCompatibleWithWaterMark = (
50
51
  parameter: VariableExpression,
@@ -54,18 +55,25 @@ const isParamaterCompatibleWithWaterMark = (
54
55
 
55
56
  const WatermarkValueEditor = observer(
56
57
  (props: {
57
- watermarkValue: ValueSpecification;
58
+ selectedValue: ValueSpecification;
59
+ setSelectedValue: (val: ValueSpecification) => void;
60
+ handleResetValue: () => void;
58
61
  watermarkState: QueryBuilderWatermarkState;
59
62
  }) => {
60
- const { watermarkValue, watermarkState } = props;
63
+ const {
64
+ selectedValue,
65
+ setSelectedValue,
66
+ handleResetValue,
67
+ watermarkState,
68
+ } = props;
61
69
 
62
70
  const graph = watermarkState.queryBuilderState.graphManagerState.graph;
63
71
 
64
72
  const handleDrop = useCallback(
65
73
  (item: QueryBuilderVariableDragSource): void => {
66
- watermarkState.setValue(item.variable);
74
+ setSelectedValue(item.variable);
67
75
  },
68
- [watermarkState],
76
+ [setSelectedValue],
69
77
  );
70
78
 
71
79
  const [{ isParameterValueDragOver }, dropTargetConnector] = useDrop<
@@ -101,20 +109,18 @@ const WatermarkValueEditor = observer(
101
109
  dropTargetConnector={dropTargetConnector}
102
110
  >
103
111
  <BasicValueSpecificationEditor
104
- valueSpecification={watermarkValue}
112
+ valueSpecification={selectedValue}
105
113
  setValueSpecification={(val: ValueSpecification): void => {
106
- watermarkState.setValue(val);
114
+ setSelectedValue(clone(val));
107
115
  }}
108
116
  graph={graph}
109
117
  obseverContext={watermarkState.queryBuilderState.observerContext}
110
118
  typeCheckOption={{
111
119
  expectedType: PrimitiveType.STRING,
112
120
  }}
113
- resetValue={(): void => {
114
- watermarkState.resetValue();
115
- }}
121
+ resetValue={handleResetValue}
116
122
  isConstant={watermarkState.queryBuilderState.constantState.isValueSpecConstant(
117
- watermarkValue,
123
+ selectedValue,
118
124
  )}
119
125
  />
120
126
  </PanelDropZone>
@@ -127,36 +133,66 @@ const WatermarkValueEditor = observer(
127
133
  export const QueryBuilderWatermarkEditor = observer(
128
134
  (props: { queryBuilderState: QueryBuilderState }) => {
129
135
  const { queryBuilderState } = props;
136
+ const applicationStore = queryBuilderState.applicationStore;
130
137
  const watermarkState = queryBuilderState.watermarkState;
131
- const handleClose = (): void => {
138
+
139
+ const [selectedValue, setSelectedValue] = useState(
140
+ deepClone(watermarkState.value),
141
+ );
142
+
143
+ const handleCancel = (): void => {
132
144
  watermarkState.setIsEditingWatermark(false);
133
145
  };
134
146
 
147
+ const handleApply = (): void => {
148
+ watermarkState.setValue(selectedValue);
149
+ handleCancel();
150
+ };
151
+
152
+ const handleResetValue = (): void => {
153
+ setSelectedValue(watermarkState.getDefaultValue());
154
+ };
155
+
156
+ const toggleWatermark = (): void => {
157
+ if (selectedValue) {
158
+ setSelectedValue(undefined);
159
+ } else {
160
+ handleResetValue();
161
+ }
162
+ };
163
+
135
164
  return (
136
165
  <Dialog
137
166
  open={Boolean(watermarkState.isEditingWatermark)}
138
- onClose={handleClose}
167
+ onClose={handleCancel}
139
168
  classes={{
140
169
  root: 'editor-modal__root-container',
141
170
  container: 'editor-modal__container',
142
171
  paper: 'editor-modal__content',
143
172
  }}
144
173
  >
145
- <Modal darkMode={true} className="editor-modal">
174
+ <Modal
175
+ darkMode={
176
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
177
+ }
178
+ className="editor-modal query-builder__watermark__modal"
179
+ >
146
180
  <ModalHeader title="Watermark" />
147
181
  <ModalBody>
148
182
  <PanelForm>
149
183
  <PanelFormBooleanField
150
184
  isReadOnly={false}
151
- value={watermarkState.value !== undefined}
185
+ value={selectedValue !== undefined}
152
186
  prompt="Enable watermark"
153
- update={(): void => watermarkState.enableWatermark()}
187
+ update={toggleWatermark}
154
188
  />
155
- {watermarkState.value && (
189
+ {selectedValue && (
156
190
  <>
157
191
  <WatermarkValueEditor
192
+ selectedValue={selectedValue}
193
+ setSelectedValue={setSelectedValue}
194
+ handleResetValue={handleResetValue}
158
195
  watermarkState={watermarkState}
159
- watermarkValue={watermarkState.value}
160
196
  />
161
197
  <PanelDivider />
162
198
  <VariableSelector
@@ -168,7 +204,12 @@ export const QueryBuilderWatermarkEditor = observer(
168
204
  </PanelForm>
169
205
  </ModalBody>
170
206
  <ModalFooter>
171
- <ModalFooterButton text="Done" onClick={handleClose} />
207
+ <ModalFooterButton text="Apply" onClick={handleApply} />
208
+ <ModalFooterButton
209
+ text="Cancel"
210
+ onClick={handleCancel}
211
+ type="secondary"
212
+ />
172
213
  </ModalFooter>
173
214
  </Modal>
174
215
  </Dialog>