diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/column_sortable.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/column_sortable.tsx new file mode 100644 index 00000000000..aa5c4f412e3 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/column_sortable.tsx @@ -0,0 +1,53 @@ +import type { InfernoNode } from 'inferno'; +import { Component } from 'inferno'; + +import type { Column } from '../../grid_core/columns_controller/types'; +import type { Props as SortableProps } from '../../grid_core/inferno_wrappers/sortable'; +import { Sortable } from '../../grid_core/inferno_wrappers/sortable'; + +export interface Props extends SortableProps { + source: string; + + visibleColumns: Column[]; + + allowColumnReordering: boolean; +} + +export class ColumnSortable extends Component { + private readonly onDragStart = (e): void => { + const column = this.props.visibleColumns[e.fromIndex]; + + if (!column.allowReordering) { + e.cancel = true; + return; + } + + e.itemData = { + columnName: column.name, + source: this.props.source, + }; + }; + + render(): InfernoNode { + if (!this.props.allowColumnReordering) { + return this.props.children; + } + + const { + source, + visibleColumns, + ...restProps + } = this.props; + + return ( + + {this.props.children} + + ); + } +} diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/drop_down_button.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/drop_down_button.tsx index a2a3f1c2e45..0bc339ecb43 100644 --- a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/drop_down_button.tsx +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/drop_down_button.tsx @@ -4,7 +4,7 @@ import { Component, createRef } from 'inferno'; import type { Column } from '../../grid_core/columns_controller/types'; import { Button } from '../../grid_core/inferno_wrappers/button'; import { Popup } from '../../grid_core/inferno_wrappers/popup'; -import { Sortable } from '../../grid_core/inferno_wrappers/sortable'; +import { ColumnSortable } from './column_sortable'; import { Item } from './item'; const CLASSES = { @@ -21,6 +21,8 @@ export interface DropDownButtonProps { onRemove?: (name: string) => void; shownColumnCount: number; + + allowColumnReordering: boolean; } interface DropDownButtonState { @@ -74,23 +76,19 @@ export class DropDownButton extends Component - this.props.onReorder?.( e.itemData.columnName, - e.toIndex + this.props.shownColumnCount - +(e.itemData.source === 'main-header-panel'), + e.toIndex + this.props.shownColumnCount - +(e.itemData.source === 'header-panel-main'), )} onAdd={(e): void => this.props.onAdd?.( e.itemData.columnName, - e.toIndex + this.props.shownColumnCount - +(e.itemData.source === 'main-header-panel'), + e.toIndex + this.props.shownColumnCount - +(e.itemData.source === 'header-panel-main'), )} - onDragStart={(e): void => { - e.itemData = { - columnName: this.props.columns[e.fromIndex].name, - }; - }} - group='cardview' > {this.props.columns.map((column) => ( ))} - + ); } diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx index f592909f5b4..8f9c164eb30 100644 --- a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import type { Column } from '@ts/grids/new/grid_core/columns_controller/types'; -import type { RefObject } from 'inferno'; +import type { InfernoNode, RefObject } from 'inferno'; import { Component } from 'inferno'; -import { Sortable } from '../../grid_core/inferno_wrappers/sortable'; +import { ColumnSortable } from './column_sortable'; import { DropDownButton } from './drop_down_button'; import { Item } from './item'; @@ -23,6 +23,8 @@ export interface HeaderPanelProps { shownColumnCount: number; elementRef: RefObject; + + allowColumnReordering: boolean; } export class HeaderPanel extends Component { @@ -34,30 +36,39 @@ export class HeaderPanel extends Component { (_, index) => index >= this.props.shownColumnCount, ); - return ( -
- { + if (!this.props.allowColumnReordering) { + return content; + } + + return ( + this.props.onReorder?.(e.itemData.columnName, e.toIndex)} onAdd={(e): void => this.props.onAdd?.(e.itemData.columnName, e.toIndex)} - onDragStart={(e): void => { - e.itemData = { - columnName: visibleColumns[e.fromIndex].name, - source: 'main-header-panel', - }; - }} - group='cardview' > - {visibleColumns.map((column) => ( + {content} + + ); + }; + + return ( +
+ { + wrapSortable( + visibleColumns.map((column) => ( this.props.onRemove?.(column.name) } /> - ))} - + )), + ) + } {!!nonVisibleColumns.length && ( { onAdd={this.props.onAdd} onReorder={this.props.onReorder} shownColumnCount={this.props.shownColumnCount} + allowColumnReordering={this.props.allowColumnReordering} /> )}
diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx index db099b7feb6..299c3fe117b 100644 --- a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx @@ -7,15 +7,19 @@ import { ResizableHeaderPanel } from './resizable_header_panel'; export class HeaderPanelView extends View { public vdom = computed( - (columns) => ( + (columns, allowColumnReordering) => ( ), - [this.columnsController.visibleColumns], + [ + this.columnsController.visibleColumns, + this.columnsController.allowColumnReordering, + ], ); public static dependencies = [ColumnsController] as const; 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 d07aea8073a..c2713d044ed 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,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable spellcheck/spell-checker */ -import type { SubsGets, SubsGetsUpd } from '@ts/core/reactive/index'; +import type { Subscribable, SubsGets, SubsGetsUpd } from '@ts/core/reactive/index'; import { computed, iif, interruptableComputed } from '@ts/core/reactive/index'; import { DataController } from '../data_controller/index'; @@ -16,6 +16,8 @@ export class ColumnsController { public readonly nonVisibleColumns: SubsGets; + public readonly allowColumnReordering: Subscribable; + public static dependencies = [OptionsController, DataController] as const; constructor( @@ -58,6 +60,8 @@ export class ColumnsController { (columns) => columns.filter((column) => !column.visible), [this.columns], ); + + this.allowColumnReordering = this.options.oneWay('allowColumnReordering'); } public createDataRow(data: DataObject, columns: Column[]): DataRow { diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/options.ts b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/options.ts index 6c4fb246e2b..e8ef2688bb5 100644 --- a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/options.ts +++ b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/options.ts @@ -14,6 +14,7 @@ export const defaultColumnProperties = { }, alignment: 'left', visible: true, + allowReordering: true, } satisfies Partial; export const defaultColumnPropertiesByDataType: Record< @@ -42,8 +43,10 @@ Exclude export interface Options { columns?: ColumnProperties[]; + + allowColumnReordering?: boolean; } export const defaultOptions = { - + allowColumnReordering: false, } satisfies Options; diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/types.ts b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/types.ts index 83f1a7c29ed..814bcd4e0c7 100644 --- a/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/types.ts +++ b/packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/types.ts @@ -7,6 +7,7 @@ type InheritedColumnProps = | 'dataType' | 'visible' | 'visibleIndex' + | 'allowReordering' | 'caption'; export type Column = Pick, InheritedColumnProps> & { diff --git a/packages/devextreme/js/__internal/grids/new/grid_core/inferno_wrappers/sortable.tsx b/packages/devextreme/js/__internal/grids/new/grid_core/inferno_wrappers/sortable.tsx index bdd7f2480ce..3806d32afa2 100644 --- a/packages/devextreme/js/__internal/grids/new/grid_core/inferno_wrappers/sortable.tsx +++ b/packages/devextreme/js/__internal/grids/new/grid_core/inferno_wrappers/sortable.tsx @@ -4,7 +4,11 @@ import { type InfernoNode } from 'inferno'; import { InfernoWrapper } from './widget_wrapper'; -export class Sortable extends InfernoWrapper { +export interface Props extends SortableProperties { + +} + +export class Sortable extends InfernoWrapper { public render(): InfernoNode { return (
diff --git a/packages/devextreme/playground/jquery.html b/packages/devextreme/playground/jquery.html index 4341e4cc697..8543122812f 100644 --- a/packages/devextreme/playground/jquery.html +++ b/packages/devextreme/playground/jquery.html @@ -224,7 +224,7 @@

Te }, width: "100%", // width: 750, - height: 500, + height: 700, keyExpr: 'ID', cardsPerRow: 'auto', paging: { @@ -232,10 +232,12 @@

Te }, cardMinWidth: 250, cardMaxWidth: 350, + allowColumnReordering: true, columns: [ { dataField: 'ID', // visibleIndex: 2, + allowReordering: false, }, { dataField: 'First Name',