@adaptabletools/adaptable 23.0.0-canary.3 → 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 (43) hide show
  1. package/package.json +1 -1
  2. package/src/AdaptableOptions/DefaultAdaptableOptions.js +0 -4
  3. package/src/AdaptableOptions/FilterOptions.d.ts +0 -7
  4. package/src/AdaptableState/Common/AdaptableForm.d.ts +18 -1
  5. package/src/AdaptableState/Common/AdaptableForm.js +31 -0
  6. package/src/AdaptableState/Common/CellDataChangedInfo.d.ts +3 -2
  7. package/src/AdaptableState/Common/Enums.d.ts +0 -5
  8. package/src/AdaptableState/Common/Enums.js +0 -6
  9. package/src/Api/Implementation/LayoutHelpers.js +12 -0
  10. package/src/Strategy/CalculatedColumnModule.js +3 -1
  11. package/src/Utilities/Services/CalculatedColumnExpressionService.d.ts +1 -0
  12. package/src/Utilities/Services/CalculatedColumnExpressionService.js +7 -0
  13. package/src/Utilities/Services/CalculatedColumnSyntheticChange.d.ts +4 -0
  14. package/src/Utilities/Services/CalculatedColumnSyntheticChange.js +115 -0
  15. package/src/Utilities/Services/Interface/ICalculatedColumnExpressionService.d.ts +1 -0
  16. package/src/View/Charting/ChartingWizard/AgChargingWizard/SettingsSection.js +8 -16
  17. package/src/View/Components/ColumnFilter/ColumnFilterWindow.js +1 -1
  18. package/src/View/Components/Selectors/ColumnSelector.js +5 -0
  19. package/src/View/FlashingCell/Wizard/FlashingCellScopeWizardSection.js +3 -1
  20. package/src/View/Layout/LayoutViewPanel.js +23 -21
  21. package/src/View/renderWithAdaptableContext.js +2 -3
  22. package/src/agGrid/AdaptableAgGrid.d.ts +0 -1
  23. package/src/agGrid/AdaptableAgGrid.js +3 -18
  24. package/src/agGrid/AgGridColumnAdapter.js +1 -4
  25. package/src/components/AdaptableFormComponent/AdaptableFormComponent.js +11 -6
  26. package/src/components/Combobox/VirtualizedList.js +5 -5
  27. package/src/components/Combobox/comboboxUtils.d.ts +4 -1
  28. package/src/components/Combobox/comboboxUtils.js +2 -0
  29. package/src/components/Combobox/index.d.ts +1 -0
  30. package/src/components/Combobox/index.js +35 -15
  31. package/src/components/Tree/TreeDropdown/index.js +2 -6
  32. package/src/env.js +2 -2
  33. package/src/layout-manager/src/LayoutManagerModel.d.ts +5 -1
  34. package/src/metamodel/adaptable.metamodel.d.ts +0 -17
  35. package/src/metamodel/adaptable.metamodel.js +1 -1
  36. package/src/types.d.ts +0 -1
  37. package/tsconfig.esm.tsbuildinfo +1 -1
  38. package/src/AdaptableState/Common/FilterActionOnDataChange.d.ts +0 -17
  39. package/src/AdaptableState/Common/FilterActionOnDataChange.js +0 -4
  40. package/src/View/AdaptableComputedCSSVarsContext.d.ts +0 -12
  41. package/src/View/AdaptableComputedCSSVarsContext.js +0 -29
  42. package/src/components/Select/CSSNumericVariableWatch.d.ts +0 -11
  43. package/src/components/Select/CSSNumericVariableWatch.js +0 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable",
3
- "version": "23.0.0-canary.3",
3
+ "version": "23.0.0-canary.4",
4
4
  "description": "Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -165,10 +165,6 @@ const DefaultAdaptableOptions = {
165
165
  },
166
166
  },
