@adaptabletools/adaptable 23.0.0-canary.2 → 23.0.0-canary.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 (105) hide show
  1. package/index.css +68 -73
  2. package/package.json +1 -1
  3. package/src/AdaptableOptions/DefaultAdaptableOptions.js +0 -4
  4. package/src/AdaptableOptions/FilterOptions.d.ts +0 -7
  5. package/src/AdaptableOptions/UserInterfaceOptions.d.ts +1 -3
  6. package/src/AdaptableState/Common/AdaptableForm.d.ts +18 -1
  7. package/src/AdaptableState/Common/AdaptableForm.js +31 -0
  8. package/src/AdaptableState/Common/AdaptableFormat.d.ts +1 -1
  9. package/src/AdaptableState/Common/CellDataChangedInfo.d.ts +3 -2
  10. package/src/AdaptableState/Common/Enums.d.ts +0 -5
  11. package/src/AdaptableState/Common/Enums.js +0 -6
  12. package/src/Api/EventApi.d.ts +1 -1
  13. package/src/Api/Events/ReportScheduleRan.d.ts +4 -0
  14. package/src/Api/Implementation/LayoutHelpers.js +12 -0
  15. package/src/Api/Internal/EventInternalApi.js +2 -1
  16. package/src/Strategy/CalculatedColumnModule.js +3 -1
  17. package/src/Utilities/Services/CalculatedColumnExpressionService.d.ts +1 -0
  18. package/src/Utilities/Services/CalculatedColumnExpressionService.js +7 -0
  19. package/src/Utilities/Services/CalculatedColumnSyntheticChange.d.ts +4 -0
  20. package/src/Utilities/Services/CalculatedColumnSyntheticChange.js +115 -0
  21. package/src/Utilities/Services/Interface/ICalculatedColumnExpressionService.d.ts +1 -0
  22. package/src/View/AdaptablePopover/index.js +1 -1
  23. package/src/View/Charting/ChartingWizard/AgChargingWizard/SettingsSection.js +8 -16
  24. package/src/View/Components/Buttons/ButtonInfo.d.ts +1 -1
  25. package/src/View/Components/Buttons/ButtonInfo.js +4 -3
  26. package/src/View/Components/ColumnFilter/AdaptableColumnFilter.js +1 -1
  27. package/src/View/Components/ColumnFilter/ColumnFilter.js +15 -5
  28. package/src/View/Components/ColumnFilter/ColumnFilterWindow.js +1 -1
  29. package/src/View/Components/ColumnFilter/FloatingFilter.js +58 -60
  30. package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -1
  31. package/src/View/Components/Forms/AdaptableFormControlTextClear.js +2 -1
  32. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopup.js +1 -1
  33. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +2 -2
  34. package/src/View/Components/Selectors/ColumnSelector.js +5 -0
  35. package/src/View/Components/ValueSelector/index.js +1 -1
  36. package/src/View/FlashingCell/Wizard/FlashingCellScopeWizardSection.js +3 -1
  37. package/src/View/FormatColumn/Wizard/FormatColumnScopeWizardSection.js +3 -8
  38. package/src/View/GridFilter/GridFilterViewPanel.js +1 -1
  39. package/src/View/Layout/LayoutViewPanel.js +23 -21
  40. package/src/View/Layout/Wizard/sections/ColumnsSection.js +3 -3
  41. package/src/View/Layout/Wizard/sections/PivotColumnsSection.js +1 -1
  42. package/src/View/Layout/Wizard/sections/RowSelectionSection.js +1 -1
  43. package/src/View/Layout/Wizard/sections/SettingsSection.js +1 -1
  44. package/src/View/License/LicenseWatermark.js +1 -1
  45. package/src/View/StyledColumn/Wizard/StyledColumnWizardScopeSection.js +1 -1
  46. package/src/View/Wizard/OnePageWizards.js +1 -1
  47. package/src/View/renderWithAdaptableContext.js +2 -3
  48. package/src/agGrid/AdaptableAgGrid.d.ts +0 -1
  49. package/src/agGrid/AdaptableAgGrid.js +3 -18
  50. package/src/agGrid/AgGridColumnAdapter.js +1 -4
  51. package/src/components/AdaptableFormComponent/AdaptableFormComponent.js +11 -6
  52. package/src/components/Card/index.js +1 -1
  53. package/src/components/Combobox/VirtualizedList.js +5 -5
  54. package/src/components/Combobox/comboboxUtils.d.ts +4 -1
  55. package/src/components/Combobox/comboboxUtils.js +2 -0
  56. package/src/components/Combobox/index.d.ts +1 -0
  57. package/src/components/Combobox/index.js +38 -12
  58. package/src/components/Datepicker/index.js +2 -2
  59. package/src/components/Dialog/index.js +1 -1
  60. package/src/components/DragAndDropContext/TabList.js +1 -1
  61. package/src/components/Dropdown/Arrows.js +0 -1
  62. package/src/components/ExpressionEditor/BaseEditorInput.js +1 -1
  63. package/src/components/ExpressionEditor/index.js +1 -1
  64. package/src/components/Input/index.js +1 -1
  65. package/src/components/NewDropdownButton/index.d.ts +1 -0
  66. package/src/components/NewDropdownButton/index.js +2 -2
  67. package/src/components/NewSelect/index.d.ts +2 -0
  68. package/src/components/NewSelect/index.js +10 -7
  69. package/src/components/Panel/index.js +1 -1
  70. package/src/components/SimpleButton/index.js +1 -1
  71. package/src/components/Tabs/index.js +1 -1
  72. package/src/components/Tree/TreeDropdown/index.js +6 -14
  73. package/src/components/ui/button.d.ts +5 -2
  74. package/src/components/ui/button.js +5 -4
  75. package/src/components/ui/combobox.d.ts +16 -16
  76. package/src/components/ui/combobox.js +37 -37
  77. package/src/components/ui/input-group.d.ts +10 -9
  78. package/src/components/ui/input-group.js +13 -12
  79. package/src/components/ui/input.d.ts +2 -2
  80. package/src/components/ui/input.js +5 -4
  81. package/src/components/ui/popover.d.ts +5 -5
  82. package/src/components/ui/popover.js +7 -7
  83. package/src/components/ui/select.d.ts +7 -6
  84. package/src/components/ui/select.js +13 -12
  85. package/src/components/ui/textarea.d.ts +2 -2
  86. package/src/components/ui/textarea.js +4 -3
  87. package/src/components/ui/tooltip.d.ts +6 -5
  88. package/src/components/ui/tooltip.js +8 -7
  89. package/src/env.js +2 -2
  90. package/src/layout-manager/src/LayoutManagerModel.d.ts +5 -1
  91. package/src/lib/utils.d.ts +20 -0
  92. package/src/lib/utils.js +45 -0
  93. package/src/metamodel/adaptable.metamodel.d.ts +7 -19
  94. package/src/metamodel/adaptable.metamodel.js +1 -1
  95. package/src/migration/VersionUpgrade23.d.ts +2 -3
  96. package/src/migration/VersionUpgrade23.js +4 -16
  97. package/src/types.d.ts +0 -1
  98. package/themes/dark.css +7 -17
  99. package/tsconfig.esm.tsbuildinfo +1 -1
  100. package/src/AdaptableState/Common/FilterActionOnDataChange.d.ts +0 -17
  101. package/src/AdaptableState/Common/FilterActionOnDataChange.js +0 -4
  102. package/src/View/AdaptableComputedCSSVarsContext.d.ts +0 -12
  103. package/src/View/AdaptableComputedCSSVarsContext.js +0 -29
  104. package/src/components/Select/CSSNumericVariableWatch.d.ts +0 -11
  105. package/src/components/Select/CSSNumericVariableWatch.js +0 -45
