@finos/legend-query-builder 4.1.3 → 4.1.4

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 (49) hide show
  1. package/lib/components/QueryBuilderTextEditor.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderTextEditor.js +3 -1
  3. package/lib/components/QueryBuilderTextEditor.js.map +1 -1
  4. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  5. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +2 -1
  6. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +51 -38
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  10. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  11. package/lib/components/filter/QueryBuilderFilterPanel.js +2 -1
  12. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  13. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  14. package/lib/components/shared/LambdaEditor.js +10 -3
  15. package/lib/components/shared/LambdaEditor.js.map +1 -1
  16. package/lib/index.css +2 -2
  17. package/lib/index.css.map +1 -1
  18. package/lib/package.json +4 -4
  19. package/lib/stores/QueryBuilderTextEditorState.d.ts +3 -1
  20. package/lib/stores/QueryBuilderTextEditorState.d.ts.map +1 -1
  21. package/lib/stores/QueryBuilderTextEditorState.js +2 -2
  22. package/lib/stores/QueryBuilderTextEditorState.js.map +1 -1
  23. package/lib/stores/QueryLoaderState.d.ts +2 -0
  24. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  25. package/lib/stores/QueryLoaderState.js +7 -3
  26. package/lib/stores/QueryLoaderState.js.map +1 -1
  27. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +0 -3
  28. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  29. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +3 -12
  30. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  31. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.d.ts +4 -1
  32. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.d.ts.map +1 -1
  33. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js +5 -3
  34. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js.map +1 -1
  35. package/lib/stores/shared/LambdaEditorState.d.ts +7 -2
  36. package/lib/stores/shared/LambdaEditorState.d.ts.map +1 -1
  37. package/lib/stores/shared/LambdaEditorState.js +7 -2
  38. package/lib/stores/shared/LambdaEditorState.js.map +1 -1
  39. package/package.json +12 -12
  40. package/src/components/QueryBuilderTextEditor.tsx +3 -1
  41. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +5 -1
  42. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +117 -64
  43. package/src/components/filter/QueryBuilderFilterPanel.tsx +5 -1
  44. package/src/components/shared/LambdaEditor.tsx +10 -3
  45. package/src/stores/QueryBuilderTextEditorState.ts +4 -2
  46. package/src/stores/QueryLoaderState.ts +11 -1
  47. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +3 -17
  48. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.ts +8 -3
  49. package/src/stores/shared/LambdaEditorState.ts +12 -5
