Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -21,8 +21,6 @@ import type { ColumnViewTemplate } from '../views/types';
import { CLASSES } from './const';

const HEADERS_CLASS = 'headers';
const NOWRAP_CLASS = 'nowrap';
const COLUMN_LINES_CLASS = 'dx-column-lines';
const CONTEXT_MENU_SORT_ASC_ICON = 'context-menu-sort-asc';
const CONTEXT_MENU_SORT_DESC_ICON = 'context-menu-sort-desc';
const CONTEXT_MENU_SORT_NONE_ICON = 'context-menu-sort-none';
Expand Down Expand Up @@ -271,7 +269,7 @@ export class ColumnHeadersView extends ColumnContextMenuMixin(ColumnsView) {
// @ts-expect-error
const $row = super._createRow.apply(this, arguments);

$row.toggleClass(COLUMN_LINES_CLASS, this.option('showColumnLines'));
$row.toggleClass(VIEW_CLASSES.columnLines, this.option('showColumnLines'));

if (row.rowType === 'header') {
$row.addClass(CLASSES.headerRow);
Expand Down Expand Up @@ -322,7 +320,7 @@ export class ColumnHeadersView extends ColumnContextMenuMixin(ColumnsView) {

$container
.addClass(this.addWidgetPrefix(HEADERS_CLASS))
.toggleClass(this.addWidgetPrefix(NOWRAP_CLASS), !this.option('wordWrapEnabled'));
.toggleClass(this.addWidgetPrefix(VIEW_CLASSES.noWrap), !this.option('wordWrapEnabled'));

this.setAria('role', 'presentation', $container);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const CLASSES = {
headerPanel: 'header-panel',
toolbarButton: 'toolbar-button',
};

export const TOOLBAR_ARIA_LABEL = '-ariaToolbar';

export const DEFAULT_TOOLBAR_ITEM_NAMES = [
'addRowButton',
'applyFilterButton',
'columnChooserButton',
'exportButton',
'groupPanel',
'revertButton',
'saveButton',
'searchPanel',
];
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
/* eslint-disable max-classes-per-file */
import messageLocalization from '@js/common/core/localization/message';
import type { dxElementWrapper } from '@js/core/renderer';
import $ from '@js/core/renderer';
import { getPathParts } from '@js/core/utils/data';
import type { DeferredObj } from '@js/core/utils/deferred';
import { Deferred } from '@js/core/utils/deferred';
import { isDefined } from '@js/core/utils/type';
import type { ToolbarItem as DataGridToolbarItem } from '@js/ui/data_grid';
import type { Properties as ToolbarProperties } from '@js/ui/toolbar';
import Toolbar from '@js/ui/toolbar';
import type { EditingController } from '@ts/grids/grid_core/editing/m_editing';
import type { HeaderFilterController } from '@ts/grids/grid_core/header_filter/m_header_filter';
import type { DefaultToolbarItem, ToolbarItem } from '@ts/grids/new/grid_core/toolbar/types';
import type { ToolbarItem } from '@ts/grids/new/grid_core/toolbar/types';
import { normalizeToolbarItems } from '@ts/grids/new/grid_core/toolbar/utils';

import type { ModuleType } from '../types';
import type { Column } from '../columns_controller/types';
import type { InternalGridOptions, ModuleType, OptionChanged } from '../types';
import { ColumnsView } from '../views/columns_view';
import type { ResizingController } from '../views/grid_view';

const HEADER_PANEL_CLASS = 'header-panel';
const TOOLBAR_BUTTON_CLASS = 'toolbar-button';

const TOOLBAR_ARIA_LABEL = '-ariaToolbar';

const DEFAULT_TOOLBAR_ITEM_NAMES = ['addRowButton', 'applyFilterButton', 'columnChooserButton', 'exportButton', 'groupPanel', 'revertButton', 'saveButton', 'searchPanel'];
import type { ContextMenuItemsOptions } from '../views/types';
import { CLASSES, DEFAULT_TOOLBAR_ITEM_NAMES, TOOLBAR_ARIA_LABEL } from './const';

export class HeaderPanel extends ColumnsView {
private _toolbar?: Toolbar;
private _toolbar?: Toolbar<ToolbarItem>;

private _toolbarOptions?: ToolbarProperties;

Expand Down Expand Up @@ -85,12 +83,12 @@ export class HeaderPanel extends ColumnsView {
(ui) => (typeof ui === 'string' ? ui === name : ui?.name === name),
);

if (!userItem) {
if (!registeredItem || !userItem) {
return registeredItem;
}

return normalizeToolbarItems(
[registeredItem] as DefaultToolbarItem[],
[registeredItem],
[userItem],
DEFAULT_TOOLBAR_ITEM_NAMES,
)[0];
Expand Down Expand Up @@ -118,21 +116,21 @@ export class HeaderPanel extends ColumnsView {
return [...items].sort((a, b) => (a.sortIndex ?? 0) - (b.sortIndex ?? 0));
}

private _getButtonContainer() {
return $('<div>').addClass(this.addWidgetPrefix(TOOLBAR_BUTTON_CLASS));
private _getButtonContainer(): dxElementWrapper {
return $('<div>').addClass(this.addWidgetPrefix(CLASSES.toolbarButton));
}

public getToolbarButtonClass(specificClass?: string): string {
const secondClass = specificClass ? ` ${specificClass}` : '';

return this.addWidgetPrefix(TOOLBAR_BUTTON_CLASS) + secondClass;
return this.addWidgetPrefix(CLASSES.toolbarButton) + secondClass;
}

private _getToolbarOptions(): ToolbarProperties<DefaultToolbarItem | ToolbarItem> {
private _getToolbarOptions(): ToolbarProperties<ToolbarItem> {
const { toolbar: userToolbarOptions } = this.option();
const sortedToolbarItems: ToolbarItem[] = this.sortToolbarItems(this._getToolbarItems());

const options: { toolbarOptions: ToolbarProperties<DefaultToolbarItem | ToolbarItem> } = {
const options: { toolbarOptions: ToolbarProperties<ToolbarItem> } = {
toolbarOptions: {
items: sortedToolbarItems,
visible: userToolbarOptions?.visible,
Expand All @@ -149,7 +147,7 @@ export class HeaderPanel extends ColumnsView {

const userItems = userToolbarOptions?.items;
options.toolbarOptions.items = normalizeToolbarItems(
sortedToolbarItems as DefaultToolbarItem[],
sortedToolbarItems,
userItems,
DEFAULT_TOOLBAR_ITEM_NAMES,
);
Expand All @@ -168,43 +166,46 @@ export class HeaderPanel extends ColumnsView {
if (!this._toolbar) {
const $headerPanel = this.element();
// @ts-expect-error the view is rendered here
$headerPanel.addClass(this.addWidgetPrefix(HEADER_PANEL_CLASS));
$headerPanel.addClass(this.addWidgetPrefix(CLASSES.headerPanel));
const label = messageLocalization.format(this.component.NAME + TOOLBAR_ARIA_LABEL);
// @ts-expect-error the view is rendered here
const $toolbar = $('<div>').appendTo($headerPanel);

this.setAria('label', label, $toolbar);
this._toolbar = this._createComponent($toolbar, Toolbar, this._toolbarOptions);
} else {
this._toolbar.option(this._toolbarOptions!);
// @ts-expect-error render() sets _toolbarOptions first
this._toolbar.option(this._toolbarOptions);
}

return Deferred<unknown>().resolve();
}

protected _columnOptionChanged() {
protected _columnOptionChanged(): void {

}

protected _handleDataChanged() {
protected _handleDataChanged(): void {
if (this._requireReady) {
this.render();
}
}

private _isDisabledDefinedByUser(name: string): boolean {
const userItems = (this.option('toolbar') as any)?.items;
const userItem = userItems?.find((item) => item?.name === name);
const userItems = this.option('toolbar')?.items;
const userItem = userItems?.find(
(item): item is DataGridToolbarItem => typeof item !== 'string' && item?.name === name,
);

return isDefined(userItem?.disabled);
}

public render() {
public render($parent?: dxElementWrapper | null, options?: unknown): void {
this._toolbarOptions = this._getToolbarOptions();
super.render.apply(this, arguments as any);
super.render($parent, options);
}

public setToolbarItemDisabled(name, disabled: boolean): void {
public setToolbarItemDisabled(name: string, disabled: boolean): void {
const toolbar = this._toolbar;
const isDefinedByUser = this._isDisabledDefinedByUser(name);

Expand All @@ -219,7 +220,7 @@ export class HeaderPanel extends ColumnsView {
return;
}

const item: any = toolbar.option(`items[${itemIndex}]`);
const item = items[itemIndex];

toolbar.option(`items[${itemIndex}].disabled`, disabled);

Expand All @@ -228,91 +229,92 @@ export class HeaderPanel extends ColumnsView {
}
}

public updateToolbarDimensions() {
(this._toolbar as any)?.updateDimensions();
public updateToolbarDimensions(): void {
// @ts-expect-error updateDimensions is an internal method not in the public dxToolbar API
this._toolbar?.updateDimensions();
}

private getHeaderPanel() {
private getHeaderPanel(): dxElementWrapper | undefined {
return this.element();
}

private getHeight() {
private getHeight(): number {
return this.getElementHeight();
}

public optionChanged(args) {
public optionChanged(args: OptionChanged): void {
if (args.name === 'onToolbarPreparing') {
this._invalidate();
args.handled = true;
}

if (args.name === 'toolbar') {
const parts = getPathParts(args.fullName);
const optionName = args.fullName.replace(/^toolbar\./, '');
const isItemsOption = parts[1] === 'items';

if (parts.length === 1 || parts[1] === 'visible') {
// `toolbar`, `toolbar.visible` case
const isToolbarReplaced = parts.length === 1;
const isVisibleChanged = parts[1] === 'visible';
const areItemsReplaced = isItemsOption && parts.length === 2;
const isItemReplaced = isItemsOption && parts.length === 3;

if (isToolbarReplaced || isVisibleChanged || areItemsReplaced) {
this._invalidate();
} else if (parts[1] === 'items') {
if (parts.length === 2) {
// `toolbar.items` case
this._invalidate();
} else if (parts.length === 3) {
// `toolbar.items[i]` case
const normalizedItem = normalizeToolbarItems(
this._getToolbarItems() as DefaultToolbarItem[],
[args.value],
DEFAULT_TOOLBAR_ITEM_NAMES,
)[0];
this._toolbar?.option(optionName, normalizedItem);
} else if (parts.length >= 4) {
// `toolbar.items[i].prop` case
this._toolbar?.option(optionName, args.value);
}
} else if (isItemReplaced) {
const normalizedItem = normalizeToolbarItems(
this._getToolbarItems(),
// @ts-expect-error OptionChanged has no paths for toolbar items by index
[args.value],
DEFAULT_TOOLBAR_ITEM_NAMES,
)[0];
this._toolbar?.option(optionName, normalizedItem);
} else {
// `toolbar.disabled` case
this._toolbar?.option(optionName, args.value);
}
args.handled = true;
}

super.optionChanged(args);
}

/**
* @extended: column_chooser, editing
*/
public isVisible() {
return !!(this._toolbarOptions && this._toolbarOptions.visible);
public isVisible(): boolean {
return !!this._toolbarOptions?.visible;
}

/**
* @extended: DataGrid's grouping
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public allowDragging(column): boolean {
public allowDragging(column: Column): boolean {
return false;
}

public hasGroupedColumns(): any {}
public hasGroupedColumns(): boolean | undefined {
return undefined;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public getContextMenuItems(options) {
public getContextMenuItems(options: ContextMenuItemsOptions): unknown {
return undefined;
}
}

const resizing = (Base: ModuleType<ResizingController>) => class HeaderPanelResizingExtender extends Base {
protected _updateDimensionsCore() {
// @ts-expect-error
super._updateDimensionsCore.apply(this, arguments);
const resizing = (
Base: ModuleType<ResizingController>,
): ModuleType<ResizingController> => class HeaderPanelResizingExtender extends Base {
protected _updateDimensionsCore(): void {
super._updateDimensionsCore();

this.getView('headerPanel').updateToolbarDimensions();
}
};

export const headerPanelModule = {
defaultOptions() {
return {
};
defaultOptions(): InternalGridOptions {
return {};
},
views: {
headerPanel: HeaderPanel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ export const ATTRIBUTES = {
dragCell: 'dx-drag-cell',
};

export const ROWS_VIEW_CLASS = 'rowsview';
export const EDIT_FORM_CLASS = 'edit-form';
export const GROUP_FOOTER_CLASS = 'group-footer';
export const EDIT_FORM_ITEM_CLASS = 'edit-form-item';
export const FREESPACE_ROW_CLASS = 'dx-freespace-row';
export const VIRTUAL_ROW_CLASS = 'dx-virtual-row';
export const MASTER_DETAIL_CELL_CLASS = 'dx-master-detail-cell';
export const EDITOR_CELL_CLASS = 'dx-editor-cell';
Expand Down
Loading
Loading