@@ -32,7 +32,9 @@ export class CalculatedColumnModule extends AdaptableModuleBase {
32
32
  this.api.internalApi
33
33
  .getDataService()
34
34
  .on('CellDataChanged', (cellDataChangedInfo) => {
35
- if (cellDataChangedInfo.trigger !== 'aggChange' && !cellDataChangedInfo.preventEdit) {
35
+ if (cellDataChangedInfo.trigger !== 'aggChange' &&
36
+ cellDataChangedInfo.trigger !== 'calculatedColumnChange' &&
37
+ !cellDataChangedInfo.preventEdit) {
36
38
  this.api.internalApi
37
39
  .getCalculatedColumnExpressionService()
38
40
  .listentoCellDataChange(cellDataChangedInfo);
@@ -8,6 +8,7 @@ export declare class CalculatedColumnExpressionService implements ICalculatedCol
8
8
  private adaptableApi;
9
9
  private aggregatedScalarLiveValuesMap;
10
10
  constructor(adaptableApi: AdaptableApi);
11
+ buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo: CellDataChangedInfo): CellDataChangedInfo[];
11
12
  listentoCellDataChange(cellDataChangedInfo: CellDataChangedInfo): void;
12
13
  listentoRowDataChange(rowDataChangedInfo: RowDataChangedInfo): void;
13
14
  destroy(): void;
@@ -1,5 +1,6 @@
1
1
  import { CalculatedColumnModuleId } from '../Constants/ModuleConstants';
2
2
  import { AggregatedScalarLiveValue } from './AggregatedScalarLiveValue';
3
+ import { buildSyntheticCellDataChangedInfosForCalcColumns } from './CalculatedColumnSyntheticChange';
3
4
  export class CalculatedColumnExpressionService {
4
5
  adaptableApi;
5
6
  aggregatedScalarLiveValuesMap = new Map();
@@ -7,7 +8,13 @@ export class CalculatedColumnExpressionService {
7
8
  this.adaptableApi = adaptableApi;
8
9
  this.adaptableApi = adaptableApi;
9
10
  }
11
+ buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo) {
12
+ return buildSyntheticCellDataChangedInfosForCalcColumns(this.adaptableApi, cellDataChangedInfo);
13
+ }
10
14
  listentoCellDataChange(cellDataChangedInfo) {
15
+ if (cellDataChangedInfo.trigger === 'calculatedColumnChange') {
16
+ return;
17
+ }
11
18
  const refreshedCalculatedColumns = [];
12
19
  this.aggregatedScalarLiveValuesMap.forEach((aggregatedScalarLiveValue, calculatedColumnId) => {
13
20
  const calculatedColumn = this.adaptableApi.calculatedColumnApi.getCalculatedColumnById(calculatedColumnId);
@@ -0,0 +1,4 @@
1
+ import { AdaptableApi } from '../../types';
2
+ import { CellDataChangedInfo } from '../../AdaptableState/Common/CellDataChangedInfo';
3
+ export declare function buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi: AdaptableApi, info: CellDataChangedInfo): CellDataChangedInfo[];
4
+ export declare function expandCellDataChangedInfosWithCalculatedColumns(adaptableApi: AdaptableApi, cellDataChangedInfos: CellDataChangedInfo[]): CellDataChangedInfo[];
@@ -0,0 +1,115 @@
1
+ import * as parser from '../../parser/src';
2
+ import { CalculatedColumnModuleId } from '../Constants/ModuleConstants';
3
+ import Helper from '../Helpers/Helper';
4
+ function isScalarCalculatedColumn(calculatedColumn) {
5
+ return !!calculatedColumn.Query?.ScalarExpression;
6
+ }
7
+ function collectDependentScalarCalculatedColumns(adaptableApi, rootColumnId) {
8
+ const collected = [];
9
+ const seenCalcColumnIds = new Set();
10
+ const queue = [rootColumnId];
11
+ while (queue.length > 0) {
12
+ const columnId = queue.shift();
13
+ const adaptableColumn = adaptableApi.columnApi.getColumnWithColumnId(columnId);
14
+ if (!adaptableColumn) {
15
+ continue;
16
+ }
17
+ const dependentColumnIds = adaptableApi.calculatedColumnApi.internalApi.getCalculatedColumnsDependentOnColumn(adaptableColumn);
18
+ dependentColumnIds.forEach((dependentColumnId) => {
19
+ if (seenCalcColumnIds.has(dependentColumnId)) {
20
+ return;
21
+ }
22
+ const calculatedColumn = adaptableApi.calculatedColumnApi.getCalculatedColumnForColumnId(dependentColumnId);
23
+ if (!calculatedColumn || !isScalarCalculatedColumn(calculatedColumn)) {
24
+ return;
25
+ }
26
+ seenCalcColumnIds.add(dependentColumnId);
27
+ collected.push(calculatedColumn);
28
+ queue.push(dependentColumnId);
29
+ });
30
+ }
31
+ return collected;
32
+ }
33
+ function buildShadowRowData(adaptableApi, info) {
34
+ const shadowData = Helper.cloneObject(info.rowNode?.data ?? info.rowData ?? {});
35
+ const fieldName = info.column.field ?? info.column.columnId;
36
+ adaptableApi.internalApi.setValueUsingField(shadowData, fieldName, info.oldValue);
37
+ return shadowData;
38
+ }
39
+ function evaluateScalarExpressionWithShadowData(adaptableApi, calculatedColumn, rowNode, shadowData) {
40
+ const internalApi = adaptableApi.internalApi;
41
+ const moduleFns = internalApi
42
+ .getQueryLanguageService()
43
+ .getModuleExpressionFunctionsMap(CalculatedColumnModuleId);
44
+ const baseFunctions = { ...moduleFns.booleanFunctions, ...moduleFns.scalarFunctions };
45
+ const resolveColumnValue = (columnId) => {
46
+ const childCalculatedColumn = adaptableApi.calculatedColumnApi.getCalculatedColumnForColumnId(columnId);
47
+ if (childCalculatedColumn?.Query?.ScalarExpression) {
48
+ return evaluateScalarExpressionWithShadowData(adaptableApi, childCalculatedColumn, rowNode, shadowData);
49
+ }
50
+ const adaptableColumn = adaptableApi.columnApi.getColumnWithColumnId(columnId);
51
+ return internalApi.getValueUsingField(shadowData, adaptableColumn?.field ?? columnId);
52
+ };
53
+ const customFunctions = {
54
+ ...baseFunctions,
55
+ COL: {
56
+ ...baseFunctions.COL,
57
+ handler: (args) => resolveColumnValue(args[0]),
58
+ },
59
+ FIELD: {
60
+ ...baseFunctions.FIELD,
61
+ handler: (args) => internalApi.getValueUsingField(shadowData, args[0]),
62
+ },
63
+ };
64
+ return parser.evaluate(calculatedColumn.Query.ScalarExpression, {
65
+ node: { ...rowNode, data: shadowData },
66
+ functions: customFunctions,
67
+ ...internalApi.buildBaseContext(),
68
+ });
69
+ }
70
+ export function buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi, info) {
71
+ if (!info.rowNode ||
72
+ info.preventEdit ||
73
+ info.trigger === 'undo' ||
74
+ info.trigger === 'aggChange' ||
75
+ info.trigger === 'calculatedColumnChange') {
76
+ return [];
77
+ }
78
+ const calculatedColumns = collectDependentScalarCalculatedColumns(adaptableApi, info.column.columnId);
79
+ if (!calculatedColumns.length) {
80
+ return [];
81
+ }
82
+ const shadowData = buildShadowRowData(adaptableApi, info);
83
+ const expressionService = adaptableApi.internalApi.getCalculatedColumnExpressionService();
84
+ const syntheticEvents = [];
85
+ calculatedColumns.forEach((calculatedColumn) => {
86
+ const oldValue = evaluateScalarExpressionWithShadowData(adaptableApi, calculatedColumn, info.rowNode, shadowData);
87
+ const newValue = expressionService.evaluateCalculatedColumnQuery(calculatedColumn, info.rowNode);
88
+ if (oldValue == newValue) {
89
+ return;
90
+ }
91
+ const column = adaptableApi.columnApi.getColumnWithColumnId(calculatedColumn.ColumnId);
92
+ if (!column) {
93
+ return;
94
+ }
95
+ syntheticEvents.push(adaptableApi.internalApi.buildCellDataChangedInfo({
96
+ oldValue,
97
+ newValue,
98
+ column,
99
+ primaryKeyValue: info.primaryKeyValue,
100
+ rowNode: info.rowNode,
101
+ trigger: 'calculatedColumnChange',
102
+ }));
103
+ });
104
+ return syntheticEvents;
105
+ }
106
+ export function expandCellDataChangedInfosWithCalculatedColumns(adaptableApi, cellDataChangedInfos) {
107
+ if (!cellDataChangedInfos.length) {
108
+ return cellDataChangedInfos;
109
+ }
110
+ const syntheticEvents = cellDataChangedInfos.flatMap((info) => buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi, info));
111
+ if (!syntheticEvents.length) {
112
+ return cellDataChangedInfos;
113
+ }
114
+ return [...cellDataChangedInfos, ...syntheticEvents];
115
+ }
@@ -11,4 +11,5 @@ export interface ICalculatedColumnExpressionService extends IAdaptableService {
11
11
  destroyAggregatedScalarLiveValue(calculatedColumn: CalculatedColumn): void;
12
12
  listentoCellDataChange(cellDataChangedInfo: CellDataChangedInfo): void;
13
13
  listentoRowDataChange(rowDataChangedInfo: RowDataChangedInfo): void;
14
+ buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo: CellDataChangedInfo): CellDataChangedInfo[];
14
15
  }
@@ -25,7 +25,7 @@ export class AdaptablePopover extends React.Component {
25
25
  const openOnHover = showEvent === 'mouseenter';
26
26
  const triggerElement = useButton ? (_jsx(ButtonInfo, { style: iconStyle, variant: "text", onClick: () => null, icon: showIcon && icon, tooltip: this.props.tooltipText, disabled: this.props.disabled, children: this.props.children })) : (_jsxs("div", { title: this.props.tooltipText, tabIndex: 0, style: { cursor: 'pointer', display: 'inline-block' }, children: [this.props.children, showIcon && _jsx(Icon, { name: icon, style: iconStyle })] }));
27
27
  const controlledProps = this.props.visible !== undefined ? { open: this.props.visible } : {};
28
- return (_jsx(Flex, { alignItems: "center", className: this.props.className, children: _jsxs(Popover, { ...controlledProps, children: [_jsx(PopoverTrigger, { nativeButton: !!useButton, openOnHover: openOnHover, delay: 0, closeDelay: 0, render: triggerElement }), _jsxs(PopoverContent, { align: "start", sideOffset: 10, className: "ab-Popover twa:w-auto twa:gap-0 twa:p-0", style: {
28
+ return (_jsx(Flex, { alignItems: "center", className: this.props.className, children: _jsxs(Popover, { ...controlledProps, children: [_jsx(PopoverTrigger, { nativeButton: !!useButton, openOnHover: openOnHover, delay: 0, closeDelay: 0, render: triggerElement }), _jsxs(PopoverContent, { align: "start", sideOffset: 10, className: "ab-Popover twa:border twa:border-primarylight twa:w-auto twa:gap-0 twa:p-0", style: {
29
29
  minWidth: popoverMinWidth,
30
30
  maxWidth: this.props.popoverMaxWidth ?? 300,
31
31
  }, children: [title ? _jsx(Box, { className: "twa:text-4 twa:p-2", children: title }) : null, _jsx(Box, { className: `ab-Popover__body ${(this.props.popupPadding ?? 2) === 0 ? 'twa:p-0' : 'twa:p-2'}`, children: this.props.bodyText.map((textOrHTML, index) => (_jsx("span", { children: textOrHTML }, index))) })] })] }) }));
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
3
  import { CheckBox } from '../../../../components/CheckBox';
4
- import DropdownButton from '../../../../components/DropdownButton';
4
+ import { SingleSelect } from '../../../../components/NewSelect';
5
5
  import FormLayout, { FormRow } from '../../../../components/FormLayout';
6
6
  import { validateChartName } from '../../../../Utilities/Helpers/chartingHelper';
7
7
  import AdaptableInput from '../../../Components/AdaptableInput';
@@ -35,27 +35,19 @@ export const SettingsSection = (props) => {
35
35
  });
36
36
  }, [props.chartDefinition]);
37
37
  const aggFuncs = ['sum', 'min', 'max', 'count', 'avg', 'first', 'last'];
38
- const aggFuncsOptions = aggFuncs.map((aggFunc) => ({
39
- label: aggFunc,
40
- onClick: () => {
41
- props.onChange({
42
- ...props.chartDefinition,
43
- Model: {
44
- ...props.chartDefinition.Model,
45
- aggFunc,
46
- },
47
- });
48
- },
49
- }));
50
38
  const aggFunc = props.chartDefinition.Model.aggFunc;
51
- const handleAggFuncClear = React.useCallback(() => {
39
+ const handleAggFuncChange = React.useCallback((value) => {
52
40
  props.onChange({
53
41
  ...props.chartDefinition,
54
42
  Model: {
55
43
  ...props.chartDefinition.Model,
56
- aggFunc: '',
44
+ aggFunc: value,
57
45
  },
58
46
  });
59
47
  }, [props.chartDefinition]);
60
- return (_jsxs(FormLayout, { children: [_jsx(FormRow, { label: "Name", children: _jsx(AdaptableInput, { onChange: handleNameChange, value: props.chartDefinition.Name }) }), _jsx(FormRow, { label: "Unlink Chart", children: _jsx(CheckBox, { onClick: handleUnLinkChange, checked: props.chartDefinition.Model.unlinkChart }) }), _jsx(FormRow, { label: "Suppress Chart Ranges", children: _jsx(CheckBox, { onClick: handleSuppressChartRanges, checked: props.chartDefinition.Model.suppressChartRanges }) }), props.chartDefinition.Model.modelType === 'range' && typeof aggFunc !== 'function' && (_jsx(FormRow, { label: "Agg Func", children: _jsx(DropdownButton, { columns: ['label'], items: aggFuncsOptions, onClear: handleAggFuncClear, children: aggFunc ? aggFunc : 'Select ' }) }))] }));
48
+ const aggFuncsOptions = aggFuncs.map((option) => ({
49
+ label: option,
50
+ value: option,
51
+ }));
52
+ return (_jsxs(FormLayout, { children: [_jsx(FormRow, { label: "Name", children: _jsx(AdaptableInput, { onChange: handleNameChange, value: props.chartDefinition.Name }) }), _jsx(FormRow, { label: "Unlink Chart", children: _jsx(CheckBox, { onClick: handleUnLinkChange, checked: props.chartDefinition.Model.unlinkChart }) }), _jsx(FormRow, { label: "Suppress Chart Ranges", children: _jsx(CheckBox, { onClick: handleSuppressChartRanges, checked: props.chartDefinition.Model.suppressChartRanges }) }), props.chartDefinition.Model.modelType === 'range' && typeof aggFunc !== 'function' && (_jsx(FormRow, { label: "Agg Func", children: _jsx(SingleSelect, { placeholder: "Select", items: aggFuncsOptions, value: aggFunc || undefined, onValueChange: handleAggFuncChange }) }))] }));
61
53
  };
@@ -4,4 +4,4 @@ export interface InfoButtonProps extends SimpleButtonProps {
4
4
  glyph?: string;
5
5
  tooltip?: string;
6
6
  }
7
- export declare const ButtonInfo: React.FunctionComponent<InfoButtonProps>;
7
+ export declare const ButtonInfo: React.ForwardRefExoticComponent<Omit<InfoButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from 'react';
2
3
  import SimpleButton from '../../../components/SimpleButton';
3
- export const ButtonInfo = (props) => {
4
- return (_jsx(SimpleButton, { "data-name": "info", iconSize: 20, icon: "info", variant: "raised", tone: "accent", ...props }));
5
- };
4
+ export const ButtonInfo = React.forwardRef(function ButtonInfo(props, ref) {
5
+ return (_jsx(SimpleButton, { ref: ref, "data-name": "info", iconSize: 20, icon: "info", variant: "raised", tone: "accent", ...props }));
6
+ });
@@ -19,7 +19,7 @@ export const AdaptableColumnFilter = (props) => {
19
19
  handlePredicateChange(predicate);
20
20
  }, [handlePredicateChange]) }) }));
21
21
  if (props.location === 'filtersToolPanel') {
22
- return (_jsx(Panel, { className: "twa:mb-2", bodyProps: { className: 'twa:p-0' }, children: filterContent }));
22
+ return (_jsx(Panel, { className: "twa:p-1", bodyProps: { className: 'twa:p-0 twa:border-none' }, children: filterContent }));
23
23
  }
24
24
  return filterContent;
25
25
  };
@@ -11,11 +11,13 @@ import clsx from 'clsx';
11
11
  import { twMerge } from '../../../twMerge';
12
12
  import { SingleSelect } from '../../../components/NewSelect';
13
13
  import { isEmbeddedColumnFilterLocation } from './columnFilterLocation';
14
+ import { captureTab } from '../../../lib/utils';
14
15
  const ColumnFilterPredicateDropdown = (props) => {
15
16
  const predicateDef = usePredicateDef(props.predicate?.operator, props.predicateDefs);
16
17
  const options = props.predicateDefs.map((predicateDef) => {
17
18
  return {
18
- label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(SimpleButton, { as: "span", variant: "raised", className: "twa:mr-2", tone: "accent", children: predicateDef.icon }), predicateDef.label] })),
19
+ label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(SimpleButton, { as: "span", variant: "raised", className: "twa:mr-2 twa:p-0.5", tone: "accent", children: predicateDef.icon }), predicateDef.label] })),
20
+ tooltip: predicateDef.label,
19
21
  value: predicateDef.operator,
