Skip to content

Commit c81f56f

Browse files
fix: swap columns iteratively on reorder (#2220)
* fix: swap columns iteratively on reorder Cherry-pick of vaadin/web-components#4534 * replace usages of findIndex, includes * try reduce column size * Update src/vaadin-grid-column-reordering-mixin.html Co-authored-by: Tomi Virkki <[email protected]> Co-authored-by: Tomi Virkki <[email protected]>
1 parent 7957353 commit c81f56f

File tree

2 files changed

+75
-9
lines changed

2 files changed

+75
-9
lines changed

src/vaadin-grid-column-reordering-mixin.html

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,23 @@
167167
const targetColumn = this._getTargetColumn(targetCell, this._draggedColumn);
168168
if (this._isSwapAllowed(this._draggedColumn, targetColumn) &&
169169
this._isSwappableByPosition(targetColumn, e.detail.x)) {
170-
this._swapColumnOrders(this._draggedColumn, targetColumn);
170+
// Get the header level of the target column (and the dragged column)
171+
const columnTreeLevel = this.__getColumnTreeLevel(targetColumn);
172+
// Get the columns on that level in visual order
173+
const levelColumnsInOrder = this._getColumnsInOrder(columnTreeLevel);
174+
175+
// Index of the column being dragged
176+
const startIndex = levelColumnsInOrder.indexOf(this._draggedColumn);
177+
// Index of the column being dragged over
178+
const endIndex = levelColumnsInOrder.indexOf(targetColumn);
179+
180+
// Direction of iteration
181+
const direction = startIndex < endIndex ? 1 : -1;
182+
183+
// Iteratively swap all the columns from the dragged column to the target column
184+
for (let i = startIndex; i !== endIndex; i += direction) {
185+
this._swapColumnOrders(this._draggedColumn, levelColumnsInOrder[i + direction]);
186+
}
171187
}
172188

173189
this._updateGhostPosition(e.detail.x, this._touchDevice ? e.detail.y - 50 : e.detail.y);
@@ -194,13 +210,17 @@
194210
}
195211

196212
/**
213+
* Returns the columns (or column groups) on the specified header level in visual order.
214+
* By default, the bottom level is used.
215+
*
197216
* @return {!Array<!GridColumnElement>}
198217
* @protected
199218
*/
200-
_getColumnsInOrder() {
201-
return this._columnTree.slice(0).pop()
202-
.filter(c => !c.hidden)
203-
.sort((b, a) => (b._order - a._order));
219+
_getColumnsInOrder(headerLevel) {
220+
if (!headerLevel && headerLevel !== 0) {
221+
headerLevel = this._columnTree.length - 1;
222+
}
223+
return this._columnTree[headerLevel].filter((c) => !c.hidden).sort((b, a) => b._order - a._order);
204224
}
205225

206226
/**
@@ -403,6 +423,16 @@
403423
}
404424
}
405425

426+
/** @private */
427+
__getColumnTreeLevel(column) {
428+
for (let level = 0; level < this._columnTree.length; level++) {
429+
if (this._columnTree[level].indexOf(column) >= 0) {
430+
return level;
431+
}
432+
}
433+
return -1;
434+
}
435+
406436
/**
407437
* Fired when the columns in the grid are reordered.
408438
*

test/column-reordering.html

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@
4141

4242
<test-fixture id="groups">
4343
<template>
44-
<vaadin-grid style="width: 400px; height: 200px;" size="1" column-reordering-allowed>
45-
<dom-repeat is="dom-repeat" items="[1, 2]" as="colgroup">
44+
<vaadin-grid style="width: 800px; height: 200px;" size="1" column-reordering-allowed>
45+
<dom-repeat is="dom-repeat" items="[1, 2, 3]" as="colgroup">
4646
<template>
4747
<vaadin-grid-column-group>
4848
<template class="header">[[colgroup]]</template>
4949
<template class="footer">[[colgroup]]</template>
5050
<dom-repeat is="dom-repeat" items="[1, 2]" as="col">
5151
<template>
52-
<vaadin-grid-column>
52+
<vaadin-grid-column width="50px" flex-grow="0">
5353
<template class="header">[[colgroup]][[col]]</template>
5454
<template>[[colgroup]][[col]]</template>
5555
<template class="footer">[[colgroup]][[col]]</template>
@@ -358,10 +358,32 @@
358358
});
359359

360360
it('should reorder multiple columns while dragging', () => {
361+
// Start column order [1, 2, 3, 4]
362+
363+
// Drag column 1 on top of column 2. Expected order [2, 1, 3, 4]
361364
dragOver(headerContent[0], headerContent[1]);
365+
// Keep dragging the column all the way over to the last column. Expected order [2, 3, 4, 1]
362366
dragOver(headerContent[0], headerContent[3]);
363367
flushGrid(grid);
364-
expectVisualOrder(grid, [2, 4, 3, 1]);
368+
expectVisualOrder(grid, [2, 3, 4, 1]);
369+
});
370+
371+
it('should shift columns in between when dragged as last', () => {
372+
// Start column order [1, 2, 3, 4]
373+
374+
// Drag column 2 all the way over to the last column. Expected order [1, 3, 4, 2]
375+
dragOver(headerContent[1], headerContent[3]);
376+
flushGrid(grid);
377+
expectVisualOrder(grid, [1, 3, 4, 2]);
378+
});
379+
380+
it('should shift columns in between when dragged as first', () => {
381+
// Start column order [1, 2, 3, 4]
382+
383+
// Drag column 3 over the very first column. Expected order [3, 1, 2, 4]
384+
dragOver(headerContent[2], headerContent[0]);
385+
flushGrid(grid);
386+
expectVisualOrder(grid, [3, 1, 2, 4]);
365387
});
366388

367389
it('should update first-column attribute', () => {
@@ -516,6 +538,20 @@
516538
expectVisualOrder(grid, [21, 22, 11, 12]);
517539
});
518540

541+
it('should reorder all the groups', () => {
542+
// Start order
543+
// [1, 2, 3 ] <- groups
544+
// [11, 12, 21, 22, 31, 32] <- columns
545+
546+
// Drag the first group over the last group
547+
dragAndDropOver(getVisualHeaderCellContent(grid, 0, 0), getVisualHeaderCellContent(grid, 0, 5));
548+
549+
// Expected order
550+
// [2, 3, 1 ] <- groups
551+
// [21, 22, 31, 32, 11, 12] <- columns
552+
expectVisualOrder(grid, [21, 22, 31, 32, 11, 12]);
553+
});
554+
519555
it('should allow dropping group over other groups column header', () => {
520556
dragAndDropOver(
521557
getVisualHeaderCellContent(grid, 0, 0),

0 commit comments

Comments
 (0)