diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/columns_controller.ts b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/columns_controller.ts index 6f6876098824..1f15857289af 100644 --- a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/columns_controller.ts +++ b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/columns_controller.ts @@ -1,3 +1,5 @@ +import { equalByValue } from '@js/core/utils/common'; +import { getPathParts } from '@js/core/utils/data'; import type { ReadonlySignal, Signal } from '@ts/core/state_manager/index'; import { computed, effect, signal } from '@ts/core/state_manager/index'; import type { DataObject } from '@ts/grids/new/grid_core/data_controller/types'; @@ -6,11 +8,14 @@ import { isColumnFilterable, mergeColumnHeaderFilterOptions } from '@ts/grids/ne import type { OptionWithChanges } from '@ts/grids/new/grid_core/options_controller/types'; import { OptionsController } from '../options_controller/options_controller'; +import { getTreeNodeByPath } from '../utils/tree/index'; import { updateColumnSettings } from './columns_settings/index'; +import { IGNORE_COLUMN_OPTION_NAMES } from './const'; import type { ColumnProperties, ColumnSettings, PreNormalizedColumn } from './options'; import type { Column, ColumnsConfigurationFromData, VisibleColumn } from './types'; import { columnOptionUpdate, + getColumnByIndexOrName, getColumnIndexByName, getColumnOptionsFromDataItem, normalizeColumns, @@ -121,14 +126,16 @@ export class ColumnsController { } public columnOption( - { name }: Column, + column: Column, // TODO: Fix type -> option may be path with dots in runtime // E.g: 'columnOption('A', 'headerFilter.search.enabled', true) option: TProp, value: ColumnSettings[TProp], ): void { + const { name } = column; const settings = this.columnsSettings.peek(); const columnIdx = getColumnIndexByName(settings, name); + const prevValue = getTreeNodeByPath(column, getPathParts(option)); this.columnsSettings.value = columnOptionUpdate( settings, @@ -136,12 +143,43 @@ export class ColumnsController { option, value, ); + + this.fireOptionChanged(columnIdx, option, value, prevValue); } public updateColumns(func: (columns: PreNormalizedColumn[]) => PreNormalizedColumn[]): void { + const prevColumns = this.columns.peek(); + let newColumnSettings = func(this.columnsSettings.peek()); newColumnSettings = normalizeColumnsVisibleIndexes(newColumnSettings); this.columnsSettings.value = newColumnSettings; + + const newColumns = this.columns.peek(); + newColumns.forEach((newColumn, columnIdx) => { + const prevColumn = getColumnByIndexOrName(prevColumns, newColumn.name); + if (prevColumn) { + const options = new Set([...Object.keys(prevColumn), ...Object.keys(newColumn)]); + for (const option of options) { + if (!IGNORE_COLUMN_OPTION_NAMES[option]) { + const prevValue = prevColumn[option]; + const newValue = newColumn[option]; + this.fireOptionChanged(columnIdx, option, newValue, prevValue); + } + } + } + }); + } + + private fireOptionChanged( + columnIndex: number, + optionName: string, + newValue: unknown, + prevValue: unknown, + ): void { + if (!equalByValue(prevValue, newValue, { maxDepth: 5 })) { + const fullOptionPath = `columns[${columnIndex}].${optionName}`; + this.options.notifyColumnOptionChanged(fullOptionPath, newValue, prevValue); + } } public setColumnOptionsFromDataItem( diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/const.ts b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/const.ts new file mode 100644 index 000000000000..862389a7ea76 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/const.ts @@ -0,0 +1,3 @@ +export const IGNORE_COLUMN_OPTION_NAMES = { + selector: true, +}; diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/options_controller/options_controller_base.ts b/packages/devextreme/js/__internal/grids/new/grid_core/options_controller/options_controller_base.ts index 0b41813464a1..509b3943a06b 100644 --- a/packages/devextreme/js/__internal/grids/new/grid_core/options_controller/options_controller_base.ts +++ b/packages/devextreme/js/__internal/grids/new/grid_core/options_controller/options_controller_base.ts @@ -47,6 +47,8 @@ export class OptionsController< private isControlledMode = false; + private _skipProcessingColumnsChange: string | false = false; + private readonly internalOptions: Signal>; // @ts-expect-error Component type doesn't have fields from widget.ts @@ -76,6 +78,10 @@ export class OptionsController< private onOptionChangedHandler(optionChanges: ChangedOptionInfo): void { const { fullName } = optionChanges; + if (this._skipProcessingColumnsChange === fullName) { + return; + } + this.updateIsControlledMode(); this.updateInternalOptionsState(fullName, optionChanges); } @@ -221,4 +227,15 @@ export class OptionsController< ); }); } + + public notifyColumnOptionChanged( + fullOptionPath: string, + newValue: unknown, + prevValue: unknown, + ): void { + this._skipProcessingColumnsChange = fullOptionPath; + // @ts-expect-error + this.component._notifyOptionChanged(fullOptionPath, newValue, prevValue); + this._skipProcessingColumnsChange = false; + } }