@finos/legend-query-builder 4.14.37 → 4.14.39

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 (94) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +2 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilder.d.ts.map +1 -1
  6. package/lib/components/QueryBuilder.js +10 -9
  7. package/lib/components/QueryBuilder.js.map +1 -1
  8. package/lib/components/QueryBuilderParametersPanel.js +2 -2
  9. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  10. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +0 -2
  11. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  12. package/lib/components/QueryBuilderPropertyExpressionEditor.js +10 -26
  13. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  14. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  15. package/lib/components/QueryBuilderSideBar.js +3 -3
  16. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  17. package/lib/components/QueryBuilderTextEditor.d.ts.map +1 -1
  18. package/lib/components/QueryBuilderTextEditor.js +17 -3
  19. package/lib/components/QueryBuilderTextEditor.js.map +1 -1
  20. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts +5 -0
  21. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  22. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +10 -5
  23. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  24. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +45 -12
  26. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  27. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +13 -5
  29. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  30. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  31. package/lib/components/filter/QueryBuilderFilterPanel.js +1 -2
  32. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  33. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  34. package/lib/components/result/QueryBuilderResultPanel.js +6 -5
  35. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  36. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  37. package/lib/components/shared/BasicValueSpecificationEditor.js +49 -8
  38. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  39. package/lib/components/workflows/ClassQueryBuilder.d.ts.map +1 -1
  40. package/lib/components/workflows/ClassQueryBuilder.js +3 -3
  41. package/lib/components/workflows/ClassQueryBuilder.js.map +1 -1
  42. package/lib/components/workflows/MappingQueryBuilder.d.ts.map +1 -1
  43. package/lib/components/workflows/MappingQueryBuilder.js +3 -3
  44. package/lib/components/workflows/MappingQueryBuilder.js.map +1 -1
  45. package/lib/components/workflows/ServiceQueryBuilder.d.ts.map +1 -1
  46. package/lib/components/workflows/ServiceQueryBuilder.js +3 -3
  47. package/lib/components/workflows/ServiceQueryBuilder.js.map +1 -1
  48. package/lib/index.css +2 -2
  49. package/lib/index.css.map +1 -1
  50. package/lib/package.json +1 -1
  51. package/lib/stores/QueryBuilderTextEditorState.d.ts +4 -1
  52. package/lib/stores/QueryBuilderTextEditorState.d.ts.map +1 -1
  53. package/lib/stores/QueryBuilderTextEditorState.js +19 -2
  54. package/lib/stores/QueryBuilderTextEditorState.js.map +1 -1
  55. package/lib/stores/QueryLoaderState.d.ts +2 -2
  56. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  57. package/lib/stores/QueryLoaderState.js +3 -3
  58. package/lib/stores/QueryLoaderState.js.map +1 -1
  59. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts +1 -1
  60. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts.map +1 -1
  61. package/lib/stores/explorer/QueryFunctionsExplorerState.js +2 -1
  62. package/lib/stores/explorer/QueryFunctionsExplorerState.js.map +1 -1
  63. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +1 -0
  64. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  65. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +8 -0
  66. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  67. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts.map +1 -1
  68. package/lib/stores/milestoning/QueryBuilderMilestoningState.js +9 -3
  69. package/lib/stores/milestoning/QueryBuilderMilestoningState.js.map +1 -1
  70. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -1
  71. package/lib/stores/watermark/QueryBuilderWatermarkState.js +0 -1
  72. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -1
  73. package/package.json +8 -8
  74. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  75. package/src/components/QueryBuilder.tsx +16 -15
  76. package/src/components/QueryBuilderParametersPanel.tsx +2 -2
  77. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +40 -92
  78. package/src/components/QueryBuilderSideBar.tsx +3 -2
  79. package/src/components/QueryBuilderTextEditor.tsx +46 -11
  80. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +60 -46
  81. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +78 -34
  82. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +121 -34
  83. package/src/components/filter/QueryBuilderFilterPanel.tsx +0 -11
  84. package/src/components/result/QueryBuilderResultPanel.tsx +21 -23
  85. package/src/components/shared/BasicValueSpecificationEditor.tsx +141 -34
  86. package/src/components/workflows/ClassQueryBuilder.tsx +3 -2
  87. package/src/components/workflows/MappingQueryBuilder.tsx +3 -2
  88. package/src/components/workflows/ServiceQueryBuilder.tsx +7 -3
  89. package/src/stores/QueryBuilderTextEditorState.ts +20 -2
  90. package/src/stores/QueryLoaderState.ts +5 -7
  91. package/src/stores/explorer/QueryFunctionsExplorerState.ts +6 -2
  92. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +11 -0
  93. package/src/stores/milestoning/QueryBuilderMilestoningState.ts +11 -7
  94. package/src/stores/watermark/QueryBuilderWatermarkState.ts +0 -1
