[FIX] web: drag and drop kanban flicker
Before this commit, in a kanban view, if you resequence records or
groups by dragging and dropping, there is a flicker.
How to reproduce:
- Go to a kanban view
- Drag and drop a kanban card
Before this commit:
The moved kanban card returns to its previous position during a render.
After this commit:
The kanban card keeps its new position.
closes odoo/odoo#130561
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -86,7 +86,7 @@ export class DynamicGroupList extends DynamicList {
|
||||
const targetGroup = this.groups.find((g) => g.id === targetGroupId);
|
||||
if (dataGroupId === targetGroupId) {
|
||||
// move a record inside the same group
|
||||
targetGroup.list.records = await targetGroup.list._resequence(
|
||||
await targetGroup.list._resequence(
|
||||
targetGroup.list.records,
|
||||
this.resModel,
|
||||
dataRecordId,
|
||||
@@ -125,7 +125,7 @@ export class DynamicGroupList extends DynamicList {
|
||||
throw e;
|
||||
}
|
||||
if (!targetGroup.isFolded) {
|
||||
targetGroup.list.records = await targetGroup.list._resequence(
|
||||
await targetGroup.list._resequence(
|
||||
targetGroup.list.records,
|
||||
this.resModel,
|
||||
dataRecordId,
|
||||
@@ -140,7 +140,7 @@ export class DynamicGroupList extends DynamicList {
|
||||
}
|
||||
|
||||
return this.model.mutex.exec(async () => {
|
||||
this.groups = await this._resequence(
|
||||
await this._resequence(
|
||||
this.groups,
|
||||
this.groupByField.relation,
|
||||
movedGroupId,
|
||||
@@ -220,12 +220,8 @@ export class DynamicGroupList extends DynamicList {
|
||||
const group = this._createGroupDatapoint(data);
|
||||
if (lastGroup) {
|
||||
const groups = [...this.groups, group];
|
||||
this.groups = await this._resequence(
|
||||
groups,
|
||||
this.groupByField.relation,
|
||||
group.id,
|
||||
lastGroup.id
|
||||
);
|
||||
await this._resequence(groups, this.groupByField.relation, group.id, lastGroup.id);
|
||||
this.groups = groups;
|
||||
} else {
|
||||
this.groups.push(group);
|
||||
}
|
||||
|
||||
@@ -268,18 +268,17 @@ export class DynamicList extends DataPoint {
|
||||
|
||||
async _resequence(originalList, resModel, movedId, targetId) {
|
||||
if (this.resModel === resModel && !this.canResequence()) {
|
||||
return originalList;
|
||||
return;
|
||||
}
|
||||
const handleField = this.resModel === resModel ? this.handleField : DEFAULT_HANDLE_FIELD;
|
||||
const dataPoints = [...originalList];
|
||||
const order = this.orderBy.find((o) => o.name === handleField);
|
||||
const asc = !order || order.asc;
|
||||
|
||||
// Find indices
|
||||
const fromIndex = dataPoints.findIndex((d) => d.id === movedId);
|
||||
const fromIndex = originalList.findIndex((d) => d.id === movedId);
|
||||
let toIndex = 0;
|
||||
if (targetId !== null) {
|
||||
const targetIndex = dataPoints.findIndex((d) => d.id === targetId);
|
||||
const targetIndex = originalList.findIndex((d) => d.id === targetId);
|
||||
toIndex = fromIndex > targetIndex ? targetIndex + 1 : targetIndex;
|
||||
}
|
||||
|
||||
@@ -288,13 +287,13 @@ export class DynamicList extends DataPoint {
|
||||
// Determine which records/groups need to be modified
|
||||
const firstIndex = Math.min(fromIndex, toIndex);
|
||||
const lastIndex = Math.max(fromIndex, toIndex) + 1;
|
||||
let reorderAll = dataPoints.some(
|
||||
let reorderAll = originalList.some(
|
||||
(dp) => this._getDPFieldValue(dp, handleField) === undefined
|
||||
);
|
||||
if (!reorderAll) {
|
||||
let lastSequence = (asc ? -1 : 1) * Infinity;
|
||||
for (let index = 0; index < dataPoints.length; index++) {
|
||||
const sequence = getSequence(dataPoints[index]);
|
||||
for (let index = 0; index < originalList.length; index++) {
|
||||
const sequence = getSequence(originalList[index]);
|
||||
if (
|
||||
((index < firstIndex || index >= lastIndex) &&
|
||||
((asc && lastSequence >= sequence) ||
|
||||
@@ -308,11 +307,11 @@ export class DynamicList extends DataPoint {
|
||||
}
|
||||
|
||||
// Perform the resequence in the list of records/groups
|
||||
const [dp] = dataPoints.splice(fromIndex, 1);
|
||||
dataPoints.splice(toIndex, 0, dp);
|
||||
const [dp] = originalList.splice(fromIndex, 1);
|
||||
originalList.splice(toIndex, 0, dp);
|
||||
|
||||
// Creates the list of records/groups to modify
|
||||
let toReorder = dataPoints;
|
||||
let toReorder = originalList;
|
||||
if (!reorderAll) {
|
||||
toReorder = toReorder.slice(firstIndex, lastIndex).filter((r) => r.id !== movedId);
|
||||
if (fromIndex < toIndex) {
|
||||
@@ -341,22 +340,20 @@ export class DynamicList extends DataPoint {
|
||||
}
|
||||
const wasResequenced = await this.model.rpc("/web/dataset/resequence", params);
|
||||
if (!wasResequenced) {
|
||||
return originalList;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the actual values set by the server and update the records/groups
|
||||
const kwargs = { context: this.context };
|
||||
const result = await this.model.orm.read(resModel, resIds, [handleField], kwargs);
|
||||
for (const dpData of result) {
|
||||
const dp = dataPoints.find((d) => this._getDPresId(d) === dpData.id);
|
||||
const dp = originalList.find((d) => this._getDPresId(d) === dpData.id);
|
||||
if (dp instanceof Record) {
|
||||
dp._applyValues(dpData);
|
||||
} else {
|
||||
dp[handleField] = dpData[handleField];
|
||||
}
|
||||
}
|
||||
|
||||
return dataPoints;
|
||||
}
|
||||
|
||||
async _toggleArchive(isSelected, state) {
|
||||
|
||||
@@ -88,12 +88,7 @@ export class DynamicRecordList extends DynamicList {
|
||||
async resequence(movedRecordId, targetRecordId) {
|
||||
return this.model.mutex.exec(
|
||||
async () =>
|
||||
(this.records = await this._resequence(
|
||||
this.records,
|
||||
this.resModel,
|
||||
movedRecordId,
|
||||
targetRecordId
|
||||
))
|
||||
await this._resequence(this.records, this.resModel, movedRecordId, targetRecordId)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12577,13 +12577,13 @@ QUnit.module("Views", (hooks) => {
|
||||
[...target.querySelectorAll(".o_kanban_record:not(.o_kanban_ghost)")].map(
|
||||
(el) => el.innerText
|
||||
),
|
||||
["blip", "blip", "yop", "gnap"]
|
||||
["blip", "yop", "blip", "gnap"]
|
||||
);
|
||||
assert.verifySteps(["resequence"]);
|
||||
|
||||
// try again
|
||||
await dragAndDrop(".o_kanban_record:nth-child(2)", ".o_kanban_record:nth-child(3)");
|
||||
-assert.verifySteps([]);
|
||||
assert.verifySteps([]);
|
||||
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
|
||||
Reference in New Issue
Block a user