167
167
  filterOptions: {
168
- filterActionOnDataChange: {
169
- applyFilter: 'Always',
170
- throttleDelay: 0,
171
- },
172
168
  clearFiltersOnStartUp: false,
173
169
  enableFilterOnSpecialColumns: true,
174
170
  useAdaptableFiltering: true,
@@ -1,4 +1,3 @@
1
- import { FilterActionOnDataChange } from '../AdaptableState/Common/FilterActionOnDataChange';
2
1
  import { BaseContext } from '../../types';
3
2
  import { AdaptableColumn } from '../AdaptableState/Common/AdaptableColumn';
4
3
  import { SystemAlertPredicateId, SystemFilterPredicateId } from '../../types';
@@ -30,12 +29,6 @@ export interface FilterOptions<TData = any> {
30
29
  * @returns
31
30
  */
32
31
  customInFilterValues?: (context: CustomInFilterValuesContext<TData>) => Promise<InFilterValueResult> | InFilterValueResult;
33
- /**
34
- * When to re-filter grid after data changes: 'Always', 'Never' or 'Throttle' (with a delay value)
35
- *
36
- * @defaultValue 'Always'
37
- */
38
- filterActionOnDataChange?: FilterActionOnDataChange;
39
32
  /**
40
33
  * Allow filtering on Calculated & FreeText columns
41
34
  *
@@ -133,8 +133,19 @@ export interface AdaptableFormField {
133
133
  /**
134
134
  * Field Default Value - can be of type string, boolean, number, or for
135
135
  * `select` fields with `multi: true` an array of those.
136
+ *
137
+ * For single `select` fields, this is also the value restored when the user
138
+ * clears the combobox (unless {@link clearToDefault} is `false`).
136
139
  */
137
140
  defaultValue?: string | boolean | number | Array<string | number | boolean>;
141
+ /**
142
+ * For single `select` fields only. When the user clears the combobox,
143
+ * whether to restore {@link defaultValue} instead of leaving the field empty.
144
+ *
145
+ * Defaults to `true` when `defaultValue` is set, otherwise `false`.
146
+ * Set to `false` when an empty selection is a distinct state from the default.
147
+ */
148
+ clearToDefault?: boolean;
138
149
  /**
139
150
  * Items to populate the `select` and `radio` fieldTypes.
140
151
  *
@@ -166,7 +177,10 @@ export interface AdaptableFormField {
166
177
  /**
167
178
  * Placeholder text shown inside `text`, `textarea`, `number`, `date`,
168
179
  * `time` and `datetime` inputs when empty. For `select` fields it is
169
- * rendered as the empty-state label.
180
+ * rendered as the empty-state label when no value is selected.
181
+ *
182
+ * When omitted on a `select` field with a {@link defaultValue}, the label of
183
+ * the matching `options` entry is used as the empty-state label.
170
184
  */
171
185
  placeholder?: string;
172
186
  /**
@@ -310,6 +324,9 @@ export declare function isAdaptableFormFieldGroup(entry: AdaptableFormField | Ad
310
324
  * computing defaults, validation or per-field lookups.
311
325
  */
312
326
  export declare function flattenAdaptableFormFields<T extends BaseContext>(formDef?: AdaptableForm<T, any>): AdaptableFormField[];
327
+ export declare function shouldClearSelectToDefault(field: AdaptableFormField): boolean;
328
+ export declare function resolveSelectValueAfterClear(field: AdaptableFormField, newValue: unknown): unknown;
329
+ export declare function resolveSelectPlaceholder(field: AdaptableFormField, options: AdaptableFormFieldOption[]): string | undefined;
313
330
  export declare function getDefaultAdaptableFormData<T extends BaseContext = BaseContext>(formDef?: AdaptableForm<T, any>): AdaptableFormData;
314
331
  /**
315
332
  * Resolves a field's `options` to the current array of options.
@@ -32,6 +32,37 @@ export function flattenAdaptableFormFields(formDef) {
32
32
  }
33
33
  return out;
34
34
  }
35
+ export function shouldClearSelectToDefault(field) {
36
+ if (field.fieldType !== 'select' || field.multi) {
37
+ return false;
38
+ }
39
+ if (field.clearToDefault === false) {
40
+ return false;
41
+ }
42
+ if (field.clearToDefault === true) {
43
+ return true;
44
+ }
45
+ return (field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '');
46
+ }
47
+ export function resolveSelectValueAfterClear(field, newValue) {
48
+ if (field.fieldType !== 'select' || field.multi) {
49
+ return newValue;
50
+ }
51
+ const isEmpty = newValue === null || newValue === undefined || newValue === '';
52
+ if (!isEmpty || !shouldClearSelectToDefault(field)) {
53
+ return newValue;
54
+ }
55
+ return field.defaultValue;
56
+ }
57
+ export function resolveSelectPlaceholder(field, options) {
58
+ if (field.placeholder) {
59
+ return field.placeholder;
60
+ }
61
+ if (field.defaultValue === undefined || field.defaultValue === null || field.defaultValue === '') {
62
+ return undefined;
63
+ }
64
+ return options.find((option) => option.value === field.defaultValue)?.label;
65
+ }
35
66
  export function getDefaultAdaptableFormData(formDef) {
36
67
  return flattenAdaptableFormFields(formDef).reduce((data, field) => {
37
68
  if (field.fieldType === 'select' && field.multi) {
@@ -33,9 +33,10 @@ export interface CellDataChangedInfo<TData = any> {
33
33
  */
34
34
  rowData?: TData;
35
35
  /**
36
- * What triggered the change - user, background change or a reverted change?
36
+ * What triggered the change - user, background change, a reverted change, or a
37
+ * derived update on a Calculated Column whose source value changed?
37
38
  */
38
- trigger?: 'edit' | 'tick' | 'undo' | 'aggChange';
39
+ trigger?: 'edit' | 'tick' | 'undo' | 'aggChange' | 'calculatedColumnChange';
39
40
  /**
40
41
  * Whether the change was prevented by a validation rule
41
42
  */
@@ -49,11 +49,6 @@ export declare enum SummaryOperation {
49
49
  Only = "Only",
50
50
  Weighted_Average = "Weighted Avg"
51
51
  }
52
- export declare enum FilterOnDataChangeOptions {
53
- Always = "Always",
54
- Never = "Never",
55
- Throttle = "Throttle"
56
- }
57
52
  export declare enum ChangeDirection {
58
53
  Up = "Up",
59
54
  Down = "Down",
@@ -61,12 +61,6 @@ export var SummaryOperation;
61
61
  SummaryOperation["Only"] = "Only";
62
62
  SummaryOperation["Weighted_Average"] = "Weighted Avg";
63
63
  })(SummaryOperation || (SummaryOperation = {}));
64
- export var FilterOnDataChangeOptions;
65
- (function (FilterOnDataChangeOptions) {
66
- FilterOnDataChangeOptions["Always"] = "Always";
67
- FilterOnDataChangeOptions["Never"] = "Never";
68
- FilterOnDataChangeOptions["Throttle"] = "Throttle";
69
- })(FilterOnDataChangeOptions || (FilterOnDataChangeOptions = {}));
70
64
  export var ChangeDirection;
71
65
  (function (ChangeDirection) {
72
66
  ChangeDirection["Up"] = "Up";
@@ -248,6 +248,9 @@ export const tableLayoutToTableLayoutModel = (tableLayout) => {
248
248
  if (tableLayout.Metadata) {
249
249
  result.Ignore_Metadata = tableLayout.Metadata;
250
250
  }
251
+ if (tableLayout.OpenCharts) {
252
+ result.Ignore_OpenCharts = tableLayout.OpenCharts;
253
+ }
251
254
  if (tableLayout.RowSummaries != null) {
252
255
  result.Ignore_RowSummaries = tableLayout.RowSummaries;
253
256
  }
@@ -327,6 +330,9 @@ export const pivotLayoutToPivotLayoutModel = (pivotLayout) => {
327
330
  if (pivotLayout.Metadata) {
328
331
  result.Ignore_Metadata = pivotLayout.Metadata;
329
332
  }
333
+ if (pivotLayout.OpenCharts) {
334
+ result.Ignore_OpenCharts = pivotLayout.OpenCharts;
335
+ }
330
336
  return result;
331
337
  };
332
338
  function toAggFunc(aggFunc) {
@@ -376,6 +382,9 @@ export const tableLayoutModelToTableLayout = (layoutModel) => {
376
382
  if (layoutModel.Ignore_Metadata) {
377
383
  tableLayout.Metadata = layoutModel.Ignore_Metadata;
378
384
  }
385
+ if (layoutModel.Ignore_OpenCharts) {
386
+ tableLayout.OpenCharts = layoutModel.Ignore_OpenCharts;
387
+ }
379
388
  // if (layoutModel.RowGroupDisplayType) {
380
389
  tableLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType ?? 'single';
381
390
  // }
@@ -481,6 +490,9 @@ export const pivotLayoutModelToPivotLayout = (layoutModel) => {
481
490
  if (layoutModel.Ignore_Metadata) {
482
491
  pivotLayout.Metadata = layoutModel.Ignore_Metadata;
483
492
  }
493
+ if (layoutModel.Ignore_OpenCharts) {
494
+ pivotLayout.OpenCharts = layoutModel.Ignore_OpenCharts;
495
+ }
484
496
  if (layoutModel.PivotGroupedColumns) {
485
497
  pivotLayout.PivotGroupedColumns = layoutModel.PivotGroupedColumns;
486
498
  }
@@ -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
  }
@@ -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
  };
@@ -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
  };
@@ -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,
@@ -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',
@@ -33,29 +33,31 @@ const LayoutViewPanelComponent = (props) => {
33
33
  const entityAccessLevel = AdaptableHelper.getAccessLevelForObject(layoutEntity, accessLevel);
34
34
  const elementType = viewType === 'Toolbar' ? 'DashboardToolbar' : 'ToolPanel';
35
35
  const layoutSelectStyle = elementType === 'ToolPanel' ? { minWidth: '100%' } : {};
36
+ const toLayoutSelectItems = (layouts) => layouts.map((layout) => ({
37
+ label: layout.Name,
38
+ value: layout.Name,
39
+ }));
36
40
  const tableLayoutsArray = Layouts.filter((layout) => !isPivotLayout(layout));
37
41
  const pivotLayoutsArray = Layouts.filter((layout) => isPivotLayout(layout));
38
- const layoutGroups = [
39
- tableLayoutsArray.length > 0
40
- ? {
41
- label: 'Table Layouts',
42
- items: tableLayoutsArray.map((layout) => ({
43
- label: layout.Name,
44
- value: layout.Name,
45
- })),
46
- }
47
- : null,
48
- pivotLayoutsArray.length > 0
49
- ? {
50
- label: 'Pivot Layouts',
51
- items: pivotLayoutsArray.map((layout) => ({
52
- label: layout.Name,
53
- value: layout.Name,
54
- })),
55
- }
56
- : null,
57
- ].filter(Boolean);
58
- return (_jsxs(Flex, { flexDirection: "row", className: `ab-${elementType}__Layout__wrap twa:gap-0.5`, flexWrap: viewType === 'ToolPanel' ? 'wrap' : 'nowrap', children: [_jsx(Flex, { style: layoutSelectStyle, className: "twa:flex-1", children: _jsx(SingleSelect, { groups: layoutGroups, showItemTooltip: true, disabled: isErrorLayout, className: `twa:w-full twa:min-w-30 ab-${elementType}__Layout__select`, ariaLabel: 'Select Layout', value: layoutEntity ? layoutEntity.Name : null, onValueChange: (layout) => onSelectLayout(layout) }) }), _jsxs(Flex, { flexDirection: "row", className: join(accessLevel === GeneralConstants.ACCESS_LEVEL_READ_ONLY
42
+ const showLayoutTypeHeadings = tableLayoutsArray.length > 0 && pivotLayoutsArray.length > 0;
43
+ const layoutSelectCommonProps = {
44
+ showItemTooltip: true,
45
+ disabled: isErrorLayout,
46
+ className: `twa:w-full twa:min-w-30 ab-${elementType}__Layout__select`,
47
+ ariaLabel: 'Select Layout',
48
+ value: layoutEntity ? layoutEntity.Name : null,
49
+ onValueChange: (layout) => onSelectLayout(layout),
50
+ };
51
+ return (_jsxs(Flex, { flexDirection: "row", className: `ab-${elementType}__Layout__wrap twa:gap-0.5`, flexWrap: viewType === 'ToolPanel' ? 'wrap' : 'nowrap', children: [_jsx(Flex, { style: layoutSelectStyle, className: "twa:flex-1", children: showLayoutTypeHeadings ? (_jsx(SingleSelect, { ...layoutSelectCommonProps, groups: [
52
+ {
53
+ label: 'Table Layouts',
54
+ items: toLayoutSelectItems(tableLayoutsArray),
55
+ },
56
+ {
57
+ label: 'Pivot Layouts',
58
+ items: toLayoutSelectItems(pivotLayoutsArray),
59
+ },
60
+ ] })) : (_jsx(SingleSelect, { ...layoutSelectCommonProps, items: toLayoutSelectItems(Layouts) })) }), _jsxs(Flex, { flexDirection: "row", className: join(accessLevel === GeneralConstants.ACCESS_LEVEL_READ_ONLY
59
61
  ? GeneralConstants.READ_ONLY_STYLE
60
62
  : '', `ab-${elementType}__Layout__wrap`), children: [_jsx(ButtonEdit, { disabled: isErrorLayout, onClick: () => api.layoutApi.showLayoutEditor(layoutEntity.Name), tooltip: LAYOUT_EDIT_TOOLTIP, className: `ab-${elementType}__Layout__edit`, accessLevel: entityAccessLevel }), _jsx(ButtonClone, { disabled: isErrorLayout, onClick: () => api.layoutApi.showLayoutEditor(layoutEntity.Name, isPivotLayout(layoutEntity) ? 'pivot' : 'table', 'Clone'), tooltip: LAYOUT_CLONE_TOOLTIP, className: `ab-${elementType}__Layout__clone`, tone: "neutral", variant: "text", children: null, accessLevel: cloneAccessLevel }), _jsx(NewDropdownButton, { variant: "text", tooltip: LAYOUT_NEW_TABLE_OR_PIVOT_TOOLTIP, "data-name": "new", items: [
61
63
  {
@@ -1,8 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Provider } from 'react-redux';
3
3
  import AdaptableContext from './AdaptableContext';
4
- import { WithAdaptableComputedCSSVars } from './AdaptableComputedCSSVarsContext';
5
- import { TooltipProvider } from '../components/ui/tooltip';
4
+ import { TooltipProvider } from "../components/ui/tooltip";
6
5
  export const renderWithAdaptableContext = (children, adaptable) => {
7
- return (_jsx(TooltipProvider, { delay: 300, children: _jsx(Provider, { store: adaptable.adaptableStore.TheStore, children: _jsx(WithAdaptableComputedCSSVars, { children: _jsx(AdaptableContext.Provider, { value: adaptable, children: children }) }) }) }));
6
+ return (_jsx(TooltipProvider, { delay: 300, children: _jsx(Provider, { store: adaptable.adaptableStore.TheStore, children: _jsx(AdaptableContext.Provider, { value: adaptable, children: children }) }) }));
8
7
  };
@@ -97,7 +97,6 @@ export declare class AdaptableAgGrid implements IAdaptable {
97
97
  private LicenseService;
98
98
  private ChartingService;
99
99
  private rowListeners;
100
- private throttleFilterOnDataChange;
101
100
  private debouncedSetSelectedRows;
102
101
  private debouncedSetSelectedCells;
103
102
  private agGridListenerKeydown;
@@ -1,4 +1,3 @@
1
- import throttle from '../Utilities/utils/throttle';
2
1
  import debounce from '../Utilities/utils/debounce';
3
2
  import { createGrid, LocalEventService, } from 'ag-grid-enterprise';
4
3
  import { AdaptableLogger } from './AdaptableLogger';
@@ -21,6 +20,7 @@ import { ThemeService } from '../Utilities/Services/ThemeService';
21
20
  import { ValidationService } from '../Utilities/Services/ValidationService';
22
21
  import { ModuleService } from '../Utilities/Services/ModuleService';
23
22
  import { CalculatedColumnExpressionService } from '../Utilities/Services/CalculatedColumnExpressionService';
23
+ import { expandCellDataChangedInfosWithCalculatedColumns } from '../Utilities/Services/CalculatedColumnSyntheticChange';
24
24
  import { QueryLanguageService } from '../Utilities/Services/QueryLanguageService';
25
25
  import { AlertService } from '../Utilities/Services/AlertService';
26
26
  import { TeamSharingService } from '../Utilities/Services/TeamSharingService';
@@ -83,7 +83,6 @@ import { computeParameterizedAggregation, getParameterizedAggregationDefinitions
83
83
  import { getParameterizedAggForColumn } from '../Aggregation/parameterizedAggregationHelpers';
84
84
  import { getParameterizedAggregationHeaderParenthesisValue } from '../Aggregation/parameterizedAggregationHeader';
85
85
  import { RowFormService } from '../Utilities/Services/RowFormService';
86
- import { FilterOnDataChangeOptions } from '../AdaptableState/Common/Enums';
87
86
  import { ADAPTABLE_PUBLISH_TIMESTAMP } from '../EnvVars';
88
87
  import { AdaptableUpgradeHelper } from '../migration/AdaptableUpgradeHelper';
89
88
  import { ensureLoadingScreenPortalElement } from '../components/Modal';
@@ -204,7 +203,6 @@ export class AdaptableAgGrid {
204
203
  LicenseService;
205
204
  ChartingService;
206
205
  rowListeners;
207
- throttleFilterOnDataChange;
208
206
  debouncedSetSelectedRows;
209
207
  debouncedSetSelectedCells;
210
208
  agGridListenerKeydown;
@@ -1699,12 +1697,6 @@ export class AdaptableAgGrid {
1699
1697
  }), true);
1700
1698
  gridContainerElement.addEventListener('mouseleave', (this.agGridListenerMouseLeave = (event) => this._emit('MouseLeave', event)));
1701
1699
  }
1702
- this.throttleFilterOnDataChange = throttle(
1703
- // the extra function is to make sure we have a reference to ag-grid-api
1704
- () => this.agGridAdapter.getAgGridApi()?.onFilterChanged(), this.adaptableOptions.filterOptions.filterActionOnDataChange.throttleDelay, {
1705
- trailing: true,
1706
- leading: false,
1707
- });
1708
1700
  /**
1709
1701
  * Use Case: User has started inline editing but its disabled in Row Form Options
1710
1702
  * Action: Stop editing
@@ -3813,7 +3805,6 @@ export class AdaptableAgGrid {
3813
3805
  this.listenerCellSelectionChanged = null;
3814
3806
  this.listenerGlobalSetRowSelection = null;
3815
3807
  this.listenerSortChanged = null;
3816
- this.throttleFilterOnDataChange = null;
3817
3808
  const liveGridOptions = this.agGridAdapter.DANGER_getLiveGridOptions();
3818
3809
  if (liveGridOptions) {
3819
3810
  this.agGridOptionsService.revertGridOptionsPropertiesToUserValue(liveGridOptions, [
@@ -4133,6 +4124,7 @@ export class AdaptableAgGrid {
4133
4124
  * There are a few things we need to do AFTER we edit a cell and it makes sense to put them in one place
4134
4125
  */
4135
4126
  performPostEditChecks(rowNode, cellDataChangedInfos) {
4127
+ cellDataChangedInfos = expandCellDataChangedInfosWithCalculatedColumns(this.api, cellDataChangedInfos);
4136
4128
  cellDataChangedInfos.forEach((cellDataChangedInfo) => {
4137
4129
  // if a Cell Data Change is undone, log to the Console
4138
4130
  if (cellDataChangedInfo.trigger === 'undo') {
@@ -4290,14 +4282,7 @@ export class AdaptableAgGrid {
4290
4282
  }
4291
4283
  }
4292
4284
  filterOnDataChange() {
4293
- if (this.adaptableOptions.filterOptions.filterActionOnDataChange.applyFilter ==
4294
- FilterOnDataChangeOptions.Always) {
4295
- this.agGridAdapter.getAgGridApi()?.onFilterChanged();
4296
- }
4297
- else if (this.adaptableOptions.filterOptions.filterActionOnDataChange.applyFilter ==
4298
- FilterOnDataChangeOptions.Throttle) {
4299
- this.throttleFilterOnDataChange();
4300
- }
4285
+ this.agGridAdapter.getAgGridApi()?.onFilterChanged();
4301
4286
  }
4302
4287
  refreshLayout() {
4303
4288
  const columnDefs = this.agGridAdapter.getColumnDefinitionsInclSpecialColumns();
@@ -951,10 +951,7 @@ export class AgGridColumnAdapter {
951
951
  // 1. evaluate EditOptions.isCellEditable if provided
952
952
  if (this.adaptableApi.gridApi.internalApi.hasCellEditableAccordingToEditOptions()) {
953
953
  const gridCell = this.adaptableApi.gridApi.getGridCellFromRowNode(params.node, params.column.getColId());
954
- const editOptionsEditability = this.adaptableApi.gridApi.internalApi.isCellEditableAccordingToEditOptions(gridCell, getOriginalColDefEditable());
955
- if (editOptionsEditability) {
956
- return editOptionsEditability;
957
- }
954
+ return this.adaptableApi.gridApi.internalApi.isCellEditableAccordingToEditOptions(gridCell, getOriginalColDefEditable());
958
955
  }
959
956
  // 2. otherwise, fallback to colDef.editable
960
957
  return getOriginalColDefEditable();