@@ -16,7 +16,6 @@
16
16
 
17
17
  import {
18
18
  BlankPanelContent,
19
- PanelLoadingIndicator,
20
19
  PlayIcon,
21
20
  DropdownMenu,
22
21
  MenuContent,
@@ -43,6 +42,8 @@ import {
43
42
  CsvIcon,
44
43
  DebugIcon,
45
44
  ReportIcon,
45
+ CubesLoadingIndicatorIcon,
46
+ CubesLoadingIndicator,
46
47
  } from '@finos/legend-art';
47
48
  import { observer } from 'mobx-react-lite';
48
49
  import { flowResult } from 'mobx';
@@ -334,6 +335,9 @@ export const QueryBuilderResultPanel = observer(
334
335
  </MenuContentItem>
335
336
  ));
336
337
 
338
+ const isLoading =
339
+ resultState.isRunningQuery || resultState.isGeneratingPlan;
340
+
337
341
  return (
338
342
  <div
339
343
  data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_PANEL}
@@ -383,7 +387,7 @@ export const QueryBuilderResultPanel = observer(
383
387
 
384
388
  <div className="panel__header">
385
389
  <div className="panel__header__title">
386
- <div className="panel__header__title__label">result</div>
390
+ <div className="panel__header__title__label">results</div>
387
391
  {executedSql && (
388
392
  <Button
389
393
  onClick={() => setShowSqlModal(true)}
@@ -457,7 +461,7 @@ export const QueryBuilderResultPanel = observer(
457
461
  {allowSettingPreviewLimit && (
458
462
  <div className="query-builder__result__limit">
459
463
  <div className="query-builder__result__limit__label">
460
- preview limit
464
+ preview row limit
461
465
  </div>
462
466
  <input
463
467
  ref={inputRef}
@@ -476,22 +480,20 @@ export const QueryBuilderResultPanel = observer(
476
480
  <div className="query-builder__result__execute-btn btn__dropdown-combo btn__dropdown-combo--primary">
477
481
  {resultState.isRunningQuery ? (
478
482
  <button
479
- className="btn__dropdown-combo__canceler"
483
+ className="btn__dropdown-combo__canceler query-builder__result__execute-btn__btn"
480
484
  onClick={cancelQuery}
481
485
  tabIndex={-1}
482
486
  disabled={!isQueryValid}
483
487
  >
484
- <div className="btn--dark btn--caution btn__dropdown-combo__canceler__label">
485
- <PauseCircleIcon className="btn__dropdown-combo__canceler__label__icon" />
486
- <div className="btn__dropdown-combo__canceler__label__title">
487
- Stop
488
- </div>
488
+ <div className="btn--dark btn--caution btn__dropdown-combo__canceler__label query-builder__result__execute-btn__btn">
489
+ <PauseCircleIcon />
490
+ Stop
489
491
  </div>
490
492
  </button>
491
493
  ) : (
492
494
  <>
493
495
  <button
494
- className="btn__dropdown-combo__label"
496
+ className="btn__dropdown-combo__label query-builder__result__execute-btn__btn query-builder__result__execute-btn__btn--green"
495
497
  onClick={runQuery}
496
498
  tabIndex={-1}
497
499
  title={
@@ -503,13 +505,11 @@ export const QueryBuilderResultPanel = observer(
503
505
  }
504
506
  disabled={isRunQueryDisabled}
505
507
  >
506
- <PlayIcon className="btn__dropdown-combo__label__icon" />
507
- <div className="btn__dropdown-combo__label__title">
508
- Run Query
509
- </div>
508
+ <PlayIcon />
509
+ Run Query
510
510
  </button>
511
511
  <DropdownMenu
512
- className="btn__dropdown-combo__dropdown-btn"
512
+ className="btn__dropdown-combo__dropdown-btn query-builder__result__execute-btn__btn query-builder__result__execute-btn__btn--green"
513
513
  disabled={isRunQueryDisabled}
514
514
  content={
515
515
  <MenuContent>
@@ -617,18 +617,16 @@ export const QueryBuilderResultPanel = observer(
617
617
  ))}
618
618
  </div>
619
619
  </div>
620
- <PanelContent>
621
- <PanelLoadingIndicator
622
- isLoading={
623
- resultState.isRunningQuery || resultState.isGeneratingPlan
624
- }
625
- />
626
- {!executionResult && (
620
+ <PanelContent className="query-builder__result__content">
621
+ <CubesLoadingIndicator isLoading={isLoading}>
622
+ <CubesLoadingIndicatorIcon />
623
+ </CubesLoadingIndicator>
624
+ {!executionResult && !isLoading && (
627
625
  <BlankPanelContent>
628
626
  Build or load a valid query first
629
627
  </BlankPanelContent>
630
628
  )}
631
- {executionResult && (
629
+ {executionResult && !isLoading && (
632
630
  <div className="query-builder__result__values">
633
631
  <QueryBuilderResultValues
634
632
  executionResult={executionResult}
@@ -776,6 +776,98 @@ const setCollectionValue = (
776
776
  instanceValue_setValues(valueSpecification, result, obseverContext);
777
777
  };
778
778
 
779
+ const EnumCollectionInstanceValueEditor = observer(
780
+ (props: {
781
+ valueSpecification: CollectionInstanceValue;
782
+ observerContext: ObserverContext;
783
+ saveEdit: () => void;
784
+ }) => {
785
+ const { valueSpecification, observerContext, saveEdit } = props;
786
+ const applicationStore = useApplicationStore();
787
+ const enumType = guaranteeType(
788
+ valueSpecification.genericType?.value.rawType,
789
+ Enumeration,
790
+ );
791
+
792
+ const [selectedOptions, setSelectedOptions] = useState<
793
+ { label: string; value: Enum }[]
794
+ >(
795
+ (valueSpecification.values as EnumValueInstanceValue[])
796
+ .filter((valueSpec) => valueSpec.values[0]?.value !== undefined)
797
+ .map((valueSpec) => ({
798
+ label: valueSpec.values[0]!.value.name,
799
+ value: valueSpec.values[0]!.value,
800
+ })),
801
+ );
802
+
803
+ const availableOptions = enumType.values
804
+ .filter(
805
+ (value) =>
806
+ !selectedOptions.some(
807
+ (selectedValue) => selectedValue.value.name === value.name,
808
+ ),
809
+ )
810
+ .map((value) => ({
811
+ label: value.name,
812
+ value: value,
813
+ }));
814
+
815
+ const changeValue = (
816
+ newSelectedOptions: { value: Enum; label: string }[],
817
+ ): void => {
818
+ setSelectedOptions(newSelectedOptions);
819
+ };
820
+
821
+ const updateValueSpecAndSaveEdit = (): void => {
822
+ const result = selectedOptions
823
+ .map((value) => {
824
+ const enumValueInstanceValue = new EnumValueInstanceValue(
825
+ GenericTypeExplicitReference.create(new GenericType(enumType)),
826
+ );
827
+ instanceValue_setValues(
828
+ enumValueInstanceValue,
829
+ [EnumValueExplicitReference.create(value.value)],
830
+ observerContext,
831
+ );
832
+ return enumValueInstanceValue;
833
+ })
834
+ .filter(isNonNullable);
835
+ instanceValue_setValues(valueSpecification, result, observerContext);
836
+ saveEdit();
837
+ };
838
+
839
+ return (
840
+ <>
841
+ <CustomSelectorInput
842
+ className="value-spec-editor__enum-collection-selector"
843
+ options={availableOptions}
844
+ isMulti={true}
845
+ onChange={changeValue}
846
+ onBlur={updateValueSpecAndSaveEdit}
847
+ onKeyDown={(event: KeyboardEvent): void => {
848
+ if (event.key === 'Enter' && !event.shiftKey) {
849
+ updateValueSpecAndSaveEdit();
850
+ }
851
+ }}
852
+ value={selectedOptions}
853
+ darkMode={
854
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
855
+ }
856
+ placeholder="Select value"
857
+ autoFocus={true}
858
+ menuIsOpen={true}
859
+ />
860
+ <button
861
+ className="value-spec-editor__list-editor__save-button btn--dark"
862
+ onClick={updateValueSpecAndSaveEdit}
863
+ >
864
+ <SaveIcon />
865
+ </button>
866
+ </>
867
+ );
868
+ },
869
+ );
870
+
779
871
  const COLLECTION_PREVIEW_CHAR_LIMIT = 50;
780
872
 
781
873
  const getPlaceHolder = (expectedType: Type): string => {
@@ -836,6 +928,11 @@ const CollectionValueInstanceValueEditor = observer(
836
928
  if (editable) {
837
929
  setEditable(false);
838
930
  setShowAdvancedEditorPopover(false);
931
+ setValueSpecification(valueSpecification);
932
+ }
933
+ };
934
+ const updateValueSpecAndSaveEdit = (): void => {
935
+ if (editable) {
839
936
  setCollectionValue(
840
937
  valueSpecification,
841
938
  expectedType,
@@ -843,7 +940,7 @@ const CollectionValueInstanceValueEditor = observer(
843
940
  obseverContext,
844
941
  );
845
942
  setText(stringifyValue(valueSpecification.values));
846
- setValueSpecification(valueSpecification);
943
+ saveEdit();
847
944
  }
848
945
  };
849
946
 
@@ -861,7 +958,7 @@ const CollectionValueInstanceValueEditor = observer(
861
958
  (event.relatedTarget as HTMLButtonElement | undefined)?.name !==
862
959
  expandButtonName
863
960
  ) {
864
- saveEdit();
961
+ updateValueSpecAndSaveEdit();
865
962
  }
866
963
  };
867
964
 
@@ -891,7 +988,7 @@ const CollectionValueInstanceValueEditor = observer(
891
988
  onChange={changeValueTextArea}
892
989
  onKeyDown={(event): void => {
893
990
  if (event.key === 'Enter' && !event.shiftKey) {
894
- saveEdit();
991
+ updateValueSpecAndSaveEdit();
895
992
  }
896
993
  }}
897
994
  />
@@ -903,37 +1000,47 @@ const CollectionValueInstanceValueEditor = observer(
903
1000
  </BasePopover>
904
1001
  )}
905
1002
  <div className={clsx('value-spec-editor', className)}>
906
- <textarea
907
- ref={inputRef}
908
- className={clsx(
909
- 'panel__content__form__section__input value-spec-editor__input value-spec-editor__textarea ',
910
- )}
911
- spellCheck={false}
912
- value={text}
913
- placeholder={placeholder}
914
- onChange={changeValueTextArea}
915
- onKeyDown={(event): void => {
916
- if (event.key === 'Enter' && !event.shiftKey) {
917
- saveEdit();
918
- }
919
- }}
920
- onBlur={handleOnBlur}
921
- />
922
- <button
923
- className="value-spec-editor__list-editor__expand-button btn--dark"
924
- onClick={() => setShowAdvancedEditorPopover(true)}
925
- tabIndex={-1}
926
- name={expandButtonName}
927
- title="Expand window..."
928
- >
929
- <FilledWindowMaximizeIcon />
930
- </button>
931
- <button
932
- className="value-spec-editor__list-editor__save-button btn--dark"
933
- onClick={saveEdit}
934
- >
935
- <SaveIcon />
936
- </button>
1003
+ {expectedType instanceof Enumeration ? (
1004
+ <EnumCollectionInstanceValueEditor
1005
+ valueSpecification={valueSpecification}
1006
+ observerContext={obseverContext}
1007
+ saveEdit={saveEdit}
1008
+ />
1009
+ ) : (
1010
+ <>
1011
+ <textarea
1012
+ ref={inputRef}
1013
+ className={clsx(
1014
+ 'panel__content__form__section__input value-spec-editor__input value-spec-editor__textarea ',
1015
+ )}
1016
+ spellCheck={false}
1017
+ value={text}
1018
+ placeholder={placeholder}
1019
+ onChange={changeValueTextArea}
1020
+ onKeyDown={(event): void => {
1021
+ if (event.key === 'Enter' && !event.shiftKey) {
1022
+ updateValueSpecAndSaveEdit();
1023
+ }
1024
+ }}
1025
+ onBlur={handleOnBlur}
1026
+ />
1027
+ <button
1028
+ className="value-spec-editor__list-editor__expand-button btn--dark"
1029
+ onClick={() => setShowAdvancedEditorPopover(true)}
1030
+ tabIndex={-1}
1031
+ name={expandButtonName}
1032
+ title="Expand window..."
1033
+ >
1034
+ <FilledWindowMaximizeIcon />
1035
+ </button>
1036
+ <button
1037
+ className="value-spec-editor__list-editor__save-button btn--dark"
1038
+ onClick={saveEdit}
1039
+ >
1040
+ <SaveIcon />
1041
+ </button>
1042
+ </>
1043
+ )}
937
1044
  <button
938
1045
  className="value-spec-editor__reset-btn"
939
1046
  name="Reset"
@@ -17,6 +17,7 @@
17
17
  import {
18
18
  CustomSelectorInput,
19
19
  PanelHeader,
20
+ compareLabelFn,
20
21
  createFilter,
21
22
  } from '@finos/legend-art';
22
23
  import { observer } from 'mobx-react-lite';
@@ -71,7 +72,7 @@ const ClassQueryBuilderSetupPanelContent = observer(
71
72
  : []
72
73
  )
73
74
  .map(buildElementOption)
74
- .sort((a, b) => a.label.localeCompare(b.label));
75
+ .sort(compareLabelFn);
75
76
  const selectedMappingOption = queryBuilderState.executionContextState
76
77
  .mapping
77
78
  ? buildElementOption(queryBuilderState.executionContextState.mapping)
@@ -107,7 +108,7 @@ const ClassQueryBuilderSetupPanelContent = observer(
107
108
  new RuntimePointer(PackageableElementExplicitReference.create(rt)),
108
109
  )
109
110
  .map(buildRuntimeValueOption)
110
- .sort((a, b) => a.label.localeCompare(b.label));
111
+ .sort(compareLabelFn);
111
112
  const selectedRuntimeOption = queryBuilderState.executionContextState
112
113
  .runtimeValue
113
114
  ? buildRuntimeValueOption(
@@ -17,6 +17,7 @@
17
17
  import {
18
18
  CustomSelectorInput,
19
19
  PanelHeader,
20
+ compareLabelFn,
20
21
  createFilter,
21
22
  } from '@finos/legend-art';
22
23
  import { observer } from 'mobx-react-lite';
@@ -59,7 +60,7 @@ const MappingQueryBuilderSetupPanelContent = observer(
59
60
  // mapping
60
61
  const mappingOptions = queryBuilderState.graphManagerState.usableMappings
61
62
  .map(buildElementOption)
62
- .sort((a, b) => a.label.localeCompare(b.label));
63
+ .sort(compareLabelFn);
63
64
  const selectedMappingOption = queryBuilderState.executionContextState
64
65
  .mapping
65
66
  ? buildElementOption(queryBuilderState.executionContextState.mapping)
@@ -93,7 +94,7 @@ const MappingQueryBuilderSetupPanelContent = observer(
93
94
  new RuntimePointer(PackageableElementExplicitReference.create(rt)),
94
95
  )
95
96
  .map(buildRuntimeValueOption)
96
- .sort((a, b) => a.label.localeCompare(b.label));
97
+ .sort(compareLabelFn);
97
98
  const selectedRuntimeOption = queryBuilderState.executionContextState
98
99
  .runtimeValue
99
100
  ? buildRuntimeValueOption(
@@ -14,7 +14,11 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { CustomSelectorInput, PanelHeader } from '@finos/legend-art';
17
+ import {
18
+ CustomSelectorInput,
19
+ PanelHeader,
20
+ compareLabelFn,
21
+ } from '@finos/legend-art';
18
22
  import { observer } from 'mobx-react-lite';
19
23
  import { getMappingCompatibleClasses, type Service } from '@finos/legend-graph';
20
24
  import { useApplicationStore } from '@finos/legend-application';
@@ -57,7 +61,7 @@ const ServiceQueryBuilderSetupPanelContent = observer(
57
61
  const serviceOptions =
58
62
  queryBuilderState.usableServices
59
63
  ?.map(buildElementOption)
60
- .sort((a, b) => a.label.localeCompare(b.label)) ?? [];
64
+ .sort(compareLabelFn) ?? [];
61
65
  const selectedServiceOption = buildElementOption(queryBuilderState.service);
62
66
  const onServiceOptionChange = (
63
67
  option: PackageableElementOption<Service>,
@@ -71,7 +75,7 @@ const ServiceQueryBuilderSetupPanelContent = observer(
71
75
  // execution context
72
76
  const executionContextOptions = queryBuilderState.executionContexts
73
77
  .map(buildExecutionContextOption)
74
- .sort((a, b) => a.label.localeCompare(b.label));
78
+ .sort(compareLabelFn);
75
79
  const selectedExecutionContextOption =
76
80
  queryBuilderState.selectedExecutionContext
77
81
  ? buildExecutionContextOption(
@@ -67,6 +67,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
67
67
  * TODO: consider moving this to another state if we need to simplify the logic of text-mode
68
68
  */
69
69
  readOnlylambdaJson = '';
70
+ isReadOnly: boolean | undefined;
70
71
 
71
72
  constructor(queryBuilderState: QueryBuilderState) {
72
73
  super('', '');
@@ -75,7 +76,9 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
75
76
  rawLambdaState: observable,
76
77
  isConvertingLambdaToString: observable,
77
78
  mode: observable,
79
+ isReadOnly: observable,
78
80
  setQueryRawLambdaState: action,
81
+ setIsReadOnly: action,
79
82
  setMode: action,
80
83
  openModal: action,
81
84
  closeModal: flow,
@@ -89,10 +92,23 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
89
92
  return buildSourceInformationSourceId(['query-builder']);
90
93
  }
91
94
 
95
+ get text(): string | undefined {
96
+ if (this.mode === QueryBuilderTextEditorMode.TEXT) {
97
+ return this.fullLambdaString;
98
+ } else if (this.mode === QueryBuilderTextEditorMode.JSON) {
99
+ return this.readOnlylambdaJson;
100
+ }
101
+ return undefined;
102
+ }
103
+
92
104
  setQueryRawLambdaState(rawLambdaState: QueryBuilderRawLambdaState): void {
93
105
  this.rawLambdaState = rawLambdaState;
94
106
  }
95
107
 
108
+ setIsReadOnly(val: boolean | undefined): void {
109
+ this.isReadOnly = val;
110
+ }
111
+
96
112
  setMode(openModal: QueryBuilderTextEditorMode | undefined): void {
97
113
  this.mode = openModal;
98
114
  }
@@ -170,7 +186,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
170
186
  }
171
187
  }
172
188
 
173
- openModal(mode: QueryBuilderTextEditorMode): void {
189
+ openModal(mode: QueryBuilderTextEditorMode, isReadOnly?: boolean): void {
174
190
  try {
175
191
  const rawLambda = this.queryBuilderState.buildQuery();
176
192
  if (mode === QueryBuilderTextEditorMode.TEXT) {
@@ -190,6 +206,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
190
206
  );
191
207
  }
192
208
  this.setMode(mode);
209
+ this.setIsReadOnly(isReadOnly);
193
210
  } catch (error) {
194
211
  assertErrorThrown(error);
195
212
  this.queryBuilderState.applicationStore.notificationService.notifyError(
@@ -200,7 +217,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
200
217
 
201
218
  *closeModal(): GeneratorFn<void> {
202
219
  this.closingQueryState.inProgress();
203
- if (this.mode === QueryBuilderTextEditorMode.TEXT) {
220
+ if (this.mode === QueryBuilderTextEditorMode.TEXT && !this.isReadOnly) {
204
221
  yield flowResult(this.convertLambdaGrammarStringToObject());
205
222
  if (this.parserError) {
206
223
  this.queryBuilderState.applicationStore.notificationService.notifyError(
@@ -215,6 +232,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
215
232
  }
216
233
  return;
217
234
  }
235
+ this.setIsReadOnly(undefined);
218
236
  this.closingQueryState.complete();
219
237
 
220
238
  this.setMode(undefined);
@@ -65,7 +65,7 @@ export class QueryLoaderState {
65
65
 
66
66
  readonly isReadOnly?: boolean | undefined;
67
67
  readonly onQueryRenamed?: ((query: LightQuery) => void) | undefined;
68
- readonly onQueryDeleted?: ((query: LightQuery) => void) | undefined;
68
+ readonly onQueryDeleted?: ((query: string) => void) | undefined;
69
69
  readonly handleFetchDefaultQueriesFailure?: (() => void) | undefined;
70
70
 
71
71
  queryBuilderState?: QueryBuilderState | undefined;
@@ -100,7 +100,7 @@ export class QueryLoaderState {
100
100
 
101
101
  isReadOnly?: boolean | undefined;
102
102
  onQueryRenamed?: ((query: LightQuery) => void) | undefined;
103
- onQueryDeleted?: ((query: LightQuery) => void) | undefined;
103
+ onQueryDeleted?: ((query: string) => void) | undefined;
104
104
  handleFetchDefaultQueriesFailure?: (() => void) | undefined;
105
105
  },
106
106
  ) {
@@ -304,11 +304,9 @@ export class QueryLoaderState {
304
304
  *deleteQuery(queryId: string): GeneratorFn<void> {
305
305
  this.deleteQueryState.inProgress();
306
306
  try {
307
- const query = (yield this.graphManagerState.graphManager.deleteQuery(
308
- queryId,
309
- )) as Query;
310
- this.onQueryDeleted?.(query);
311
- this.applicationStore.notificationService.notify(
307
+ yield this.graphManagerState.graphManager.deleteQuery(queryId);
308
+ this.onQueryDeleted?.(queryId);
309
+ this.applicationStore.notificationService.notifySuccess(
312
310
  'Deleted query successfully',
313
311
  );
314
312
  this.deleteQueryState.pass();
@@ -30,7 +30,11 @@ import {
30
30
  } from '@finos/legend-shared';
31
31
  import { action, makeObservable, observable } from 'mobx';
32
32
  import type { QueryBuilderState } from '../QueryBuilderState.js';
33
- import type { TreeNodeData, TreeData } from '@finos/legend-art';
33
+ import {
34
+ type TreeNodeData,
35
+ type TreeData,
36
+ compareLabelFn,
37
+ } from '@finos/legend-art';
34
38
 
35
39
  export const QUERY_BUILDER_FUNCTION_DND_TYPE = 'QUERY_BUILDER_FUNCTION';
36
40
 
@@ -206,7 +210,7 @@ export const getFunctionsExplorerTreeNodeChildren = (
206
210
  return node.childrenIds
207
211
  .map((id) => data.nodes.get(id))
208
212
  .filter(isNonNullable)
209
- .sort((a, b) => a.label.localeCompare(b.label))
213
+ .sort(compareLabelFn)
210
214
  .sort(
211
215
  (a, b) =>
212
216
  (b.packageableElement instanceof Package ? 1 : 0) -
@@ -146,6 +146,7 @@ export class QueryBuilderTDSState
146
146
  TEMPORARY__showPostFetchStructurePanel: computed,
147
147
  derivations: computed,
148
148
  hasParserError: computed,
149
+ isQueryOptionsSet: computed,
149
150
  addColumn: action,
150
151
  moveColumn: action,
151
152
  removeAllColumns: action,
@@ -356,6 +357,16 @@ export class QueryBuilderTDSState
356
357
  return fetchStructureValidationIssues;
357
358
  }
358
359
 
360
+ get isQueryOptionsSet(): boolean {
361
+ return (
362
+ this.resultSetModifierState.limit !== undefined ||
363
+ this.queryBuilderState.milestoningState.isMilestonedQuery ||
364
+ this.resultSetModifierState.slice !== undefined ||
365
+ this.resultSetModifierState.sortColumns.length > 0 ||
366
+ this.resultSetModifierState.distinct
367
+ );
368
+ }
369
+
359
370
  get tdsColumns(): QueryBuilderTDSColumnState[] {
360
371
  const aggregationStateCols = this.aggregationState.columns.map(
361
372
  (c) => c.projectionColumnState,
@@ -75,7 +75,7 @@ export class QueryBuilderMilestoningState implements Hashable {
75
75
  startDate: observable,
76
76
  endDate: observable,
77
77
  showMilestoningEditor: observable,
78
- isMilestonedQuery: computed,
78
+
79
79
  setProcessingDate: action,
80
80
  setBusinessDate: action,
81
81
  setStartDate: action,
@@ -87,6 +87,10 @@ export class QueryBuilderMilestoningState implements Hashable {
87
87
  initializeAllVersionsInRangeParameters: action,
88
88
  clearAllVersionsInRangeParameters: action,
89
89
  clearGetAllParameters: action,
90
+
91
+ isAllVersionsEnabled: computed,
92
+ isAllVersionsInRangeEnabled: computed,
93
+ isMilestonedQuery: computed,
90
94
  hashCode: computed,
91
95
  });
92
96
 
@@ -380,9 +384,9 @@ export class QueryBuilderMilestoningState implements Hashable {
380
384
  this.queryBuilderState.parametersState.parameterStates.find(
381
385
  (p) => p.parameter === this.startDate,
382
386
  );
383
- this.queryBuilderState.parametersState.removeParameter(
384
- guaranteeNonNullable(paramState),
385
- );
387
+ if (paramState) {
388
+ this.queryBuilderState.parametersState.removeParameter(paramState);
389
+ }
386
390
  }
387
391
  if (
388
392
  this.endDate instanceof VariableExpression &&
@@ -394,9 +398,9 @@ export class QueryBuilderMilestoningState implements Hashable {
394
398
  this.queryBuilderState.parametersState.parameterStates.find(
395
399
  (p) => p.parameter === this.endDate,
396
400
  );
397
- this.queryBuilderState.parametersState.removeParameter(
398
- guaranteeNonNullable(paramState),
399
- );
401
+ if (paramState) {
402
+ this.queryBuilderState.parametersState.removeParameter(paramState);
403
+ }
400
404
  }
401
405
  this.setStartDate(undefined);
402
406
  this.setEndDate(undefined);
@@ -50,7 +50,6 @@ export class QueryBuilderWatermarkState implements Hashable {
50
50
  ),
51
51
  );
52
52
 
53
- watermarkConstant.values = ['watermarkValue'];
54
53
  return watermarkConstant;
55
54
  }
56
55