Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataGrid/TreeList - Sticky Columns: Adapt the editing and filter row features #28185

Merged
Merged
Changes from 1 commit
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
Next Next commit
Adapt the editing feature
Alyar committed Oct 16, 2024
commit 5ac394982ece57a7033303b57c6dc124885156d7
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
import DataGrid from 'devextreme-testcafe-models/dataGrid';
import { safeSizeTest } from '../../../helpers/safeSizeTest';
import { createWidget } from '../../../helpers/createWidget';
import url from '../../../helpers/getPageUrl';
import { defaultConfig } from './data';

const DATA_GRID_SELECTOR = '#container';

fixture.disablePageReloads`Sticky columns - Editing`
.page(url(__dirname, '../../container.html'));

safeSizeTest('The row edit mode: Edit cell with validation rule when there are sticky columns', async (t) => {
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);

await dataGrid.apiEditRow(1);
await dataGrid.apiCellValue(1, 1, '');
await t.click(dataGrid.getDataCell(1, 1).element);

await takeScreenshot('edit_row_with_sticky_columns_1.png', dataGrid.element);

await dataGrid.scrollTo(t, { x: 10000 });

await takeScreenshot('edit_row_with_sticky_columns_2.png', dataGrid.element);

await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
}, [800, 800]).before(async () => createWidget('dxDataGrid', {
...defaultConfig,
editing: {
mode: 'row',
allowUpdating: true,
},
customizeColumns(columns) {
columns.forEach((column, index) => {
if (index === 1) {
column.validationRules = [{ type: 'required' }];
}
});
},
}));

safeSizeTest('The cell edit mode: Edit cell with validation rule when there are sticky columns', async (t) => {
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);

await dataGrid.apiEditCell(1, 1);
await dataGrid.apiCellValue(1, 1, '');
await t.click(dataGrid.getDataCell(1, 1).element);

await takeScreenshot('edit_cell_with_sticky_columns_1.png', dataGrid.element);

await dataGrid.scrollTo(t, { x: 10000 });

await takeScreenshot('edit_cell_with_sticky_columns_2.png', dataGrid.element);

await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
}, [800, 800]).before(async () => createWidget('dxDataGrid', {
...defaultConfig,
editing: {
mode: 'cell',
allowUpdating: true,
},
customizeColumns(columns) {
columns.forEach((column, index) => {
if (index === 1) {
column.validationRules = [{ type: 'required' }];
}
});
},
}));

safeSizeTest('The form edit mode: Edit row when there are sticky columns', async (t) => {
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);

await dataGrid.apiEditRow(1);

await takeScreenshot('edit_form_with_sticky_columns_1.png', dataGrid.element);

await dataGrid.scrollTo(t, { x: 10000 });

await takeScreenshot('edit_form_with_sticky_columns_2.png', dataGrid.element);

await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
}, [800, 800]).before(async () => createWidget('dxDataGrid', {
...defaultConfig,
editing: {
mode: 'form',
allowUpdating: true,
},
}));
5 changes: 5 additions & 0 deletions packages/devextreme-scss/scss/widgets/base/_gridBase.scss
Original file line number Diff line number Diff line change
@@ -197,6 +197,11 @@

.dx-#{$widget-name}-sticky-column, .dx-#{$widget-name}-sticky-column-left, .dx-#{$widget-name}-sticky-column-right {
position: sticky;
z-index: 2;

&.dx-#{$widget-name}-sticky-column-right {
z-index: 3;
}
}
}

Original file line number Diff line number Diff line change
@@ -1122,8 +1122,14 @@ $fluent-grid-base-group-panel-message-line-height: $fluent-button-text-line-heig
}
}

&.dx-#{$widget-name}-sticky-columns .dx-row:not(.dx-row-lines) > td {
padding-top: $fluent-grid-base-cell-vertical-padding + 1;
&.dx-#{$widget-name}-sticky-columns {
.dx-row:not(.dx-row-lines) > td:not(.dx-editor-cell, .dx-master-detail-cell) {
padding-top: $fluent-grid-base-cell-vertical-padding + 1px;
}

.dx-row.dx-row-lines.dx-edit-row > td {
border-top-width: 0;
}
}
}

Original file line number Diff line number Diff line change
@@ -1030,8 +1030,14 @@ $generic-grid-base-group-panel-message-line-height: $generic-button-text-line-he
}
}

.dx-#{$widget-name}-rowsview.dx-#{$widget-name}-sticky-columns .dx-row:not(.dx-row-lines) > td {
padding-top: $generic-grid-base-cell-padding + 1px;
.dx-#{$widget-name}-rowsview.dx-#{$widget-name}-sticky-columns {
.dx-row:not(.dx-row-lines) > td:not(.dx-editor-cell, .dx-master-detail-cell) {
padding-top: $generic-grid-base-cell-padding + 1px;
}