@@ -50,9 +50,14 @@ export class LambdaEditorState {
50
50
  setLambdaString(val) {
51
51
  this.lambdaString = val;
52
52
  }
53
- clearErrors() {
54
- this.setCompilationError(undefined);
53
+ clearErrors(options) {
55
54
  this.setParserError(undefined);
55
+ if (options?.preserveCompilationError && this.compilationError) {
56
+ this.compilationError.sourceInformation = undefined;
57
+ }
58
+ else {
59
+ this.setCompilationError(undefined);
60
+ }
56
61
  }
57
62
  setCompilationError(compilationError) {
58
63
  // account for the lambda prefix offset in source information
@@ -1 +1 @@
1
- {"version":3,"file":"LambdaEditorState.js","sourceRoot":"","sources":["../../../src/stores/shared/LambdaEditorState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LambdaEditorState.js","sourceRoot":"","sources":["../../../src/stores/shared/LambdaEditorState.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-query-builder",
3
- "version": "4.1.3",
3
+ "version": "4.1.4",
4
4
  "description": "Legend query builder core",
5
5
  "keywords": [
6
6
  "legend",
@@ -42,15 +42,15 @@
42
42
  "test:watch": "jest --watch"
43
43
  },
44
44
  "dependencies": {
45
- "@finos/legend-application": "15.0.27",
46
- "@finos/legend-art": "7.0.27",
47
- "@finos/legend-graph": "30.0.12",
48
- "@finos/legend-lego": "1.1.4",
49
- "@finos/legend-server-depot": "6.0.16",
50
- "@finos/legend-shared": "10.0.15",
51
- "@finos/legend-storage": "3.0.65",
45
+ "@finos/legend-application": "15.0.28",
46
+ "@finos/legend-art": "7.0.28",
47
+ "@finos/legend-graph": "30.0.13",
48
+ "@finos/legend-lego": "1.1.5",
49
+ "@finos/legend-server-depot": "6.0.17",
50
+ "@finos/legend-shared": "10.0.16",
51
+ "@finos/legend-storage": "3.0.66",
52
52
  "@testing-library/react": "14.0.0",
53
- "@types/react": "18.2.13",
53
+ "@types/react": "18.2.14",
54
54
  "@types/react-dom": "18.2.6",
55
55
  "chart.js": "4.3.0",
56
56
  "mathjs": "11.8.2",
@@ -65,15 +65,15 @@
65
65
  "sql-formatter": "12.2.3"
66
66
  },
67
67
  "devDependencies": {
68
- "@finos/legend-dev-utils": "2.0.70",
68
+ "@finos/legend-dev-utils": "2.0.71",
69
69
  "@jest/globals": "29.5.0",
70
70
  "cross-env": "7.0.3",
71
- "eslint": "8.43.0",
71
+ "eslint": "8.44.0",
72
72
  "jest": "29.5.0",
73
73
  "npm-run-all": "4.1.5",
74
74
  "rimraf": "5.0.1",
75
75
  "sass": "1.63.6",
76
- "typescript": "5.1.3"
76
+ "typescript": "5.1.6"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "react": "^18.0.0"
@@ -54,7 +54,9 @@ export const QueryBuilderTextEditor = observer(
54
54
  const mode = queryTextEditorState.mode;
55
55
  useEffect(() => {
56
56
  flowResult(
57
- queryTextEditorState.convertLambdaObjectToGrammarString(true),
57
+ queryTextEditorState.convertLambdaObjectToGrammarString({
58
+ pretty: true,
59
+ }),
58
60
  ).catch(applicationStore.alertUnhandledError);
59
61
  }, [applicationStore, queryTextEditorState]);
60
62
 
@@ -166,12 +166,16 @@ const QueryBuilderPostFilterGroupConditionEditor = observer(
166
166
  : QUERY_BUILDER_GROUP_OPERATION.AND,
167
167
  );
168
168
  };
169
+
170
+ const operationName =
171
+ node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND ? 'AND' : 'OR';
172
+
169
173
  return (
170
174
  <div className="query-builder-post-filter-tree__node__label__content dnd__entry__container">
171
175
  <PanelEntryDropZonePlaceholder
172
176
  isDragOver={isDragOver}
173
177
  isDroppable={isDroppable}
174
- label="Add to Logical Group"
178
+ label={`Add to Logical Group '${operationName}'`}
175
179
  >
176
180
  <div
177
181
  className={clsx('query-builder-post-filter-tree__group-node', {
@@ -324,12 +324,25 @@ const buildCalendarTypeOption = (
324
324
  });
325
325
 
326
326
  const QueryBuilderProjectionColumnEditor = observer(
327
- (props: { projectionColumnState: QueryBuilderProjectionColumnState }) => {
328
- const { projectionColumnState } = props;
329
- const columnIdx = projectionColumnState.tdsState.tdsColumns.indexOf(
327
+ (props: {
328
+ projectionColumnState: QueryBuilderProjectionColumnState;
329
+ isRearrangeActive: boolean;
330
+ currentRearrangeDraggedColumnIndex: number | undefined;
331
+ setCurrentRearrangeDraggedColumnIndex: (val: number | undefined) => void;
332
+ currentRearrangeDropGapIndex: number | undefined;
333
+ setCurrentRearrangeDropGapIndex: (val: number | undefined) => void;
334
+ columnIdx: number;
335
+ }) => {
336
+ const {
337
+ isRearrangeActive,
330
338
  projectionColumnState,
331
- );
332
- const handleRef = useRef<HTMLDivElement>(null);
339
+ columnIdx,
340
+ currentRearrangeDraggedColumnIndex,
341
+ setCurrentRearrangeDraggedColumnIndex,
342
+ currentRearrangeDropGapIndex,
343
+ setCurrentRearrangeDropGapIndex,
344
+ } = props;
345
+ const dragHandleRef = useRef<HTMLDivElement>(null);
333
346
  const applicationStore = useApplicationStore();
334
347
  const ref = useRef<HTMLDivElement>(null);
335
348
  const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
@@ -405,6 +418,7 @@ const QueryBuilderProjectionColumnEditor = observer(
405
418
  aggregateColumnState?.calendarFunction?.setCalendarType(option.value);
406
419
  }
407
420
  };
421
+
408
422
  const defaultEndDate = observe_PrimitiveInstanceValue(
409
423
  new PrimitiveInstanceValue(
410
424
  GenericTypeExplicitReference.create(
@@ -484,17 +498,26 @@ const QueryBuilderProjectionColumnEditor = observer(
484
498
  (type: string): void => {
485
499
  if (
486
500
  type === QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE &&
487
- tdsState.draggedColumnIndex !== undefined &&
488
- tdsState.hoveredColumnIndex !== undefined
501
+ currentRearrangeDropGapIndex !== undefined &&
502
+ currentRearrangeDraggedColumnIndex !== undefined
489
503
  ) {
490
504
  tdsState.moveColumn(
491
- tdsState.draggedColumnIndex,
492
- tdsState.hoveredColumnIndex,
505
+ currentRearrangeDraggedColumnIndex,
506
+ currentRearrangeDropGapIndex === tdsState.projectionColumns.length
507
+ ? tdsState.projectionColumns.length - 1
508
+ : currentRearrangeDropGapIndex,
493
509
  );
494
510
  }
495
- tdsState.setRearrangeColumnsIndex(undefined, undefined);
511
+ setCurrentRearrangeDraggedColumnIndex(undefined);
512
+ setCurrentRearrangeDropGapIndex(undefined);
496
513
  },
497
- [tdsState],
514
+ [
515
+ tdsState,
516
+ currentRearrangeDropGapIndex,
517
+ currentRearrangeDraggedColumnIndex,
518
+ setCurrentRearrangeDraggedColumnIndex,
519
+ setCurrentRearrangeDropGapIndex,
520
+ ],
498
521
  );
499
522
 
500
523
  // Drag and Drop
@@ -506,36 +529,47 @@ const QueryBuilderProjectionColumnEditor = observer(
506
529
  const dragIndex = tdsState.projectionColumns.findIndex(
507
530
  (e) => e === item.columnState,
508
531
  );
509
- const hoverIndex = tdsState.projectionColumns.findIndex(
510
- (e) => e === projectionColumnState,
511
- );
532
+ const hoveredRectangle = ref.current?.getBoundingClientRect();
533
+ const hoveredRectangleMiddle =
534
+ hoveredRectangle?.top && hoveredRectangle.bottom
535
+ ? (hoveredRectangle.top + hoveredRectangle.bottom) / 2
536
+ : undefined;
537
+ const yCoordinate = monitor.getClientOffset()?.y ?? 0;
512
538
 
513
- if (dragIndex === hoverIndex) {
514
- tdsState.setRearrangeColumnsIndex(undefined, hoverIndex);
539
+ if (yCoordinate && hoveredRectangleMiddle) {
540
+ setCurrentRearrangeDropGapIndex(
541
+ yCoordinate < hoveredRectangleMiddle ? columnIdx : columnIdx + 1,
542
+ );
515
543
  }
516
544
 
517
- if (dragIndex === -1 || hoverIndex === -1 || dragIndex === hoverIndex) {
518
- return;
519
- }
520
545
  // move the item being hovered on when the dragged item position is beyond the its middle point
521
546
  const hoverBoundingReact = ref.current?.getBoundingClientRect();
522
-
523
547
  const distanceThreshold =
524
548
  ((hoverBoundingReact?.bottom ?? 0) - (hoverBoundingReact?.top ?? 0)) /
525
549
  2;
526
- const dragDistance =
527
- (monitor.getClientOffset()?.y ?? 0) - (hoverBoundingReact?.top ?? 0);
528
- if (dragIndex < hoverIndex && dragDistance < distanceThreshold) {
550
+ const dragDistance = yCoordinate - (hoverBoundingReact?.top ?? 0);
551
+
552
+ if (dragIndex === -1 || columnIdx === -1 || dragIndex === columnIdx) {
553
+ return;
554
+ }
555
+
556
+ if (dragIndex < columnIdx && dragDistance < distanceThreshold) {
529
557
  return;
530
558
  }
531
- if (dragIndex > hoverIndex && dragDistance > distanceThreshold) {
559
+ if (dragIndex > columnIdx && dragDistance > distanceThreshold) {
532
560
  return;
533
561
  }
534
562
 
535
- tdsState.setRearrangeColumnsIndex(dragIndex, hoverIndex);
563
+ setCurrentRearrangeDraggedColumnIndex(dragIndex);
536
564
  },
537
- [projectionColumnState, tdsState],
565
+ [
566
+ tdsState,
567
+ columnIdx,
568
+ setCurrentRearrangeDropGapIndex,
569
+ setCurrentRearrangeDraggedColumnIndex,
570
+ ],
538
571
  );
572
+
539
573
  const [, dropConnector] = useDrop<QueryBuilderProjectionColumnDragSource>(
540
574
  () => ({
541
575
  accept: [QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE],
@@ -580,11 +614,7 @@ const QueryBuilderProjectionColumnEditor = observer(
580
614
  [projectionColumnState],
581
615
  );
582
616
 
583
- const isBeingDragged =
584
- columnIdx === tdsState.hoveredColumnIndex &&
585
- projectionColumnBeingDragged !== undefined;
586
-
587
- dragConnector(handleRef);
617
+ dragConnector(dragHandleRef);
588
618
  dropConnector(ref);
589
619
 
590
620
  useDragPreviewLayer(dragPreviewConnector);
@@ -647,22 +677,24 @@ const QueryBuilderProjectionColumnEditor = observer(
647
677
  return (
648
678
  <PanelDnDEntry
649
679
  ref={ref}
650
- // TODO: this is the more appropriate solution than what we did
651
- // before and in other places for rearrange because it does no
652
- // rearrange while on hovering, but on drop, there's some work to
653
- // do about the drop location indicator though
654
- // See https://github.com/finos/legend-studio/pull/2330
655
680
  placeholder={
656
681
  <div
657
- className={
658
- (tdsState.hoveredColumnIndex ?? 0) >
659
- (tdsState.draggedColumnIndex ?? 0)
660
- ? 'query-builder__projection__column__placeholder--bottom'
661
- : 'query-builder__projection__column__placeholder--top'
662
- }
682
+ className={clsx(
683
+ {
684
+ 'query-builder__projection__column__placeholder--bottom':
685
+ currentRearrangeDropGapIndex === columnIdx + 1 &&
686
+ columnIdx === tdsState.projectionColumns.length - 1,
687
+ },
688
+ {
689
+ 'query-builder__projection__column__placeholder--top':
690
+ currentRearrangeDropGapIndex === columnIdx,
691
+ },
692
+ )}
663
693
  />
664
694
  }
665
- showPlaceholder={isBeingDragged}
695
+ showPlaceholder={
696
+ projectionColumnBeingDragged !== undefined && isRearrangeActive
697
+ }
666
698
  className="query-builder__projection__column"
667
699
  >
668
700
  <ContextMenu
@@ -687,8 +719,8 @@ const QueryBuilderProjectionColumnEditor = observer(
687
719
  >
688
720
  <div className="query-builder__projection__column__container">
689
721
  <PanelEntryDragHandle
690
- isDragging={isBeingDragged}
691
- dragSourceConnector={handleRef}
722
+ isDragging={false}
723
+ dragSourceConnector={dragHandleRef}
692
724
  className="query-builder__projection__column__drag-handle__container"
693
725
  />
694
726
  <div className="query-builder__projection__column__name">
@@ -904,6 +936,12 @@ export const QueryBuilderTDSPanel = observer(
904
936
  const applicationStore = useApplicationStore();
905
937
  const { tdsState } = props;
906
938
  const projectionColumns = tdsState.projectionColumns;
939
+ const [
940
+ currentRearrangeDraggedColumnIndex,
941
+ setCurrentRearrangeDraggedColumnIndex,
942
+ ] = useState<number | undefined>();
943
+ const [currentRearrangeDropGapIndex, setCurrentRearrangeDropGapIndex] =
944
+ useState<number | undefined>();
907
945
 
908
946
  // Toolbar
909
947
  const openResultSetModifierEditor = (): void =>
@@ -986,15 +1024,15 @@ export const QueryBuilderTDSPanel = observer(
986
1024
  [handleDrop],
987
1025
  );
988
1026
 
989
- const [, projectionColumnDropConnector] = useDrop<
1027
+ const [{ isRearrangeActive }, rearrangeColumnDropConnector] = useDrop<
990
1028
  QueryBuilderProjectionColumnDragSource,
991
1029
  void,
992
- { isOverProjectionColumns: boolean }
1030
+ { isRearrangeActive: boolean }
993
1031
  >(
994
1032
  () => ({
995
1033
  accept: [QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE],
996
1034
  collect: (monitor) => ({
997
- isOverProjectionColumns: monitor.isOver({ shallow: false }),
1035
+ isRearrangeActive: monitor.isOver({ shallow: false }),
998
1036
  }),
999
1037
  }),
1000
1038
  [],
@@ -1065,24 +1103,39 @@ export const QueryBuilderTDSPanel = observer(
1065
1103
  <div
1066
1104
  data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_TDS}
1067
1105
  className="query-builder__projection__columns"
1068
- ref={projectionColumnDropConnector}
1069
1106
  >
1070
- <DragPreviewLayer
1071
- labelGetter={(
1072
- item: QueryBuilderProjectionColumnDragSource,
1073
- ): string =>
1074
- item.columnState.columnName === ''
1075
- ? '(unknown)'
1076
- : item.columnState.columnName
1077
- }
1078
- types={[QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE]}
1079
- />
1080
- {projectionColumns.map((projectionColumnState) => (
1081
- <QueryBuilderProjectionColumnEditor
1082
- key={projectionColumnState.uuid}
1083
- projectionColumnState={projectionColumnState}
1107
+ <div ref={rearrangeColumnDropConnector}>
1108
+ <DragPreviewLayer
1109
+ labelGetter={(
1110
+ item: QueryBuilderProjectionColumnDragSource,
1111
+ ): string =>
1112
+ item.columnState.columnName === ''
1113
+ ? '(unknown)'
1114
+ : item.columnState.columnName
1115
+ }
1116
+ types={[QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE]}
1084
1117
  />
1085
- ))}
1118
+ {projectionColumns.map((projectionColumnState, columnIdx) => (
1119
+ <QueryBuilderProjectionColumnEditor
1120
+ key={projectionColumnState.uuid}
1121
+ projectionColumnState={projectionColumnState}
1122
+ isRearrangeActive={isRearrangeActive}
1123
+ currentRearrangeDraggedColumnIndex={
1124
+ currentRearrangeDraggedColumnIndex
1125
+ }
1126
+ currentRearrangeDropGapIndex={
1127
+ currentRearrangeDropGapIndex
1128
+ }
1129
+ setCurrentRearrangeDraggedColumnIndex={
1130
+ setCurrentRearrangeDraggedColumnIndex
1131
+ }
1132
+ setCurrentRearrangeDropGapIndex={
1133
+ setCurrentRearrangeDropGapIndex
1134
+ }
1135
+ columnIdx={columnIdx}
1136
+ />
1137
+ ))}
1138
+ </div>
1086
1139
  </div>
1087
1140
  )}
1088
1141
  <QueryResultModifierModal tdsState={tdsState} />
@@ -118,12 +118,16 @@ const QueryBuilderFilterGroupConditionEditor = observer(
118
118
  : QUERY_BUILDER_GROUP_OPERATION.AND,
119
119
  );
120
120
  };
121
+
122
+ const operationName =
123
+ node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND ? 'AND' : 'OR';
124
+
121
125
  return (
122
126
  <div className="query-builder-filter-tree__node__label__content dnd__entry__container">
123
127
  <PanelEntryDropZonePlaceholder
124
128
  isDragOver={isDragOver}
125
129
  isDroppable={isDroppable}
126
- label="Add to Logical Group"
130
+ label={`Add to Logical Group '${operationName}'`}
127
131
  >
128
132
  <div
129
133
  className={clsx('query-builder-filter-tree__group-node', {
@@ -140,7 +140,9 @@ const LambdaEditor_Inner = observer(
140
140
  const transformLambdaToString = async (pretty: boolean): Promise<void> => {
141
141
  transformStringToLambda?.cancel();
142
142
  return flowResult(
143
- lambdaEditorState.convertLambdaObjectToGrammarString(pretty),
143
+ lambdaEditorState.convertLambdaObjectToGrammarString({
144
+ pretty: pretty,
145
+ }),
144
146
  ).catch(applicationStore.alertUnhandledError);
145
147
  };
146
148
  const discardChanges = applicationStore.guardUnhandledError(() =>
@@ -447,7 +449,9 @@ const LambdaEditor_PopUp = observer(
447
449
  const transformLambdaToString = async (pretty: boolean): Promise<void> => {
448
450
  transformStringToLambda?.cancel();
449
451
  return flowResult(
450
- lambdaEditorState.convertLambdaObjectToGrammarString(pretty),
452
+ lambdaEditorState.convertLambdaObjectToGrammarString({
453
+ pretty: pretty,
454
+ }),
451
455
  ).catch(applicationStore.alertUnhandledError);
452
456
  };
453
457
  const discardChanges = applicationStore.guardUnhandledError(() =>
@@ -554,7 +558,10 @@ const LambdaEditor_PopUp = observer(
554
558
 
555
559
  useEffect(() => {
556
560
  flowResult(
557
- lambdaEditorState.convertLambdaObjectToGrammarString(true),
561
+ lambdaEditorState.convertLambdaObjectToGrammarString({
562
+ pretty: true,
563
+ preserveCompilationError: true,
564
+ }),
558
565
  ).catch(applicationStore.alertUnhandledError);
559
566
  }, [applicationStore, lambdaEditorState]);
560
567
 
@@ -129,7 +129,9 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
129
129
  }
130
130
  }
131
131
 
132
- *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn<void> {
132
+ *convertLambdaObjectToGrammarString(options: {
133
+ pretty?: boolean | undefined;
134
+ }): GeneratorFn<void> {
133
135
  if (this.rawLambdaState.lambda.body) {
134
136
  this.isConvertingLambdaToString = true;
135
137
  try {
@@ -144,7 +146,7 @@ export class QueryBuilderTextEditorState extends LambdaEditorState {
144
146
  const isolatedLambdas =
145
147
  (yield this.queryBuilderState.graphManagerState.graphManager.lambdasToPureCode(
146
148
  lambdas,
147
- pretty,
149
+ options.pretty,
148
150
  )) as Map<string, string>;
149
151
  const grammarText = isolatedLambdas.get(this.lambdaId);
150
152
  this.setLambdaString(
@@ -24,12 +24,14 @@ import {
24
24
  type QueryInfo,
25
25
  type BasicGraphManagerState,
26
26
  type Query,
27
+ GRAPH_MANAGER_EVENT,
27
28
  } from '@finos/legend-graph';
28
29
  import {
29
30
  ActionState,
30
31
  type GeneratorFn,
31
32
  assertErrorThrown,
32
33
  guaranteeNonNullable,
34
+ LogEvent,
33
35
  } from '@finos/legend-shared';
34
36
  import { makeObservable, observable, action, flow } from 'mobx';
35
37
  import type { QueryBuilderState } from './QueryBuilderState.js';
@@ -62,6 +64,7 @@ export class QueryLoaderState {
62
64
  readonly isReadOnly?: boolean | undefined;
63
65
  readonly onQueryRenamed?: ((query: LightQuery) => void) | undefined;
64
66
  readonly onQueryDeleted?: ((query: LightQuery) => void) | undefined;
67
+ readonly handleFetchDefaultQueriesFailure?: (() => void) | undefined;
65
68
 
66
69
  queryBuilderState?: QueryBuilderState | undefined;
67
70
 
@@ -93,6 +96,7 @@ export class QueryLoaderState {
93
96
  isReadOnly?: boolean | undefined;
94
97
  onQueryRenamed?: ((query: LightQuery) => void) | undefined;
95
98
  onQueryDeleted?: ((query: LightQuery) => void) | undefined;
99
+ handleFetchDefaultQueriesFailure?: (() => void) | undefined;
96
100
  },
97
101
  ) {
98
102
  makeObservable(this, {
@@ -126,6 +130,8 @@ export class QueryLoaderState {
126
130
  this.isReadOnly = options.isReadOnly;
127
131
  this.onQueryRenamed = options.onQueryRenamed;
128
132
  this.onQueryDeleted = options.onQueryDeleted;
133
+ this.handleFetchDefaultQueriesFailure =
134
+ options.handleFetchDefaultQueriesFailure;
129
135
  }
130
136
 
131
137
  setSearchText(val: string): void {
@@ -190,7 +196,11 @@ export class QueryLoaderState {
190
196
  } catch (error) {
191
197
  this.searchQueriesState.fail();
192
198
  assertErrorThrown(error);
193
- this.applicationStore.notificationService.notifyError(error);
199
+ this.applicationStore.logService.error(
200
+ LogEvent.create(GRAPH_MANAGER_EVENT.GET_QUERY_FAILURE),
201
+ error,
202
+ );
203
+ this.handleFetchDefaultQueriesFailure?.();
194
204
  }
195
205
  }
196
206
 
@@ -121,8 +121,6 @@ export class QueryBuilderTDSState
121
121
  isConvertDerivationProjectionObjects = false;
122
122
  showPostFilterPanel: boolean;
123
123
  showWindowFuncPanel = false;
124
- draggedColumnIndex: number | undefined;
125
- hoveredColumnIndex: number | undefined;
126
124
 
127
125
  postFilterOperators: QueryBuilderPostFilterOperator[] =
128
126
  getQueryBuilderCorePostFilterOperators();
@@ -144,14 +142,11 @@ export class QueryBuilderTDSState
144
142
  isConvertDerivationProjectionObjects: observable,
145
143
  showPostFilterPanel: observable,
146
144
  showWindowFuncPanel: observable,
147
- draggedColumnIndex: observable,
148
- hoveredColumnIndex: observable,
149
145
  TEMPORARY__showPostFetchStructurePanel: computed,
150
146
  derivations: computed,
151
147
  hasParserError: computed,
152
148
  addColumn: action,
153
149
  moveColumn: action,
154
- setRearrangeColumnsIndex: action,
155
150
  replaceColumn: action,
156
151
  initialize: action,
157
152
  setShowPostFilterPanel: action,
@@ -159,9 +154,6 @@ export class QueryBuilderTDSState
159
154
  convertDerivationProjectionObjects: flow,
160
155
  });
161
156
 
162
- this.draggedColumnIndex = undefined;
163
- this.hoveredColumnIndex = undefined;
164
-
165
157
  this.resultSetModifierState = new QueryResultSetModifierState(this);
166
158
  this.postFilterState = new QueryBuilderPostFilterState(
167
159
  this,
@@ -182,14 +174,6 @@ export class QueryBuilderTDSState
182
174
  ) ?? false;
183
175
  }
184
176
 
185
- setRearrangeColumnsIndex(
186
- draggedColumnIndex: number | undefined,
187
- hoveredColumnIndex: number | undefined,
188
- ): void {
189
- this.draggedColumnIndex = draggedColumnIndex;
190
- this.hoveredColumnIndex = hoveredColumnIndex;
191
- }
192
-
193
177
  get type(): string {
194
178
  return FETCH_STRUCTURE_IMPLEMENTATION.TABULAR_DATA_STRUCTURE;
195
179
  }
@@ -481,7 +465,9 @@ export class QueryBuilderTDSState
481
465
  // convert to grammar for display
482
466
  flowResult(
483
467
  derivationColumnState.derivationLambdaEditorState.convertLambdaObjectToGrammarString(
484
- false,
468
+ {
469
+ pretty: false,
470
+ },
485
471
  ),
486
472
  ).catch(this.queryBuilderState.applicationStore.alertUnhandledError);
487
473
  }
@@ -226,7 +226,10 @@ class QueryBuilderDerivationProjectionLambdaState extends LambdaEditorState {
226
226
  }
227
227
  }
228
228
 
229
- *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn<void> {
229
+ *convertLambdaObjectToGrammarString(options?: {
230
+ pretty?: boolean | undefined;
231
+ preserveCompilationError?: boolean | undefined;
232
+ }): GeneratorFn<void> {
230
233
  if (this.derivationProjectionColumnState.lambda.body) {
231
234
  try {
232
235
  const lambdas = new Map<string, RawLambda>();
@@ -240,7 +243,7 @@ class QueryBuilderDerivationProjectionLambdaState extends LambdaEditorState {
240
243
  const isolatedLambdas =
241
244
  (yield this.queryBuilderState.graphManagerState.graphManager.lambdasToPureCode(
242
245
  lambdas,
243
- pretty,
246
+ options?.pretty,
244
247
  )) as Map<string, string>;
245
248
  const grammarText = isolatedLambdas.get(this.lambdaId);
246
249
  this.setLambdaString(
@@ -248,7 +251,9 @@ class QueryBuilderDerivationProjectionLambdaState extends LambdaEditorState {
248
251
  ? this.extractLambdaString(grammarText)
249
252
  : '',
250
253
  );
251
- this.clearErrors();
254
+ this.clearErrors({
255
+ preserveCompilationError: options?.preserveCompilationError,
256
+ });
252
257
  } catch (error) {
253
258
  assertErrorThrown(error);
254
259
  this.queryBuilderState.applicationStore.logService.error(
@@ -64,9 +64,15 @@ export abstract class LambdaEditorState {
64
64
  this.lambdaString = val;
65
65
  }
66
66
 
67
- clearErrors(): void {
68
- this.setCompilationError(undefined);
67
+ clearErrors(options?: {
68
+ preserveCompilationError?: boolean | undefined;
69
+ }): void {
69
70
  this.setParserError(undefined);
71
+ if (options?.preserveCompilationError && this.compilationError) {
72
+ this.compilationError.sourceInformation = undefined;
73
+ } else {
74
+ this.setCompilationError(undefined);
75
+ }
70
76
  }
71
77
 
72
78
  setCompilationError(compilationError: CompilationError | undefined): void {
@@ -113,7 +119,8 @@ export abstract class LambdaEditorState {
113
119
  }
114
120
 
115
121
  abstract convertLambdaGrammarStringToObject(): GeneratorFn<void>;
116
- abstract convertLambdaObjectToGrammarString(
117
- pretty: boolean,
118
- ): GeneratorFn<void>;
122
+ abstract convertLambdaObjectToGrammarString(options?: {
123
+ pretty?: boolean | undefined;
124
+ preserveCompilationError?: boolean | undefined;
125
+ }): GeneratorFn<void>;
119
126
  }