20
22
  };
21
23
  });
@@ -23,15 +25,14 @@ const ColumnFilterPredicateDropdown = (props) => {
23
25
  const isAndOr = operator === 'AND' || operator === 'OR';
24
26
  return (_jsx(Box, { className: "twa:flex twa:items-center ab-ColumnFilterPredicateDropdown twa:p-0.5", style: {
25
27
  //@ts-ignore ignore
26
- '--ab-cmp-input__background': 'var(--ab-color-primary)',
27
28
  '--ab-color-input-background': 'var(--ab-color-primary)',
28
- }, children: _jsx(SingleSelect, { "data-name": "filter-predicate-dropdown",
29
+ }, children: _jsx(SingleSelect, { "data-name": "filter-predicate-dropdown", extraWidthChars: 8,
29
30
  // The trigger lives inside ag-grid's column menu, which closes itself
30
31
  // on mousedowns outside its DOM subtree. Since the popup is portaled
31
32
  // to `document.body`, mousedowns inside it would otherwise bubble to
32
33
  // `document` and unmount the trigger mid-interaction (causing the
33
34
  // popup to re-align to (0,0) before disappearing).
34
- stopMouseDownPropagation: true, className: predicateDef ? `twa:min-w-[10rem]` : null, onValueChange: (value) => {
35
+ stopMouseDownPropagation: true, showItemTooltip: true, className: predicateDef ? `twa:min-w-[10rem]` : null, onValueChange: (value) => {
35
36
  props.onPredicateChange({
36
37
  operator: value,
37
38
  args: [],
@@ -60,6 +61,7 @@ const AndOrInput = (props) => {
60
61
  export const ColumnFilterComponent = (props) => {
61
62
  const adaptable = useAdaptable();
62
63
  const manuallyApplyColumnFilter = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId);
64
+ const rootRef = React.useRef(null);
63
65
  const contentWrapperRef = React.useRef(null);
64
66
  React.useEffect(() => {
65
67
  if (props.location !== 'columnMenu')
@@ -69,6 +71,14 @@ export const ColumnFilterComponent = (props) => {
69
71
  const dropdown = contentWrapperRef.current?.querySelector('[data-name="filter-predicate-dropdown"]');
70
72
  dropdown?.focus();
71
73
  }, [props.location]);
74
+ // When rendered inside ag-grid's column menu, Tabbing would otherwise escape
75
+ // to the surrounding menu/grid. Trap focus so Tab / Shift+Tab cycle within the filter.
76
+ const handleFocusTrap = React.useCallback((e) => {
77
+ if (props.location !== 'columnMenu') {
78
+ return;
79
+ }
80
+ captureTab(rootRef.current, e);
81
+ }, [props.location]);
72
82
  const [predicateNotYetApplied, setPredicateNotYetApplied] = React.useState(props.predicate);
73
83
  const applyFilter = () => {
74
84
  props.onPredicateChange(currentPredicateRef.current);
@@ -129,7 +139,7 @@ export const ColumnFilterComponent = (props) => {
129
139
  .map((qlPredicate) => mapQlPredicateToAdaptablePredicate(qlPredicate))
130
140
  .some((adaptablePredicate) => adaptable.api.predicateApi.isValidPredicate(adaptablePredicate));
131
141
  };
132
- return (_jsxs(_Fragment, { children: [_jsxs(Flex, { flexDirection: "column", className: clsx({
142
+ return (_jsxs("div", { ref: rootRef, onKeyDown: handleFocusTrap, className: "twa:contents", children: [_jsxs(Flex, { flexDirection: "column", className: clsx({
133
143
  'twa:pb-2': !props.hideActionButtons,
134
144
  'twa:mb-2': isEmbeddedColumnFilterLocation(props.location),
135
145
  'twa:mt-2 twa:ml-2 twa:mr-2': props.location === 'columnMenu',
@@ -28,5 +28,5 @@ export const ColumnFilterWindow = (props) => {
28
28
  return (_jsxs(Flex, { children: [label, _jsx(Box, { className: "twa:flex-1" }), _jsx(AdaptableIconComponent, { icon: { name: 'filter' } })] }));
29
29
  }
30
30
  return label;
31
- }, onChange: (column) => setColumnId(column), filterColumn: (column) => column.queryable, isMulti: false, value: columnId }) }) }) }), _jsx(AdaptableColumnFilter, { columnId: columnId, location: 'filterForm' })] }));
31
+ }, onChange: (column) => setColumnId(column), filterColumn: (column) => column.queryable, value: columnId }) }) }) }), _jsx(AdaptableColumnFilter, { columnId: columnId, location: 'filterForm' })] }));
32
32
  };
@@ -1,15 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import OverlayTrigger from '../../../components/OverlayTrigger';
4
3
  import SimpleButton from '../../../components/SimpleButton';
5
4
  import { useAdaptable } from '../../AdaptableContext';
6
5
  import { AdaptableIconComponent } from '../AdaptableIconComponent';
7
- import { ColumnFilterMenu } from './components/ColumnFilterMenu';
6
+ import { SingleSelect } from '../../../components/NewSelect';
8
7
  import { FloatingFilterInputList } from './components/FloatingFilterInputList';
9
8
  import { isPredicateEmpty, qlPredicateToString } from './utils';
10
9
  import { AG_GRID_GROUPED_COLUMN } from '../../../Utilities/Constants/GeneralConstants';
11
10
  import { Box, Flex } from '../../../components/Flex';
12
- import { cn } from '../../../lib/utils';
11
+ import { cn, getFocusableElements } from '../../../lib/utils';
13
12
  import { Maximize2 } from 'lucide-react';
14
13
  export const FloatingFilter = (props) => {
15
14
  const adaptable = useAdaptable();
@@ -40,75 +39,74 @@ export const FloatingFilter = (props) => {
40
39
  const colDef = adaptable.api.columnApi.getAGGridColDefForColumnId(props.columnId);
41
40
  const showExpandFilterButton = colDef?.suppressHeaderFilterButton !== true;
42
41
  const handleClear = () => props.onClear?.();
43
- const showEvent = 'click';
44
- const hideEvent = 'blur';
45
- const [overlayVisible, setOverlayVisible] = React.useState(false);
42
+ const [selectOpen, setSelectOpen] = React.useState(false);
43
+ const currentOperator = props.predicate?.args[0]?.operator;
44
+ const operatorOptions = props.predicateDefs.map((predicateDef) => ({
45
+ label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(Box, { className: "twa:mr-2 twa:flex twa:items-center", children: predicateDef.icon }), _jsx(Box, { className: "twa:truncate", "data-name": "filter-predicate-label", "data-label": predicateDef.label, children: predicateDef.label })] })),
46
+ tooltip: predicateDef.label,
47
+ value: predicateDef.operator,
48
+ }));
49
+ const renderTriggerValue = () => (_jsxs(Flex, { alignItems: "center", className: "twa:min-w-0", children: [_jsx(Box, { className: "twa:flex twa:items-center", children: !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (_jsx(AdaptableIconComponent, { icon: { name: 'filter' } })) }), showLabel && (_jsx(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1 twa:truncate", title: label, children: label }))] }));
46
50
  let filterDropdown = null;
47
- const filterDropdownButton = (_jsxs(SimpleButton, { variant: "text", "data-name": "floating-filter-button", "aria-label": "Column Filter Operator Dropdown", tooltip: "Click to change filter operator", onBlur: () => {
48
- if (isInlineEditable) {
49
- setOverlayVisible(false);
50
- }
51
- }, "data-value": props.predicate?.args[0]?.operator, onClick: () => {
52
- if (!isInlineEditable) {
51
+ const filterDropdownSelect = (_jsx(SingleSelect, { chevronIcon: null, "data-name": "floating-filter-button", ariaLabel: "Column Filter Operator Dropdown", size: "small", stopMouseDownPropagation: true, disabled: props.disabled, open: selectOpen, extraWidthChars: 5, onOpenChange: (nextOpen) => {
52
+ // In non-inline mode the select doesn't pick an operator inline; opening it
53
+ // instead opens the full column filter popup, so keep the dropdown closed.
54
+ if (nextOpen && !isInlineEditable) {
53
55
  adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId);
56
+ return;
54
57
  }
55
- else {
56
- setOverlayVisible(true);
57
- }
58
- }, className: "twa:my-0.5 twa:mx-0.5 twa:text-left twa:p-0.5", style: {
59
- ...(!isInlineEditable
60
- ? {
61
- minWidth: 0,
62
- flex: 1,
63
- }
64
- : {}),
65
- }, children: [_jsx(Box, { children: !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (_jsx(AdaptableIconComponent, { icon: { name: 'filter' } })) }), showLabel && (_jsx(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1", title: label, children: label }))] }));
58
+ setSelectOpen(nextOpen);
59
+ }, value: currentOperator, placeholder: label, items: operatorOptions, showItemTooltip: true, renderValue: renderTriggerValue, onValueChange: (operator) => {
60
+ props.onPredicateChange({
61
+ operator: props.predicate.operator,
62
+ args: [{ operator: operator, args: [] }],
63
+ });
64
+ }, className: cn('twa:self-center twa:mx-0.5 twa:my-0.5 twa:text-left twa:p-0.5 twa:border-none', 'twa:shadow-none', !isInlineEditable && 'twa:min-w-0 twa:flex-1') }));
66
65
  if (isInlineEditable) {
67
- filterDropdown = showQuickFilterDropdown && (_jsx(OverlayTrigger, { className: "ab-FloatingFilter-overlay", showEvent: showEvent, hideEvent: hideEvent, visible: overlayVisible, onVisibleChange: setOverlayVisible, preventPortalEventPropagation: showEvent === 'click', targetOffset: 10, hideDelay: 50, "data-name": "floating-filter-overlay", render: () => {
68
- // we render this only for single filter
69
- return (_jsx(ColumnFilterMenu, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
70
- setOverlayVisible(false);
71
- props.onPredicateChange({
72
- operator: props.predicate.operator,
73
- args: [predicate],
74
- });
75
- } }));
76
- }, children: filterDropdownButton }));
66
+ filterDropdown = showQuickFilterDropdown && filterDropdownSelect;
77
67
  }
78
68
  else {
79
- filterDropdown = filterDropdownButton;
69
+ filterDropdown = filterDropdownSelect;
80
70
  }
81
71
  const showClearButton = isMultiple ||
82
72
  !isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef);
83
73
  return (_jsxs(Flex, { className: "ab-FloatingFilter twa:w-full", onKeyDownCapture: (e) => {
84
74
  // AG Grid's header keyboard navigation intercepts Tab and calls preventDefault(),
85
- // which prevents focus from moving between elements inside the floating filter.
86
- // We handle Tab manually in the capture phase (before AG Grid's handlers).
87
- if (e.key === 'Tab') {
88
- const target = e.target;
89
- const wrapper = e.currentTarget;
90
- if (!e.shiftKey) {
91
- // Tab forward: from filter button → select input
92
- if (target.getAttribute('data-name') === 'floating-filter-button') {
93
- const selectInput = wrapper.querySelector('[data-name="Select Values"] input');
94
- if (selectInput) {
95
- e.preventDefault();
96
- e.nativeEvent.stopImmediatePropagation();
97
- selectInput.focus();
98
- // When the DummyInput gets focus the combobox sets isFocused=true,
99
- // triggering a React re-render. During this re-render, unstable component
100
- // references can cause the DummyInput to be removed from the DOM and
101
- // recreated, losing focus. We restore focus after the re-render.
102
- requestAnimationFrame(() => {
103
- if (document.activeElement === document.body || document.activeElement === null) {
104
- const newInput = wrapper.querySelector('[data-name="Select Values"] input');
105
- newInput?.focus();
106
- }
107
- });
108
- }
109
- }
110
- }
75
+ // which prevents focus from moving between the controls inside the floating filter
76
+ // (operator select, filter input(s), expand/clear buttons). We handle Tab ourselves
77
+ // in the capture phase (before AG Grid's handlers) and move focus to the next/previous
78
+ // focusable control. At the boundaries we let the event through so AG Grid can move
79
+ // to the adjacent header cell.
80
+ if (e.key !== 'Tab') {
81
+ return;
82
+ }
83
+ const wrapper = e.currentTarget;
84
+ const focusable = getFocusableElements(wrapper);
85
+ if (focusable.length === 0) {
86
+ return;
111
87
  }
88
+ const active = document.activeElement;
89
+ const currentIndex = active ? focusable.indexOf(active) : -1;
90
+ if (currentIndex === -1) {
91
+ return;
92
+ }
93
+ const nextIndex = currentIndex + (e.shiftKey ? -1 : 1);
94
+ if (nextIndex < 0 || nextIndex >= focusable.length) {
95
+ // boundary reached: let AG Grid navigate between header cells
96
+ return;
97
+ }
98
+ e.preventDefault();
99
+ e.nativeEvent.stopImmediatePropagation();
100
+ focusable[nextIndex]?.focus();
101
+ // Focusing the values combobox's input makes it set isFocused=true, which
102
+ // re-renders and can momentarily recreate the input, dropping focus to <body>.
103
+ // Re-resolve the target after the re-render and restore focus to it.
104
+ requestAnimationFrame(() => {
105
+ if (document.activeElement === document.body || document.activeElement === null) {
106
+ const refreshed = getFocusableElements(wrapper);
107
+ refreshed[Math.min(nextIndex, refreshed.length - 1)]?.focus();
108
+ }
109
+ });
112
110
  }, children: [filterDropdown, isInlineEditable && (_jsx(Flex, { className: "twa:flex-1 twa:min-w-0", children: _jsx(FloatingFilterInputList, { onKeyDown: props.onKeydown, columnId: props.columnId, disabled: props.disabled,
113
111
  // It works only with a predicate
114
112
  predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
@@ -162,7 +162,7 @@ export const ColumnValuesSelect = (props) => {
162
162
  : props.onChange, items: options,
163
163
  // for dates, the treeDateOptions have ids that are numbers
164
164
  // so we have to add the `toDateValue` function to convert the values to the correct format
165
- value: selectedColumnValues, primaryKey: 'value', isLoading: props.isLoading, onOpenChange: onOpenChange, showClear: isEmbeddedColumnFilterLocation(location) })) : (_jsx(GridFilterCombobox, { disabled: props.disabled, ...selectProps, onOpenChange: onOpenChange, items: options, value: value, isLoading: props.isLoading, onValueChange: props.onChange, showClear: isEmbeddedColumnFilterLocation(location) }, "select"));
165
+ value: selectedColumnValues, "data-name": "Select Values", primaryKey: 'value', isLoading: props.isLoading, onOpenChange: onOpenChange, showClear: isEmbeddedColumnFilterLocation(location) })) : (_jsx(GridFilterCombobox, { disabled: props.disabled, ...selectProps, onOpenChange: onOpenChange, items: options, value: value, isLoading: props.isLoading, onValueChange: props.onChange, showClear: isEmbeddedColumnFilterLocation(location) }, "select"));
166
166
  return (_jsx("div", { className: join(baseClassName, 'twa:relative', props.isLoading && `${baseClassName}--loading`, !value.length && `${baseClassName}--empty`), onKeyDownCapture: (e) => {
167
167
  if (e.key === 'Tab') {
168
168
  // Prevent AG Grid from hijacking Tab; keep browser default focus navigation.
@@ -9,6 +9,7 @@ export const AdaptableFormControlTextClear = React.forwardRef((props, ref) => {
9
9
  let closeButtonTooltip = props.value ? 'Clear' : null;
10
10
  const inputRef = React.useRef(null);
11
11
  const { focusOnClear = true } = props;
12
+ const clearDisabled = StringExtensions.IsNullOrEmpty(props.value.toString());
12
13
  return (_jsxs(FieldWrap, { onClick: props.onClick, className: twMerge('twa:bg-input-background twa:text-input-foreground twa:overflow-visible twa:w-full twa:rounded-input', props.className), style: props.style, children: [_jsx(Input, { "aria-label": props['aria-label'], autoFocus: props.autoFocus, style: props.inputStyle, className: props.inputClassName, ref: (r) => {
13
14
  inputRef.current = r;
14
15
  if (!ref) {
@@ -31,5 +32,5 @@ export const AdaptableFormControlTextClear = React.forwardRef((props, ref) => {
31
32
  input.focus();
32
33
  }
33
34
  });
34
- }, disabled: StringExtensions.IsNullOrEmpty(props.value.toString()) })] }));
35
+ }, disabled: clearDisabled })] }));
35
36
  });
@@ -67,7 +67,7 @@ export const AdaptablePopup = (props) => {
67
67
  props.onHide();
68
68
  }
69
69
  },
70
- }, children: _jsxs(AdaptablePopupDialog, { dataName: componentModule, baseClassName: baseClassName, className: className, friendlyName: friendlyName, isActionModule: isStandalone, isWindowModal: isWindowModal, onHide: props.onHide, modalContainer: modalContainer, children: [!isStandalone && _jsx(TopBar, { icon: settingsPanelOptions.icon, children: settingsPanelTitle }), _jsxs(Box, { className: clsx('twa:flex twa:flex-row twa:flex-1 twa:min-h-0', 'twa:bg-defaultbackground twa:text-foreground', 'twa:rounded-bl-standard twa:rounded-br-standard', accessLevel == GeneralConstants.ACCESS_LEVEL_READ_ONLY
70
+ }, children: _jsxs(AdaptablePopupDialog, { dataName: componentModule, baseClassName: baseClassName, className: className, friendlyName: friendlyName, isActionModule: isStandalone, isWindowModal: isWindowModal, onHide: props.onHide, modalContainer: modalContainer, children: [!isStandalone && _jsx(TopBar, { icon: settingsPanelOptions.icon, children: settingsPanelTitle }), _jsxs(Box, { className: clsx('twa:flex twa:flex-row twa:flex-1 twa:min-h-0', 'twa:bg-background twa:text-foreground', 'twa:rounded-bl-standard twa:rounded-br-standard', accessLevel == GeneralConstants.ACCESS_LEVEL_READ_ONLY
71
71
  ? GeneralConstants.READ_ONLY_STYLE
72
72
  : ''), children: [!isStandalone && (_jsx(Navigation, { menuItems: menuItems, api: props.api, activeItem: activeItem, customSettingsPanels: settingsPanelOptions.customSettingsPanels })), _jsx(Box, { className: clsx('ab-Adaptable-Popup__Body', 'twa:bg-primarylight twa:text-primarylight-foreground', 'twa:flex twa:flex-1 twa:min-w-0 twa:overflow-auto', 'twa:rounded-br-standard', !isStandalone && 'twa:*:p-3'), children: moduleViewContent })] })] }) }));
73
73
  };
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import * as React from 'react';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
4
  import { ACCESS_LEVEL_READ_ONLY } from '../../../../Utilities/Constants/GeneralConstants';
5
- import DropdownButton from '../../../../components/DropdownButton';
6
5
  import EmptyContent from '../../../../components/EmptyContent';
7
6
  import { Icon } from '../../../../components/icons';
8
7
  import { AdaptableObjectList } from '../../AdaptableObjectList';
@@ -17,6 +16,7 @@ import { useRerender } from '../../../../components/utils/useRerender';
17
16
  import { Box, Flex } from '../../../../components/Flex';
18
17
  import Panel from '../../../../components/Panel';
19
18
  import { Tabs } from '../../../../components/Tabs';
19
+ import { NewDropdownButton } from '../../../../components/NewDropdownButton';
20
20
  export const AdaptablePopupModuleView = (props) => {
21
21
  /**
22
22
  * This triggers a render for each state change.
@@ -80,7 +80,7 @@ export const AdaptablePopupModuleView = (props) => {
80
80
  label: abObjectType.label ?? abObjectType.name,
81
81
  };
82
82
  });
83
- newButton = (_jsxs(DropdownButton, { tone: "accent", variant: "raised", columns: ['label'], items: items, tooltip: toolTipText, children: [_jsx(Icon, { name: "plus" }), " New"] }));
83
+ newButton = (_jsxs(NewDropdownButton, { showDivider: false, tone: "accent", variant: "raised", items: items, tooltip: toolTipText, children: [_jsx(Icon, { name: "plus" }), " New"] }));
84
84
  }
85
85
  else if (!moduleViewProperties.hideNewButton &&
86
86
  (EditWizard || moduleViewProperties.onOpenEditPopup)) {
@@ -15,6 +15,7 @@ export const ColumnSelector = function (props) {
15
15
  return {
16
16
  label,
17
17
  textLabel,
18
+ tooltip: textLabel,
18
19
  value: column.columnId,
19
20
  };
20
21
  })
@@ -31,7 +32,11 @@ export const ColumnSelector = function (props) {
31
32
  virtualized: true,
32
33
  items: options,
33
34
  showClear: false,
35
+ showItemTooltip: true,
34
36
  onValueChange: (colId) => {
37
+ if (colId === null) {
38
+ return;
39
+ }
35
40
  props.onChange(colId);
36
41
  },
37
42
  value: props.value,
@@ -101,7 +101,7 @@ export function ValueSelector(props) {
101
101
  notifyChange();
102
102
  },
103
103
  };
104
- return (_jsxs(Flex, { style: props.style, className: clsx('twa:flex-1', baseClassName), flexDirection: "column", children: [_jsx(Flex, { className: "twa:mb-1", children: showFilterInput && filter ? (_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", inputClassName: "twa:p-3", className: "twa:flex-1 twa:border-0 twa:m-[3px]" })) : (_jsx(Box, { className: "twa:flex-1" })) }), renderSelectionSection(selectionSectionProps), _jsx(DragDropProvider, { children: _jsx(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column", children: _jsx(DragList, { dragListId: "value-selector", orientation: "vertical", onDragProxyMove: defaultDragProxyMove, onDragProxySetup: ({ proxyElement }) => {
104
+ return (_jsxs(Flex, { style: props.style, className: clsx('twa:flex-1', baseClassName), flexDirection: "column", children: [_jsx(Flex, { className: "twa:mb-1", children: showFilterInput && filter ? (_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", inputClassName: "twa:p-3", className: "twa:flex-1 twa:m-[3px]" })) : (_jsx(Box, { className: "twa:flex-1" })) }), renderSelectionSection(selectionSectionProps), _jsx(DragDropProvider, { children: _jsx(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column", children: _jsx(DragList, { dragListId: "value-selector", orientation: "vertical", onDragProxyMove: defaultDragProxyMove, onDragProxySetup: ({ proxyElement }) => {
105
105
  proxyElement.classList.add('twa:shadow-md');
106
106
  }, onDrop: (_sortedIndexes) => {
107
107
  const selection = [];
@@ -6,7 +6,9 @@ import { Flex } from '../../../components/Flex';
6
6
  import { isScopeColumnIds } from '../../../AdaptableState/Common/ColumnScope';
7
7
  export const FlashingAlertScopeWizardSection = (props) => {
8
8
  const { data, api } = useOnePageAdaptableWizardContext();
9
- const availableColumns = React.useMemo(() => api.columnApi.getNonSpecialColumns(), []);
9
+ const availableColumns = React.useMemo(() => api.columnApi
10
+ .getUIAvailableColumns()
11
+ .filter((column) => !column.isActionColumn && !api.columnApi.isFdc3Column(column.columnId)), [api]);
10
12
  return (_jsx(Flex, { flexDirection: "column", className: "twa:p-2 twa:h-full", children: _jsx(NewScopeComponent, { descriptions: {
11
13
  rowScope: 'Changes anywhere in the row will trigger an Flashing Cell',
12
14
  columnScope: 'Changes in selected columns will trigger an Flashing Cell',