Skip to content

Commit fd8c47d

Browse files
GridCore: Refactoring of the fluent borders related code. (#26393)
1 parent d136b0f commit fd8c47d

File tree

2 files changed

+118
-82
lines changed

2 files changed

+118
-82
lines changed

packages/devextreme/js/__internal/grids/grid_core/m_modules.ts

Lines changed: 12 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Callbacks from '@js/core/utils/callbacks';
55
// @ts-expect-error
66
import { grep } from '@js/core/utils/common';
77
import { each } from '@js/core/utils/iterator';
8-
import { isDefined, isFunction } from '@js/core/utils/type';
8+
import { isFunction } from '@js/core/utils/type';
99
import { hasWindow } from '@js/core/utils/window';
1010
import messageLocalization from '@js/localization/message';
1111
import errors from '@js/ui/widget/ui.errors';
@@ -16,11 +16,11 @@ import type {
1616
View as ViewType,
1717
ViewController as ViewControllerType,
1818
} from './m_types';
19+
import type { ViewsWithBorder } from './views/utils/update_views_borders';
20+
import { updateViewsBorders } from './views/utils/update_views_borders';
1921

2022
const WIDGET_WITH_LEGACY_CONTAINER_NAME = 'dxDataGrid';
2123

22-
const BORDERED_VIEWS = ['columnHeadersView', 'rowsView', 'footerView', 'filterPanelView'];
23-
2424
const ModuleItem = Class.inherit({
2525
_endUpdateCore() { },
2626

@@ -262,83 +262,13 @@ const View: ModuleType<ViewType> = ModuleItem.inherit({
262262
return this.component._views[name];
263263
},
264264

265-
getFirstVisibleViewElement() {
266-
const columnHeaderView = this.getView('columnHeadersView');
267-
if (columnHeaderView && columnHeaderView.isVisible()) {
268-
return columnHeaderView.element();
269-
}
270-
271-
return this.getView('rowsView').element();
272-
},
273-
274-
getLastVisibleViewElement() {
275-
const filterPanelView = this.getView('filterPanelView');
276-
if (filterPanelView && filterPanelView.isVisible()) {
277-
return filterPanelView.element();
278-
}
279-
280-
const footerView = this.getView('footerView');
281-
if (footerView && footerView.isVisible()) {
282-
return footerView.element();
283-
}
284-
285-
return this.getView('rowsView').element();
286-
},
287-
288-
getViewElementWithClass(className) {
289-
const borderedView = BORDERED_VIEWS.map((viewName) => this.getView(viewName))
290-
.filter((view) => view && view.element())
291-
.find((view) => view.element().hasClass(className));
292-
293-
return borderedView && borderedView.element();
294-
},
295-
296-
updateBorderedViews() {
297-
const BORDERED_TOP_VIEW_CLASS = 'dx-bordered-top-view';
298-
const BORDERED_BOTTOM_VIEW_CLASS = 'dx-bordered-bottom-view';
299-
300-
const oldFirstBorderedElement = this.getViewElementWithClass(BORDERED_TOP_VIEW_CLASS);
301-
const oldLastBorderedElement = this.getViewElementWithClass(BORDERED_BOTTOM_VIEW_CLASS);
302-
const newFirstBorderedElement = this.getFirstVisibleViewElement();
303-
const newLastBorderedElement = this.getLastVisibleViewElement();
304-
305-
if (oldFirstBorderedElement && !oldFirstBorderedElement.is(newFirstBorderedElement)) {
306-
oldFirstBorderedElement.removeClass(BORDERED_TOP_VIEW_CLASS);
307-
}
308-
309-
if (oldLastBorderedElement && !oldLastBorderedElement.is(newLastBorderedElement)) {
310-
oldLastBorderedElement.removeClass(BORDERED_BOTTOM_VIEW_CLASS);
311-
}
312-
313-
if (!newFirstBorderedElement.hasClass(BORDERED_TOP_VIEW_CLASS)) {
314-
newFirstBorderedElement.addClass(BORDERED_TOP_VIEW_CLASS);
315-
}
316-
317-
if (!newLastBorderedElement.hasClass(BORDERED_BOTTOM_VIEW_CLASS)) {
318-
newLastBorderedElement.addClass(BORDERED_BOTTOM_VIEW_CLASS);
319-
}
320-
},
321-
322-
isViewsStateValid() {
323-
if (this.component._views) {
324-
if (!BORDERED_VIEWS.includes(this.name)) {
325-
return false;
326-
}
327-
328-
const rowsView = this.getView('rowsView');
329-
if (!(rowsView && isDefined(rowsView.element?.()))) {
330-
return false;
331-
}
332-
333-
const optionalViews = ['columnHeadersView', 'footerView', 'filterPanelView']
334-
.map((viewName) => this.getView(viewName))
335-
.filter((view) => view && view.isVisible?.());
336-
const isOptionalViewsRendered = optionalViews.every((view) => view && isDefined(view.element()));
337-
338-
return isOptionalViewsRendered;
339-
}
340-
341-
return false;
265+
_getBorderedViews(): ViewsWithBorder {
266+
return {
267+
columnHeadersView: this.component._views.columnHeadersView,
268+
rowsView: this.component._views.rowsView,
269+
filterPanelView: this.component._views.filterPanelView,
270+
footerView: this.component._views.footerView,
271+
};
342272
},
343273

344274
render($parent, options) {
@@ -356,8 +286,8 @@ const View: ModuleType<ViewType> = ModuleItem.inherit({
356286

357287
$element.toggleClass('dx-hidden', !isVisible);
358288

359-
if (this.isViewsStateValid()) {
360-
this.updateBorderedViews();
289+
if (this.component._views) {
290+
updateViewsBorders(this.name, this._getBorderedViews());
361291
}
362292

363293
if (isVisible) {
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-return */
2+
import { dxElementWrapper } from '@js/core/renderer';
3+
import { isDefined } from '@js/core/utils/type';
4+
5+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6+
type View = any;
7+
8+
// TODO: Move to the grid_core/m_types views interface.
9+
export interface ViewsWithBorder {
10+
columnHeadersView: View;
11+
rowsView: View;
12+
filterPanelView: View;
13+
footerView: View;
14+
}
15+
16+
const CLASSES = {
17+
borderedTop: 'dx-bordered-top-view',
18+
borderedBottom: 'dx-bordered-bottom-view',
19+
};
20+
21+
const getFirstVisibleViewElement = ({
22+
columnHeadersView,
23+
rowsView,
24+
}: ViewsWithBorder): dxElementWrapper => {
25+
if (columnHeadersView?.isVisible()) {
26+
return columnHeadersView.element();
27+
}
28+
29+
return rowsView.element();
30+
};
31+
32+
const getLastVisibleViewElement = ({
33+
filterPanelView,
34+
footerView,
35+
rowsView,
36+
}: ViewsWithBorder): dxElementWrapper => {
37+
if (filterPanelView?.isVisible()) {
38+
return filterPanelView.element();
39+
}
40+
41+
if (footerView?.isVisible()) {
42+
return footerView.element();
43+
}
44+
45+
return rowsView.element();
46+
};
47+
48+
const getViewElementWithClass = (
49+
viewsWithBorder: ViewsWithBorder,
50+
className: string,
51+
): dxElementWrapper | null => {
52+
const borderedView = Object.values(viewsWithBorder)
53+
.find((view) => view?.element()?.hasClass(className));
54+
55+
return borderedView?.element() ?? null;
56+
};
57+
58+
const shouldUpdateBorders = (
59+
viewName: string,
60+
viewsWithBorder: ViewsWithBorder,
61+
): boolean => {
62+
if (!Object.keys(viewsWithBorder).includes(viewName)) {
63+
return false;
64+
}
65+
66+
const { rowsView, ...otherViews } = viewsWithBorder;
67+
if (!isDefined(rowsView?.element?.())) {
68+
return false;
69+
}
70+
71+
return Object.values(otherViews)
72+
.filter((view) => view?.isVisible?.())
73+
.every((view) => isDefined(view?.element()));
74+
};
75+
76+
export const updateViewsBorders = (
77+
viewName: string,
78+
viewsWithBorder: ViewsWithBorder,
79+
): void => {
80+
if (!shouldUpdateBorders(viewName, viewsWithBorder)) {
81+
return;
82+
}
83+
84+
const $oldFirst = getViewElementWithClass(viewsWithBorder, CLASSES.borderedTop);
85+
const $oldLast = getViewElementWithClass(viewsWithBorder, CLASSES.borderedBottom);
86+
const $newFirst = getFirstVisibleViewElement(viewsWithBorder);
87+
const $newLast = getLastVisibleViewElement(viewsWithBorder);
88+
89+
// @ts-expect-error The dxElementWrapper's "is" method is badly typed.
90+
if ($oldFirst && !$oldFirst.is($newFirst)) {
91+
$oldFirst.removeClass(CLASSES.borderedTop);
92+
}
93+
94+
// @ts-expect-error The dxElementWrapper's "is" method is badly typed.
95+
if ($oldLast && !$oldLast.is($newLast)) {
96+
$oldLast.removeClass(CLASSES.borderedBottom);
97+
}
98+
99+
if (!$newFirst.hasClass(CLASSES.borderedTop)) {
100+
$newFirst.addClass(CLASSES.borderedTop);
101+
}
102+
103+
if (!$newLast.hasClass(CLASSES.borderedBottom)) {
104+
$newLast.addClass(CLASSES.borderedBottom);
105+
}
106+
};

0 commit comments

Comments
 (0)