Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ test('should update column options with filterType and values (regular selection
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql(undefined)
.expect(columnOptions.filterType).eql(undefined)
.expect(columnOptions.headerFilter.values).eql(['A_0', 'A_1']);

await t.click(cardView.element);
Expand Down Expand Up @@ -233,7 +233,7 @@ test('should update column options with filterType and values (selectAll case #0
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql('exclude')
.expect(columnOptions.filterType).eql('exclude')
.expect(columnOptions.headerFilter.values).eql(null);

await t.click(cardView.element);
Expand Down Expand Up @@ -277,7 +277,7 @@ test('should update column options with filterType and values (selectAll case #1
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql('exclude')
.expect(columnOptions.filterType).eql('exclude')
.expect(columnOptions.headerFilter.values).eql(['A_2', 'A_3']);

await t.click(cardView.element);
Expand Down Expand Up @@ -376,9 +376,9 @@ test('should apply filter from options (type: "include")', async (t) => {
{
dataField: 'A',
headerFilter: {
filterType: 'include',
values: ['A_0', 'A_1'],
},
filterType: 'include',
},
'B',
'C',
Expand Down Expand Up @@ -425,9 +425,9 @@ test('should apply filter from options (type: "exclude")', async (t) => {
{
dataField: 'A',
headerFilter: {
filterType: 'exclude',
values: ['A_2', 'A_3', 'A_4'],
},
filterType: 'exclude',
},
'B',
'C',
Expand Down Expand Up @@ -514,7 +514,7 @@ test('should not update column options if popup cancel btn clicked', async (t) =
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql(undefined)
.expect(columnOptions.filterType).eql(undefined)
.expect(columnOptions.headerFilter.values).eql(['A_4']);

await t.click(cardView.element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const clearRemoteOperations = () => ClientFunction(() => {
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql(undefined)
.expect(columnOptions.filterType).eql(undefined)
.expect(columnOptions.headerFilter.values).eql(['A_0', 'A_1']);

await t.click(cardView.element);
Expand Down Expand Up @@ -187,7 +187,7 @@ const clearRemoteOperations = () => ClientFunction(() => {
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql('exclude')
.expect(columnOptions.filterType).eql('exclude')
.expect(columnOptions.headerFilter.values).eql(null);

await t.click(cardView.element);
Expand Down Expand Up @@ -238,7 +238,7 @@ const clearRemoteOperations = () => ClientFunction(() => {
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql('exclude')
.expect(columnOptions.filterType).eql('exclude')
.expect(columnOptions.headerFilter.values).eql(['A_2', 'A_3']);

await t.click(cardView.element);
Expand Down Expand Up @@ -353,9 +353,9 @@ const clearRemoteOperations = () => ClientFunction(() => {
{
dataField: 'A',
headerFilter: {
filterType: 'include',
values: ['A_0', 'A_1'],
},
filterType: 'include',
},
'B',
'C',
Expand Down Expand Up @@ -409,9 +409,9 @@ const clearRemoteOperations = () => ClientFunction(() => {
{
dataField: 'A',
headerFilter: {
filterType: 'exclude',
values: ['A_2', 'A_3', 'A_4'],
},
filterType: 'exclude',
},
'B',
'C',
Expand Down Expand Up @@ -505,7 +505,7 @@ const clearRemoteOperations = () => ClientFunction(() => {
const columnOptions = await cardView.getColumnOption('A');

await t
.expect(columnOptions.headerFilter.filterType).eql(undefined)
.expect(columnOptions.filterType).eql(undefined)
.expect(columnOptions.headerFilter.values).eql(['A_4']);

await t.click(cardView.element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ export class Item extends Component<ItemProps> {
const Template = this.props.column.headerItemTemplate ?? this.props.template;
const cssClass = `${CLASSES.item} ${this.props.column.headerItemCssClass ?? ''} ${this.props.cssClass ?? ''}`;

const { headerFilter } = this.props.column;
const { headerFilter, filterType } = this.props.column;

const hasHeaderFilterValue = headerFilter?.filterType === 'exclude'
const hasHeaderFilterValue = filterType === 'exclude'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we revert change filterType -> headerFilter.filterType?
Maybe then remove change filterValue -> headerFilter.filterValue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under discussing with PMs.

|| !!headerFilter?.values?.length;
const headerFilterIconClass = [
CLASSES.headerFilter.iconEmpty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import type { SubsGets } from '@ts/core/reactive/index';
import { combined, computed } from '@ts/core/reactive/index';
import { ColumnsController } from '@ts/grids/new/grid_core/columns_controller/columns_controller';
import { View } from '@ts/grids/new/grid_core/core/view';
import { HeaderFilterController } from '@ts/grids/new/grid_core/filtering/header_filter/index';

import type { Column } from '../../grid_core/columns_controller/types';
import { HeaderFilterViewController } from '../../grid_core/filtering/header_filter/view_controller';
import { SortingController } from '../../grid_core/sorting_controller/sorting_controller';
import { ContextMenuController } from '../context_menu/controller';
import { ContextMenuController } from '../context_menu/index';
import { OptionsController } from '../options_controller';
import type { HeaderPanelProps } from './header_panel';
import { HeaderPanel } from './header_panel';
Expand All @@ -16,19 +16,19 @@ export class HeaderPanelView extends View<HeaderPanelProps> {
protected component = HeaderPanel;

public static dependencies = [
ContextMenuController,
SortingController,
ColumnsController,
OptionsController,
HeaderFilterController,
ContextMenuController,
HeaderFilterViewController,
] as const;

constructor(
private readonly contextMenuController: ContextMenuController,
private readonly sortingController: SortingController,
private readonly columnsController: ColumnsController,
private readonly options: OptionsController,
private readonly headerFilterController: HeaderFilterController,
private readonly contextMenuController: ContextMenuController,
private readonly headerFilterViewController: HeaderFilterViewController,
) {
super();
}
Expand Down Expand Up @@ -85,7 +85,7 @@ export class HeaderPanelView extends View<HeaderPanelProps> {
column: Column,
onFilterCloseCallback?: () => void,
): void {
this.headerFilterController.openPopup(element, column, onFilterCloseCallback);
this.headerFilterViewController.openPopup(element, column, onFilterCloseCallback);
}

private showContextMenu(e: MouseEvent, column?: Column, columnIndex?: number): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
computed, interruptableComputed,
} from '@ts/core/reactive/index';
import type { HeaderFilterRootOptions } from '@ts/grids/new/grid_core/filtering/header_filter/index';
import headerFilterUtils from '@ts/grids/new/grid_core/filtering/header_filter/utils';
import { mergeColumnHeaderFilterOptions } from '@ts/grids/new/grid_core/filtering/header_filter/utils';

import { OptionsController } from '../options_controller/options_controller';
import type { ColumnProperties, ColumnSettings, PreNormalizedColumn } from './options';
Expand Down Expand Up @@ -50,8 +50,7 @@ export class ColumnsController {
) => normalizeColumns(
columnsSettings ?? [],
(template) => (template ? this.options.normalizeTemplate(template) : undefined),
).map((column) => headerFilterUtils
.mergeColumnHeaderFilterOptions(column, headerFilterRootOptions)),
).map((column) => mergeColumnHeaderFilterOptions(column, headerFilterRootOptions)),
[
this.columnsSettings,
this.headerFilterConfiguration,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Format, SortOrder } from '@js/common';
import type { ColumnBase } from '@js/common/grids';
import type { ColumnBase, FilterType } from '@js/common/grids';
import type { HeaderFilterColumnOptions } from '@ts/grids/new/grid_core/filtering/header_filter/index';
import type { ComponentType } from 'inferno';

Expand Down Expand Up @@ -64,6 +64,8 @@ export type Column = Pick<Required<ColumnBase>, InheritedColumnProps> & {

// header filter options for specific column.
headerFilter?: HeaderFilterColumnOptions;

filterType?: FilterType;
};

export type VisibleColumn = Column & { visible: true };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { createPromise } from '@ts/core/utils/promise';

import { FilterController } from '../filtering/filter_controller';
import { OptionsController } from '../options_controller/options_controller';
import { SearchController } from '../search/index';
import { SortingController } from '../sorting_controller/sorting_controller';
import { StoreLoadAdapter } from './store_load_adapter/index';
import type { DataObject, Key } from './types';
Expand Down Expand Up @@ -84,15 +83,15 @@ export class DataController {
);

public static dependencies = [
OptionsController, SortingController,
FilterController, SearchController,
OptionsController,
SortingController,
FilterController,
] as const;

constructor(
private readonly options: OptionsController,
private readonly sortingController: SortingController,
private readonly filterController: FilterController,
private readonly searchController: SearchController,
) {
effect(
(dataSource) => {
Expand Down
7 changes: 7 additions & 0 deletions packages/devextreme/js/__internal/grids/new/grid_core/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import * as ColumnsControllerModule from './columns_controller/index';
import * as DataControllerModule from './data_controller/index';
import { ErrorController } from './error_controller/error_controller';
import { FilterPanelView } from './filtering/filter_panel/view';
import { ClearFilterVisitor } from './filtering/filter_visitors/clear_filter_visitor';
import { GetAppliedFilterVisitor } from './filtering/filter_visitors/get_applied_filters_visitor';
import {
HeaderFilterController,
HeaderFilterPopupView,
} from './filtering/header_filter/index';
import { HeaderFilterViewController } from './filtering/header_filter/view_controller';
import * as FilterControllerModule from './filtering/index';
import { ItemsController } from './items_controller/items_controller';
import { PagerView } from './pager/view';
Expand Down Expand Up @@ -42,4 +45,8 @@ export function register(diContext: DIContext): void {
diContext.register(HeaderFilterPopupView);
diContext.register(ErrorController);
diContext.register(SearchView);
diContext.register(HeaderFilterViewController);

diContext.register(ClearFilterVisitor);
diContext.register(GetAppliedFilterVisitor);
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,67 @@
/* eslint-disable spellcheck/spell-checker */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { computed } from '@ts/core/reactive/index';

import type { SubsGetsUpd } from '@ts/core/reactive/index';
import { computed, state } from '@ts/core/reactive/index';
import { anyOf, noneOf } from '@ts/grids/grid_core/filter/m_filter_custom_operations';
import gridCoreUtils from '@ts/grids/grid_core/m_utils';

import { ColumnsController } from '../columns_controller/index';
import { OptionsController } from '../options_controller/options_controller';
import { SearchController } from '../search/index';
import type { AppliedFilters } from './types';
import { getAppliedFilterExpressions } from './utils';

export class FilterController {
public readonly filter = this.options.twoWay('filterValue');
public readonly filterSyncEnabled = this.options.oneWay('filterSyncEnabled');

private readonly filterBuilderCustomOperations = this.options.oneWay('filterBuilder.customOperations');

public readonly appliedFilters: SubsGetsUpd<AppliedFilters> = state({});

public readonly filterEnabled = this.options.twoWay('filterPanel.filterEnabled');
public static dependencies = [
OptionsController,
ColumnsController,
] as const;

public readonly customOperations = computed(
(fbCustomOperations) => [
anyOf(null),
noneOf(null),
].concat(fbCustomOperations)
.filter((o) => o),
[this.filterBuilderCustomOperations],
);

public static dependencies = [OptionsController, SearchController] as const;
private readonly appliedFilterExpressions = computed(
(
appliedFilters,
columns,
customOperations,
) => getAppliedFilterExpressions(appliedFilters, columns, customOperations),
[
this.appliedFilters,
this.columnsController.visibleColumns,
this.customOperations,
],
);

public readonly displayFilter = computed(
(filterEnabled, filter, searchFilter) => {
if (!filterEnabled) {
return searchFilter;
}
return gridCoreUtils.combineFilters([filter, searchFilter]);
},
(filters) => gridCoreUtils.combineFilters(filters),
[
this.filterEnabled,
this.filter,
this.searchController.searchFilter,
this.appliedFilterExpressions,
],
);

public clearFilterContext: unknown = null;

constructor(
private readonly options: OptionsController,
private readonly searchController: SearchController,
private readonly columnsController: ColumnsController,
) { }

public clearFilterCallback = (): void => {};

public clearFilter(): void {
this.filter.update(null);
this.clearFilterCallback.call(this.clearFilterContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable spellcheck/spell-checker */
import { OptionsController } from '../../options_controller/options_controller';
import { SearchController } from '../../search/index';
import { FilterController } from '../filter_controller';
import { HeaderFilterController } from '../header_filter/index';

export class ClearFilterVisitor {
public static dependencies = [
OptionsController,
SearchController,
HeaderFilterController,
FilterController,
] as const;

private readonly filter = this.options.twoWay('filterValue');

public readonly filterSyncEnabled = this.options.oneWay('filterSyncEnabled');

constructor(
private readonly options: OptionsController,
private readonly searchController: SearchController,
private readonly headerFilterController: HeaderFilterController,
private readonly filterController: FilterController,
) {
this.filterController.clearFilterCallback = this.clearFilters;
this.filterController.clearFilterContext = this;
}

public clearFilters(): void {
this.searchController.searchTextOption.update('');
this.filter.update(null);
if (!this.filterSyncEnabled.unreactive_get()) {
this.headerFilterController.clearHeaderFilters();
}
}
}
Loading
Loading