@finos/legend-query-builder 2.0.0 → 2.1.0

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 (43) hide show
  1. package/lib/components/QueryBuilder.js +1 -1
  2. package/lib/components/QueryBuilder.js.map +1 -1
  3. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  4. package/lib/components/QueryBuilderResultPanel.js +15 -5
  5. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  6. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +19 -17
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  9. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  10. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +34 -31
  11. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  12. package/lib/index.css +2 -2
  13. package/lib/index.css.map +1 -1
  14. package/lib/package.json +3 -3
  15. package/lib/stores/QueryBuilderResultState.d.ts +7 -3
  16. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  17. package/lib/stores/QueryBuilderResultState.js +14 -20
  18. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  19. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts +3 -0
  20. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts.map +1 -1
  21. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  22. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +10 -1
  23. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  24. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +36 -1
  25. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  26. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +6 -0
  27. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  28. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +21 -2
  29. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  30. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts +1 -0
  31. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts.map +1 -1
  32. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.js +10 -1
  33. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.js.map +1 -1
  34. package/package.json +10 -10
  35. package/src/components/QueryBuilder.tsx +1 -1
  36. package/src/components/QueryBuilderResultPanel.tsx +30 -17
  37. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +128 -126
  38. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +262 -256
  39. package/src/stores/QueryBuilderResultState.ts +28 -33
  40. package/src/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.ts +5 -0
  41. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +44 -0
  42. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +28 -0
  43. package/src/stores/fetch-structure/tds/window/QueryBuilderWindowState.ts +14 -1
