@finos/legend-query-builder 4.1.3 → 4.1.4

Sign up to get free protection for your applications and to get access to all the features.
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
  }