@finos/legend-query-builder 4.14.18 → 4.14.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>