From 6d13e7537953897b1758f9e502f29c146f948dde Mon Sep 17 00:00:00 2001 From: Alyar Date: Tue, 23 Apr 2024 11:29:56 +0300 Subject: [PATCH] DataGrid: Fix rows overlapping each other when dragging when virtual scrolling is enabled and rowDragging.dropFeedbackMode = "push"' (T1179218) (#27181) Co-authored-by: Alyar <> --- ...1179218-virtual-scrolling-dragging-row.png | Bin 0 -> 9266 bytes ...18-virtual-scrolling-dragging-row_mask.png | Bin 0 -> 4146 bytes .../tests/dataGrid/rowDragging.ts | 38 ++++++++++++++++++ .../devextreme/js/__internal/m_sortable.ts | 4 +- .../DevExpress.ui.widgets/sortable.tests.js | 14 +++---- 5 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row.png create mode 100644 e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row_mask.png diff --git a/e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row.png b/e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row.png new file mode 100644 index 0000000000000000000000000000000000000000..8589e6a23c37aea7e21147b3f587de266f7a0fdf GIT binary patch literal 9266 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 literal 0 HcmV?d00001 diff --git a/e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row_mask.png b/e2e/testcafe-devextreme/tests/dataGrid/etalons/T1179218-virtual-scrolling-dragging-row_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..e215f875b5978579d352283e554173d12868a7e5 GIT binary patch literal 4146 zcmeAS@N?(olHy`uVBq!ia0y~yU@u@`VBEpM1{B#MUbd8hf&Ztci(^OyFhSPIHeGl4RE zGN6nZ7oZG-g`)<6gMz+cbZGMQImMsWzuOB9{U5sUxU!KfJI4u$odfw7sUA%aPkO^` zeNYWgD)VX@iv9jw-)j!FaQ=d!nJ(t-c`|46`~r9gs?##XSDu82SIzsA-H33_hKDOW zT1T@WIAx6%Q_u`HS^`4@Vzicm1jJ}f4owiFjTA^gj5g$;31YO33JnPQwoylW7LZ^c kEssXaBTxv?vc+~t-f@Ch#YzF4y&#)BUHx3vIVCg!0Cuo}?EnA( literal 0 HcmV?d00001 diff --git a/e2e/testcafe-devextreme/tests/dataGrid/rowDragging.ts b/e2e/testcafe-devextreme/tests/dataGrid/rowDragging.ts index 74300717840d..1ab63f39c413 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/rowDragging.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/rowDragging.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ import { ClientFunction, Selector } from 'testcafe'; +import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; import DataGrid, { CLASS as DataGridClassNames } from 'devextreme-testcafe-models/dataGrid'; import { ClassNames } from 'devextreme-testcafe-models/dataGrid/classNames'; import { MouseUpEvents, MouseAction } from '../../helpers/mouseUpEvents'; @@ -743,3 +744,40 @@ safeSizeTest('Item should appear in a correct spot when dragging to a different showBorders: true, }); }); + +// T1179218 +safeSizeTest('Rows should appear correctly during dragging when virtual scrolling is enabled and rowDragging.dropFeedbackMode = "push"', async (t) => { + const dataGrid = new DataGrid('#container'); + const { takeScreenshot, compareResults } = createScreenshotsComparer(t); + + // drag the row down + await dataGrid.moveRow(0, 30, 150, true); + await dataGrid.moveRow(0, 30, 350); + + // waiting for autoscrolling + await t.wait(2000); + + // drag the row up + await dataGrid.moveRow(0, 30, 75); + + await t + .expect(await takeScreenshot('T1179218-virtual-scrolling-dragging-row.png', dataGrid.element)) + .ok() + .expect(compareResults.isValid()) + .ok(compareResults.errorMessages()); +}).before(async (t) => { + await t.maximizeWindow(); + return createWidget('dxDataGrid', { + height: 440, + keyExpr: 'id', + scrolling: { + mode: 'virtual', + }, + dataSource: [...new Array(100)].fill(null).map((_, index) => ({ id: index })), + columns: ['id'], + rowDragging: { + allowReordering: true, + dropFeedbackMode: 'push', + }, + }); +}); diff --git a/packages/devextreme/js/__internal/m_sortable.ts b/packages/devextreme/js/__internal/m_sortable.ts index 0c9bcab4c886..781a83d89ebf 100644 --- a/packages/devextreme/js/__internal/m_sortable.ts +++ b/packages/devextreme/js/__internal/m_sortable.ts @@ -13,6 +13,8 @@ import { getWindow } from '@js/core/utils/window'; import eventsEngine from '@js/events/core/events_engine'; import Draggable from '@ts/m_draggable'; +import { isDefined } from '../core/utils/type'; + const window = getWindow(); const SORTABLE = 'dxSortable'; @@ -881,7 +883,7 @@ const Sortable = Draggable.inherit({ if (toIndex === null || fromIndex === null) { stopAnimation(itemElement); - } else if (prevPosition !== position || fullUpdate && position) { + } else if (prevPosition !== position || (fullUpdate && isDefined(position))) { animate(itemElement, extend({}, animationConfig, { to: { [positionPropName]: !isVerticalOrientation && rtlEnabled ? -position : position }, })); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/sortable.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/sortable.tests.js index 981ff9475d8d..b15d8eb9abd1 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/sortable.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/sortable.tests.js @@ -3971,9 +3971,9 @@ QUnit.module('update', moduleConfig, () => { sortable.update(); // assert - assert.equal(getElement(0).get(0).style.transform, '', 'item 1 is not moved'); + assert.equal(getElement(0).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 1 is not moved'); assert.equal(getElement(1).get(0).style.transform, 'translate(0px, -30px)', 'item 2 is not moved'); - assert.equal(getElement(2).get(0).style.transform, '', 'item 3 is not moved'); + assert.equal(getElement(2).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 3 is not moved'); }); QUnit.test('placeholder should be updated if dropFeedbackMode is indicate', function(assert) { @@ -4006,9 +4006,9 @@ QUnit.module('update', moduleConfig, () => { sortable.update(); // assert - assert.equal(getElement(0).get(0).style.transform, '', 'item 1 is not moved'); + assert.equal(getElement(0).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 1 is not moved'); assert.equal(getElement(1).get(0).style.transform, 'translate(0px, -30px)', 'item 2 is moved'); - assert.equal(getElement(2).get(0).style.transform, '', 'item 3 is not moved'); + assert.equal(getElement(2).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 3 is not moved'); }); QUnit.test('items should be moved correctly if offset is increased', function(assert) { @@ -4025,7 +4025,7 @@ QUnit.module('update', moduleConfig, () => { // assert assert.equal(getElement(0).get(0).style.transform, 'translate(0px, -30px)', 'item 1 is moved'); assert.equal(getElement(1).get(0).style.transform, 'translate(0px, -30px)', 'item 2 is moved'); - assert.equal(getElement(2).get(0).style.transform, '', 'item 3 is not moved'); + assert.equal(getElement(2).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 3 is not moved'); }); QUnit.test('items should be moved correctly if offset is decreased', function(assert) { @@ -4040,8 +4040,8 @@ QUnit.module('update', moduleConfig, () => { sortable.update(); // assert - assert.equal(getElement(0).get(0).style.transform, '', 'item 1 is not moved'); - assert.equal(getElement(1).get(0).style.transform, '', 'item 2 is not moved'); + assert.equal(getElement(0).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 1 is not moved'); + assert.equal(getElement(1).get(0).style.transform, browser.mozilla ? 'translate(0px)' : 'translate(0px, 0px)', 'item 2 is not moved'); assert.equal(getElement(2).get(0).style.transform, 'translate(0px, 30px)', 'item 3 is moved'); }); });