.dx-row.dx-row-lines.dx-edit-row > td {
border-top-width: 0;
}
}

.dx-rtl {
Original file line number Diff line number Diff line change
@@ -1093,8 +1093,14 @@ $material-grid-base-group-panel-message-line-height: $material-button-text-line-
}
}

&.dx-#{$widget-name}-sticky-columns .dx-row:not(.dx-row-lines) > td {
padding-top: $material-grid-base-cell-vertical-padding + 1;
&.dx-#{$widget-name}-sticky-columns {
.dx-row:not(.dx-row-lines) > td:not(.dx-editor-cell, .dx-master-detail-cell) {
padding-top: $material-grid-base-cell-vertical-padding + 1px;
}

.dx-row.dx-row-lines.dx-edit-row > td {
border-top-width: 0;
}
}
}

Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ import eventsEngine from '@js/events/core/events_engine';
import { name as wheelEventName } from '@js/events/core/wheel';
import messageLocalization from '@js/localization/message';
import Scrollable from '@js/ui/scroll_view/ui.scrollable';
import type { EditorFactory } from '@ts/grids/grid_core/editor_factory/m_editor_factory';
import { validatingEditorFactoryExtender } from '@ts/grids/grid_core/validating/m_validating';

import type { ColumnHeadersView } from '../column_headers/m_column_headers';
import type {
@@ -492,13 +494,6 @@ const baseFixedColumns = <T extends ModuleType<ColumnsView>>(Base: T) => class B
return this._fixedTableElement;
}

private isFixedColumns() {
const fixedColumns = this.getFixedColumns();
const legacyMode = this.option('columnFixing.legacyMode');

return legacyMode === true && !!fixedColumns.length;
}

protected _resizeCore() {
super._resizeCore();
this.synchronizeRows();
@@ -613,6 +608,13 @@ const baseFixedColumns = <T extends ModuleType<ColumnsView>>(Base: T) => class B
paddingRight: !rtlEnabled ? width : '',
});
}

public isFixedColumns(): boolean {
const fixedColumns = this.getFixedColumns();
const legacyMode = this.option('columnFixing.legacyMode');

return legacyMode === true && !!fixedColumns.length;
}
};

const columnHeadersView = (Base: ModuleType<ColumnHeadersView>) => class ColumnHeadersViewFixedColumnsExtender extends baseFixedColumns(Base) {
@@ -1158,6 +1160,20 @@ const keyboardNavigation = (Base: ModuleType<KeyboardNavigationController>) => c
}
};

const editorFactory = (Base: ModuleType<EditorFactory>) => class EditorFactoryFixedColumnsExtender extends validatingEditorFactoryExtender(Base) {
protected getValidationOverlayContainer($cell: dxElementWrapper): dxElementWrapper {
const rowsViewModule = this.getView('rowsView');
// @ts-expect-error RowsView's method
const isFixedColumns = rowsViewModule.isFixedColumns();

if (isFixedColumns) {
return rowsViewModule.element() as dxElementWrapper;
}

return super.getValidationOverlayContainer($cell);
}
};

export const columnFixingModule = {
defaultOptions() {
return {
@@ -1192,6 +1208,7 @@ export const columnFixingModule = {
columnsResizer,
resizing,
keyboardNavigation,
editorFactory,
},
},
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable max-classes-per-file */
import type { dxElementWrapper } from '@js/core/renderer';
import $ from '@js/core/renderer';
import browser from '@js/core/utils/browser';
// @ts-expect-error
@@ -1194,12 +1195,7 @@ export const validatingEditorFactoryExtender = (Base: ModuleType<EditorFactory>)
const myPosition = isOverlayVisible ? 'top right' : `top ${alignment}`;
const atPosition = isOverlayVisible ? 'top left' : `bottom ${alignment}`;

// TODO: Don't forget to remove this code
// after refactoring the fixed table position (or implementation).
const hasFixedColumns = this._columnsController.getFixedColumns()?.length > 0;
const $overlayContainer = hasFixedColumns
? this.getView('rowsView').element()
: $cell.closest(`.${this.addWidgetPrefix(CONTENT_CLASS)}`);
const $overlayContainer = this.getValidationOverlayContainer($cell);

let errorMessageText = '';
messages && messages.forEach((message) => {
@@ -1445,6 +1441,10 @@ export const validatingEditorFactoryExtender = (Base: ModuleType<EditorFactory>)
const $editor = $container.find('.dx-texteditor').eq(0);
return gridCoreUtils.getWidgetInstance($editor);
}

protected getValidationOverlayContainer($cell: dxElementWrapper): dxElementWrapper {
return $cell.closest(`.${this.addWidgetPrefix(CONTENT_CLASS)}`);
}
};

export const validatingDataControllerExtender = (Base: ModuleType<DataController>) => class ValidatingDataControllerExtender extends Base {