@@ -29,7 +29,6 @@ import {
29
29
  clsx,
30
30
  PanelEntryDropZonePlaceholder,
31
31
  ContextMenu,
32
- VerticalDragHandleIcon,
33
32
  TimesIcon,
34
33
  useDragPreviewLayer,
35
34
  SortIcon,
@@ -43,6 +42,8 @@ import {
43
42
  ModalFooter,
44
43
  PanelFormSection,
45
44
  ModalFooterButton,
45
+ PanelDnDEntryDragHandle,
46
+ PanelDnDEntry,
46
47
  } from '@finos/legend-art';
47
48
  import { assertErrorThrown, guaranteeNonNullable } from '@finos/legend-shared';
48
49
  import { observer } from 'mobx-react-lite';
@@ -63,6 +64,7 @@ import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/td
63
64
  import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
64
65
  import { COLUMN_SORT_TYPE } from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
65
66
  import { QUERY_BUILDER_TEST_ID } from '../../application/QueryBuilderTesting.js';
67
+ import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
66
68
 
67
69
  // helpers
68
70
  const createWindowColumnState = (
@@ -190,7 +192,9 @@ const QueryBuilderWindowColumnModalEditor = observer(
190
192
  const close = (): void => {
191
193
  windowState.setEditColumn(undefined);
192
194
  };
193
- const isDuplicatedColumnName = createNewWindow
195
+ const isDuplicatedColumnName = !windowState.windowColumns.includes(
196
+ windowColumnState,
197
+ )
194
198
  ? windowState.tdsState.tdsColumns
195
199
  .map((c) => c.columnName)
196
200
  .includes(windowColumnState.columnName)
@@ -666,6 +670,8 @@ const QueryBuilderWindowColumnEditor = observer(
666
670
  const operators = windowState.operators;
667
671
  // state
668
672
  const ref = useRef<HTMLDivElement>(null);
673
+ const handleRef = useRef<HTMLDivElement>(null);
674
+
669
675
  const [windowAnchor, setWindowAnchor] = useState<HTMLButtonElement | null>(
670
676
  null,
671
677
  );
@@ -793,7 +799,8 @@ const QueryBuilderWindowColumnEditor = observer(
793
799
  [windowColumnState],
794
800
  );
795
801
  const isBeingDragged = windowColumnState === olapColumnBeingDragged;
796
- dragConnector(dropConnector(ref));
802
+ dragConnector(handleRef);
803
+ dropConnector(ref);
797
804
  useDragPreviewLayer(dragPreviewConnector);
798
805
 
799
806
  const handleOpDrop = (val: QueryBuilderTDSColumnState): void => {
@@ -843,273 +850,272 @@ const QueryBuilderWindowColumnEditor = observer(
843
850
  );
844
851
 
845
852
  return (
846
- <div ref={ref} className="query-builder__olap__column">
847
- <PanelEntryDropZonePlaceholder
848
- showPlaceholder={isBeingDragged}
849
- className="query-builder__dnd__placeholder"
853
+ <PanelDnDEntry
854
+ ref={ref}
855
+ className="query-builder__olap__column"
856
+ showPlaceholder={isBeingDragged}
857
+ >
858
+ <ContextMenu
859
+ content={
860
+ <QueryBuilderWindowColumnContextMenu
861
+ columnState={windowColumnState}
862
+ />
863
+ }
864
+ className={clsx('query-builder__olap__column__context-menu', {
865
+ 'query-builder__olap__column--selected-from-context-menu':
866
+ isSelectedFromContextMenu,
867
+ })}
868
+ menuProps={{ elevation: 7 }}
869
+ onOpen={onContextMenuOpen}
870
+ onClose={onContextMenuClose}
850
871
  >
851
- <ContextMenu
852
- content={
853
- <QueryBuilderWindowColumnContextMenu
854
- columnState={windowColumnState}
855
- />
856
- }
857
- className={clsx('query-builder__olap__column__context-menu', {
858
- 'query-builder__olap__column--selected-from-context-menu':
859
- isSelectedFromContextMenu,
860
- })}
861
- menuProps={{ elevation: 7 }}
862
- onOpen={onContextMenuOpen}
863
- onClose={onContextMenuClose}
864
- >
865
- <div className="query-builder__olap__column__drag-handle__container">
866
- <div className="query-builder__olap__column__drag-handle">
867
- <VerticalDragHandleIcon />
872
+ <PanelDnDEntryDragHandle
873
+ isBeingDragged={isBeingDragged}
874
+ className="query-builder__olap__column__drag-handle__container"
875
+ dropTargetConnector={handleRef}
876
+ />
877
+ <div className="query-builder__olap__column__operation">
878
+ <div className="query-builder__olap__column__operation__operator">
879
+ <div
880
+ className={clsx(
881
+ 'query-builder__olap__column__operation__operator__label',
882
+ {
883
+ 'query-builder__olap__column__operation__operator__label__agg':
884
+ !aggregateColumn,
885
+ },
886
+ )}
887
+ >
888
+ {operationState.operator.getLabel()}
868
889
  </div>
890
+ {aggregateColumn && (
891
+ <TDSColumnReferenceEditor
892
+ tdsColumn={aggregateColumn}
893
+ handleChange={handleOpDrop}
894
+ selectionEditor={{
895
+ options: windowColumnState.possibleReferencedColumns,
896
+ }}
897
+ />
898
+ )}
899
+ <DropdownMenu
900
+ className="query-builder__olap__column__operation__operator__dropdown"
901
+ disabled={!operators.length}
902
+ content={
903
+ <MenuContent>
904
+ {operators.map((op) => (
905
+ <MenuContentItem
906
+ key={op.uuid}
907
+ className="query-builder__olap__column__operation__operator__dropdown__option"
908
+ onClick={changeOperator(op)}
909
+ >
910
+ {op.getLabel()}
911
+ </MenuContentItem>
912
+ ))}
913
+ </MenuContent>
914
+ }
915
+ menuProps={{
916
+ anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
917
+ transformOrigin: { vertical: 'top', horizontal: 'left' },
918
+ elevation: 7,
919
+ }}
920
+ >
921
+ <button
922
+ className="query-builder__olap__column__operation__operator__badge"
923
+ tabIndex={-1}
924
+ title="Choose Window Function Operator..."
925
+ >
926
+ <SigmaIcon />
927
+ </button>
928
+ <button
929
+ className="query-builder__olap__column__operation__operator__dropdown__trigger"
930
+ tabIndex={-1}
931
+ title="Choose Window Function Operator..."
932
+ >
933
+ <CaretDownIcon />
934
+ </button>
935
+ </DropdownMenu>
869
936
  </div>
870
- <div className="query-builder__olap__column__operation">
871
- <div className="query-builder__olap__column__operation__operator">
937
+ </div>
938
+ <div className="query-builder__olap__column__window">
939
+ <button
940
+ ref={dropOpConnector}
941
+ title="Click to edit or drag and drop columns"
942
+ onClick={openWindowPopover}
943
+ className="query-builder__olap__column__window__content"
944
+ >
945
+ <PanelEntryDropZonePlaceholder
946
+ showPlaceholder={isDragOver}
947
+ label="Add"
948
+ className="query-builder__dnd__placeholder"
949
+ >
950
+ <div
951
+ title={`${windowColumnState.windowColumns.length} columns partitioned`}
952
+ className="query-builder__olap__column__window__content__label"
953
+ >
954
+ ({windowColumnState.windowColumns.length})
955
+ </div>
872
956
  <div
873
957
  className={clsx(
874
- 'query-builder__olap__column__operation__operator__label',
875
- {
876
- 'query-builder__olap__column__operation__operator__label__agg':
877
- !aggregateColumn,
878
- },
958
+ 'query-builder__olap__column__window__operator__badge',
879
959
  )}
960
+ tabIndex={-1}
961
+ title="Edit window columns..."
880
962
  >
881
- {operationState.operator.getLabel()}
963
+ <WindowIcon />
882
964
  </div>
883
- {aggregateColumn && (
884
- <TDSColumnReferenceEditor
885
- tdsColumn={aggregateColumn}
886
- handleChange={handleOpDrop}
887
- selectionEditor={{
888
- options: windowColumnState.possibleReferencedColumns,
889
- }}
890
- />
891
- )}
892
- <DropdownMenu
893
- className="query-builder__olap__column__operation__operator__dropdown"
894
- disabled={!operators.length}
895
- content={
896
- <MenuContent>
897
- {operators.map((op) => (
898
- <MenuContentItem
899
- key={op.uuid}
900
- className="query-builder__olap__column__operation__operator__dropdown__option"
901
- onClick={changeOperator(op)}
902
- >
903
- {op.getLabel()}
904
- </MenuContentItem>
905
- ))}
906
- </MenuContent>
907
- }
908
- menuProps={{
909
- anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
910
- transformOrigin: { vertical: 'top', horizontal: 'left' },
911
- elevation: 7,
912
- }}
913
- >
914
- <button
915
- className="query-builder__olap__column__operation__operator__badge"
916
- tabIndex={-1}
917
- title="Choose Window Function Operator..."
918
- >
919
- <SigmaIcon />
920
- </button>
921
- <button
922
- className="query-builder__olap__column__operation__operator__dropdown__trigger"
923
- tabIndex={-1}
924
- title="Choose Window Function Operator..."
925
- >
926
- <CaretDownIcon />
927
- </button>
928
- </DropdownMenu>
929
- </div>
930
- </div>
931
- <div className="query-builder__olap__column__window">
932
- <button
933
- ref={dropOpConnector}
934
- title="Click to edit or drag and drop columns"
935
- onClick={openWindowPopover}
936
- className="query-builder__olap__column__window__content"
937
- >
938
- <PanelEntryDropZonePlaceholder
939
- showPlaceholder={isDragOver}
940
- label="Add"
941
- className="query-builder__dnd__placeholder"
942
- >
943
- <div
944
- title={`${windowColumnState.windowColumns.length} columns partitioned`}
945
- className="query-builder__olap__column__window__content__label"
946
- >
947
- ({windowColumnState.windowColumns.length})
948
- </div>
949
- <div
950
- className={clsx(
951
- 'query-builder__olap__column__window__operator__badge',
952
- )}
953
- tabIndex={-1}
954
- title="Edit window columns..."
955
- >
956
- <WindowIcon />
965
+ </PanelEntryDropZonePlaceholder>
966
+ </button>
967
+ <BasePopover
968
+ open={Boolean(windowAnchor)}
969
+ anchorEl={windowAnchor}
970
+ onClose={closeWindowPopover}
971
+ anchorOrigin={{
972
+ vertical: 'bottom',
973
+ horizontal: 'center',
974
+ }}
975
+ transformOrigin={{
976
+ vertical: 'top',
977
+ horizontal: 'center',
978
+ }}
979
+ >
980
+ <div className="query-builder__olap__column__window__popover">
981
+ <div className="panel__content__form__section__list">
982
+ <div className="panel__content__form__section__list__items">
983
+ {windowColumnState.windowColumns.map((value, idx) => (
984
+ <TDSColumnSelectorEditor
985
+ key={value.uuid}
986
+ colValue={value}
987
+ setColumn={(v: QueryBuilderTDSColumnState) =>
988
+ windowColumnState.changeWindow(v, idx)
989
+ }
990
+ deleteColumn={(v: QueryBuilderTDSColumnState): void =>
991
+ windowColumnState.deleteWindow(v)
992
+ }
993
+ tdsColOptions={windowOptions}
994
+ />
995
+ ))}
957
996
  </div>
958
- </PanelEntryDropZonePlaceholder>
959
- </button>
960
- <BasePopover
961
- open={Boolean(windowAnchor)}
962
- anchorEl={windowAnchor}
963
- onClose={closeWindowPopover}
964
- anchorOrigin={{
965
- vertical: 'bottom',
966
- horizontal: 'center',
967
- }}
968
- transformOrigin={{
969
- vertical: 'top',
970
- horizontal: 'center',
971
- }}
972
- >
973
- <div className="query-builder__olap__column__window__popover">
974
- <div className="panel__content__form__section__list">
975
- <div className="panel__content__form__section__list__items">
976
- {windowColumnState.windowColumns.map((value, idx) => (
977
- <TDSColumnSelectorEditor
978
- key={value.uuid}
979
- colValue={value}
980
- setColumn={(v: QueryBuilderTDSColumnState) =>
981
- windowColumnState.changeWindow(v, idx)
982
- }
983
- deleteColumn={(v: QueryBuilderTDSColumnState): void =>
984
- windowColumnState.deleteWindow(v)
985
- }
986
- tdsColOptions={windowOptions}
987
- />
988
- ))}
989
- </div>
990
- <div className="panel__content__form__section__list__new-item__add">
991
- <button
992
- className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
993
- disabled={!addWindowOptions.length}
994
- onClick={addWindowValue}
995
- tabIndex={-1}
996
- >
997
- Add Value
998
- </button>
999
- </div>
997
+ <div className="panel__content__form__section__list__new-item__add">
998
+ <button
999
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
1000
+ disabled={!addWindowOptions.length}
1001
+ onClick={addWindowValue}
1002
+ tabIndex={-1}
1003
+ >
1004
+ Add Value
1005
+ </button>
1000
1006
  </div>
1001
1007
  </div>
1002
- </BasePopover>
1003
- </div>
1004
- <div className="query-builder__olap__column__sortby">
1005
- <div className="query-builder__olap__column__sortby__operator">
1006
- {sortByState && (
1007
- <div className="query-builder__olap__column__sortby__operator__label">
1008
- {sortByState.sortType.toLowerCase()}
1009
- </div>
1010
- )}
1011
- {sortByState && (
1012
- <TDSColumnReferenceEditor
1013
- tdsColumn={sortByState.columnState}
1014
- handleChange={handleSortDrop}
1015
- selectionEditor={{
1016
- options: windowColumnState.possibleReferencedColumns,
1017
- }}
1018
- />
1019
- )}
1020
- {!sortByState && (
1021
- <div className="query-builder__olap__column__sortby__none">
1022
- (none)
1023
- </div>
1024
- )}
1025
- <DropdownMenu
1026
- className="query-builder__olap__column__sortby__operator__dropdown"
1027
- content={
1028
- <MenuContent>
1008
+ </div>
1009
+ </BasePopover>
1010
+ </div>
1011
+ <div className="query-builder__olap__column__sortby">
1012
+ <div className="query-builder__olap__column__sortby__operator">
1013
+ {sortByState && (
1014
+ <div className="query-builder__olap__column__sortby__operator__label">
1015
+ {sortByState.sortType.toLowerCase()}
1016
+ </div>
1017
+ )}
1018
+ {sortByState && (
1019
+ <TDSColumnReferenceEditor
1020
+ tdsColumn={sortByState.columnState}
1021
+ handleChange={handleSortDrop}
1022
+ selectionEditor={{
1023
+ options: windowColumnState.possibleReferencedColumns,
1024
+ }}
1025
+ />
1026
+ )}
1027
+ {!sortByState && (
1028
+ <div className="query-builder__olap__column__sortby__none">
1029
+ (none)
1030
+ </div>
1031
+ )}
1032
+ <DropdownMenu
1033
+ className="query-builder__olap__column__sortby__operator__dropdown"
1034
+ content={
1035
+ <MenuContent>
1036
+ <MenuContentItem
1037
+ key="none"
1038
+ className="query-builder__olap__column__sortby__operator__dropdown__option"
1039
+ onClick={changeSortBy(undefined)}
1040
+ >
1041
+ (none)
1042
+ </MenuContentItem>
1043
+
1044
+ {Object.values(COLUMN_SORT_TYPE).map((op) => (
1029
1045
  <MenuContentItem
1030
- key="none"
1046
+ key={op}
1031
1047
  className="query-builder__olap__column__sortby__operator__dropdown__option"
1032
- onClick={changeSortBy(undefined)}
1048
+ onClick={changeSortBy(op)}
1033
1049
  >
1034
- (none)
1050
+ {op.toLowerCase()}
1035
1051
  </MenuContentItem>
1036
-
1037
- {Object.values(COLUMN_SORT_TYPE).map((op) => (
1038
- <MenuContentItem
1039
- key={op}
1040
- className="query-builder__olap__column__sortby__operator__dropdown__option"
1041
- onClick={changeSortBy(op)}
1042
- >
1043
- {op.toLowerCase()}
1044
- </MenuContentItem>
1045
- ))}
1046
- </MenuContent>
1047
- }
1048
- menuProps={{
1049
- anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
1050
- transformOrigin: { vertical: 'top', horizontal: 'left' },
1051
- elevation: 7,
1052
- }}
1053
- >
1054
- <button
1055
- className={clsx(
1056
- 'query-builder__olap__column__sortby__operator__badge',
1057
- {
1058
- 'query-builder__olap__column__sortby__operator__badge--activated':
1059
- Boolean(sortByState),
1060
- },
1061
- )}
1062
- tabIndex={-1}
1063
- title="Choose Window Function SortBy Operator..."
1064
- >
1065
- <SortIcon />
1066
- </button>
1067
- <button
1068
- className="query-builder__olap__column__sortby__operator__dropdown__trigger"
1069
- tabIndex={-1}
1070
- title="Choose Window Function SortBy Operator..."
1071
- >
1072
- <CaretDownIcon />
1073
- </button>
1074
- </DropdownMenu>
1075
- </div>
1076
- </div>
1077
- <div className="query-builder__olap__column__name">
1078
- <InputWithInlineValidation
1079
- className="query-builder__olap__column__name__input input-group__input"
1080
- spellCheck={false}
1081
- value={windowColumnState.columnName}
1082
- onChange={changeColumnName}
1083
- validationErrorMessage={
1084
- isDuplicatedColumnName ? 'Duplicated column' : undefined
1085
- }
1086
- />
1087
- </div>
1088
- <div className="query-builder__olap__column__actions">
1089
- <button
1090
- className="query-builder__olap__column__action"
1091
- tabIndex={-1}
1092
- onClick={editoColumn}
1093
- >
1094
- <EditIcon />
1095
- </button>
1096
- <button
1097
- className="query-builder__olap__column__action"
1098
- tabIndex={-1}
1099
- onClick={removeColumn}
1100
- disabled={isRemovalDisabled}
1101
- title={
1102
- isRemovalDisabled
1103
- ? "This column is used in the post filter and can't be removed"
1104
- : 'Remove'
1052
+ ))}
1053
+ </MenuContent>
1105
1054
  }
1055
+ menuProps={{
1056
+ anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
1057
+ transformOrigin: { vertical: 'top', horizontal: 'left' },
1058
+ elevation: 7,
1059
+ }}
1106
1060
  >
1107
- <TimesIcon />
1108
- </button>
1061
+ <button
1062
+ className={clsx(
1063
+ 'query-builder__olap__column__sortby__operator__badge',
1064
+ {
1065
+ 'query-builder__olap__column__sortby__operator__badge--activated':
1066
+ Boolean(sortByState),
1067
+ },
1068
+ )}
1069
+ tabIndex={-1}
1070
+ title="Choose Window Function SortBy Operator..."
1071
+ >
1072
+ <SortIcon />
1073
+ </button>
1074
+ <button
1075
+ className="query-builder__olap__column__sortby__operator__dropdown__trigger"
1076
+ tabIndex={-1}
1077
+ title="Choose Window Function SortBy Operator..."
1078
+ >
1079
+ <CaretDownIcon />
1080
+ </button>
1081
+ </DropdownMenu>
1109
1082
  </div>
1110
- </ContextMenu>
1111
- </PanelEntryDropZonePlaceholder>
1112
- </div>
1083
+ </div>
1084
+ <div className="query-builder__olap__column__name">
1085
+ <InputWithInlineValidation
1086
+ className="query-builder__olap__column__name__input input-group__input"
1087
+ spellCheck={false}
1088
+ value={windowColumnState.columnName}
1089
+ onChange={changeColumnName}
1090
+ validationErrorMessage={
1091
+ isDuplicatedColumnName ? 'Duplicated column' : undefined
1092
+ }
1093
+ />
1094
+ </div>
1095
+ <div className="query-builder__olap__column__actions">
1096
+ <button
1097
+ className="query-builder__olap__column__action"
1098
+ tabIndex={-1}
1099
+ onClick={editoColumn}
1100
+ >
1101
+ <EditIcon />
1102
+ </button>
1103
+ <button
1104
+ className="query-builder__olap__column__action"
1105
+ tabIndex={-1}
1106
+ onClick={removeColumn}
1107
+ disabled={isRemovalDisabled}
1108
+ title={
1109
+ isRemovalDisabled
1110
+ ? "This column is used in the post filter and can't be removed"
1111
+ : 'Remove'
1112
+ }
1113
+ >
1114
+ <TimesIcon />
1115
+ </button>
1116
+ </div>
1117
+ </ContextMenu>
1118
+ </PanelDnDEntry>
1113
1119
  );
1114
1120
  },
1115
1121
  );
@@ -1167,10 +1173,7 @@ export const QueryBuilderTDSWindowPanel = observer(
1167
1173
  [applicationStore, handleDrop],
1168
1174
  );
1169
1175
  return (
1170
- <div
1171
- data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_WINDOW_GROUPBY}
1172
- className="panel"
1173
- >
1176
+ <div className="panel">
1174
1177
  <div
1175
1178
  data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_WINDOW_GROUPBY}
1176
1179
  className="panel"
@@ -1178,6 +1181,9 @@ export const QueryBuilderTDSWindowPanel = observer(
1178
1181
  <div className="panel__header">
1179
1182
  <div className="panel__header__title">
1180
1183
  <div className="panel__header__title__label">Window Function</div>
1184
+ <QueryBuilderPanelIssueCountBadge
1185
+ issues={tdsWindowState.validationIssues}
1186
+ />
1181
1187
  </div>
1182
1188
  <div className="panel__header__actions">
1183
1189
  <button