Skip to content

Commit 0d9b82b

Browse files
Alyar666pomahtri
authored andcommitted
CardView: Implement Toolbar (#28693)
Co-authored-by: Alyar <>
1 parent af0be7b commit 0d9b82b

File tree

19 files changed

+825
-71
lines changed

19 files changed

+825
-71
lines changed

packages/devextreme/js/__internal/grids/grid_core/header_panel/m_header_panel.ts

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
import messageLocalization from '@js/common/core/localization/message';
33
import $ from '@js/core/renderer';
44
import { getPathParts } from '@js/core/utils/data';
5-
import { extend } from '@js/core/utils/extend';
6-
import { isDefined, isString } from '@js/core/utils/type';
5+
import { isDefined } from '@js/core/utils/type';
76
import type { Properties as ToolbarProperties } from '@js/ui/toolbar';
87
import Toolbar from '@js/ui/toolbar';
98
import type { EditingController } from '@ts/grids/grid_core/editing/m_editing';
109
import type { HeaderFilterController } from '@ts/grids/grid_core/header_filter/m_header_filter';
10+
import { normalizeToolbarItems } from '@ts/grids/new/grid_core/toolbar/utils';
1111

1212
import type { ModuleType } from '../m_types';
1313
import { ColumnsView } from '../views/m_columns_view';
@@ -72,7 +72,11 @@ export class HeaderPanel extends ColumnsView {
7272
};
7373

7474
const userItems = userToolbarOptions?.items;
75-
options.toolbarOptions.items = this._normalizeToolbarItems(options.toolbarOptions.items, userItems);
75+
options.toolbarOptions.items = normalizeToolbarItems(
76+
options.toolbarOptions.items,
77+
userItems,
78+
DEFAULT_TOOLBAR_ITEM_NAMES,
79+
);
7680

7781
this.executeAction('onToolbarPreparing', options);
7882

@@ -84,51 +88,6 @@ export class HeaderPanel extends ColumnsView {
8488
return options.toolbarOptions;
8589
}
8690

87-
private _normalizeToolbarItems(defaultItems, userItems) {
88-
defaultItems.forEach((button) => {
89-
if (!DEFAULT_TOOLBAR_ITEM_NAMES.includes(button.name)) {
90-
throw new Error(`Default toolbar item '${button.name}' is not added to DEFAULT_TOOLBAR_ITEM_NAMES`);
91-
}
92-
});
93-
94-
const defaultProps = {
95-
location: 'after',
96-
};
97-
98-
const isArray = Array.isArray(userItems);
99-
100-
if (!isDefined(userItems)) {
101-
return defaultItems;
102-
}
103-
104-
if (!isArray) {
105-
userItems = [userItems];
106-
}
107-
108-
const defaultButtonsByNames = {};
109-
defaultItems.forEach((button) => {
110-
defaultButtonsByNames[button.name] = button;
111-
});
112-
113-
const normalizedItems = userItems.map((button) => {
114-
if (isString(button)) {
115-
button = { name: button };
116-
}
117-
118-
if (isDefined(button.name)) {
119-
if (isDefined(defaultButtonsByNames[button.name])) {
120-
button = extend(true, {}, defaultButtonsByNames[button.name], button);
121-
} else if (DEFAULT_TOOLBAR_ITEM_NAMES.includes(button.name)) {
122-
button = { ...button, visible: false };
123-
}
124-
}
125-
126-
return extend(true, {}, defaultProps, button);
127-
});
128-
129-
return isArray ? normalizedItems : normalizedItems[0];
130-
}
131-
13291
protected _renderCore() {
13392
if (!this._toolbar) {
13493
const $headerPanel = this.element();
@@ -217,7 +176,11 @@ export class HeaderPanel extends ColumnsView {
217176
this._invalidate();
218177
} else if (parts.length === 3) {
219178
// `toolbar.items[i]` case
220-
const normalizedItem = this._normalizeToolbarItems(this._getToolbarItems(), args.value);
179+
const normalizedItem = normalizeToolbarItems(
180+
this._getToolbarItems(),
181+
[args.value],
182+
DEFAULT_TOOLBAR_ITEM_NAMES,
183+
)[0];
221184
this._toolbar?.option(optionName, normalizedItem);
222185
} else if (parts.length >= 4) {
223186
// `toolbar.items[i].prop` case

packages/devextreme/js/__internal/grids/new/card_view/__snapshots__/widget.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ exports[`common initial render should be successfull 1`] = `
44
<div
55
class="dx-widget dx-cardview"
66
>
7+
78
This is cardView
89
</div>
910
`;
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
11
/* eslint-disable spellcheck/spell-checker */
22
/* eslint-disable @typescript-eslint/explicit-member-accessibility */
3-
import { state } from '@ts/core/reactive/index';
3+
import { combined } from '@ts/core/reactive/index';
44
import { View } from '@ts/grids/new/grid_core/core/view';
5+
import { ToolbarView } from '@ts/grids/new/grid_core/toolbar/view';
6+
import type { ComponentType } from 'inferno';
57

68
// eslint-disable-next-line @typescript-eslint/no-empty-interface
79
interface MainViewProps {
8-
10+
Toolbar: ComponentType;
911
}
1012

1113
// eslint-disable-next-line no-empty-pattern
1214
function MainViewComponent({
13-
15+
Toolbar,
1416
}: MainViewProps): JSX.Element {
1517
return (<>
18+
{/* @ts-expect-error */}
19+
<Toolbar/>
1620
This is cardView
1721
</>);
1822
}
1923

2024
export class MainView extends View<MainViewProps> {
2125
protected override component = MainViewComponent;
2226

23-
public static dependencies = [] as const;
27+
public static dependencies = [ToolbarView] as const;
28+
29+
constructor(
30+
private readonly toolbar: ToolbarView,
31+
) {
32+
super();
33+
}
2434

2535
// eslint-disable-next-line max-len
2636
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type
2737
protected override getProps() {
28-
return state({});
38+
return combined({
39+
Toolbar: this.toolbar.asInferno(),
40+
});
2941
}
3042
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2+
import '@js/ui/button';
3+
import '@js/ui/check_box';
4+
5+
import dxToolbar from '@js/ui/toolbar';
6+
7+
import type { ToolbarProps } from '../toolbar/types';
8+
import { InfernoWrapper } from './widget_wrapper';
9+
10+
export class Toolbar extends InfernoWrapper<ToolbarProps, dxToolbar> {
11+
protected getComponentFabric(): typeof dxToolbar {
12+
return dxToolbar;
13+
}
14+
15+
protected updateComponentOptions(prevProps: ToolbarProps, props: ToolbarProps): void {
16+
if (
17+
Array.isArray(props.items)
18+
&& Array.isArray(prevProps.items)
19+
&& props.items.length === prevProps.items.length
20+
) {
21+
props.items?.forEach((item, index) => {
22+
if (props.items![index] !== prevProps.items![index]) {
23+
const prevItem = prevProps.items![index];
24+
25+
Object.keys(item).forEach((key) => {
26+
if (item[key] !== prevItem[key]) {
27+
this.component?.option(`items[${index}].${key}`, props.items![index][key]);
28+
}
29+
});
30+
}
31+
});
32+
33+
const { items, ...propsToUpdate } = props;
34+
35+
super.updateComponentOptions(prevProps, propsToUpdate);
36+
} else {
37+
super.updateComponentOptions(prevProps, props);
38+
}
39+
}
40+
}

packages/devextreme/js/__internal/grids/new/grid_core/options.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { WidgetOptions } from '@js/ui/widget/ui.widget';
44

55
import * as columnsController from './columns_controller/index';
66
import * as dataController from './data_controller/index';
7+
import type * as toolbar from './toolbar';
78
import type { GridCoreNew } from './widget';
89

910
/**
@@ -12,7 +13,8 @@ import type { GridCoreNew } from './widget';
1213
export type Options =
1314
& WidgetOptions<GridCoreNew>
1415
& dataController.Options
15-
& columnsController.Options;
16+
& columnsController.Options
17+
& toolbar.Options;
1618

1719
export const defaultOptions = {
1820
...dataController.defaultOptions,

0 commit comments

Comments
 (0)