Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 20 additions & 12 deletions contentcuration/contentcuration/frontend/shared/data/changes.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class ChangeTracker {
// We'll go through each change one by one and revert each.
//
// R. Tibbles: I think this could be done in two queries (TODO)
return promiseChunk(this._changes.reverse(), 1, ([change]) => {
return promiseChunk(this._changes.reverse(), 1, async ([change]) => {
const resource = INDEXEDDB_RESOURCES[change.table];
if (!resource) {
if (process.env.NODE_ENV !== 'production') {
Expand All @@ -150,6 +150,16 @@ export class ChangeTracker {
}
return Promise.resolve();
}

// Query siblings before starting the transaction
// to avoid any potential API call inside the transaction
let siblings;
if (change.type === CHANGE_TYPES.MOVED && change.oldObj) {
const { parent } = change.oldObj;
siblings = await resource.where({ parent }, false);
siblings = siblings.filter(sibling => sibling.id !== change.key);
}

return resource.transaction({}, CHANGES_TABLE, () => {
// If we had created something, we'll delete it
// Special MOVED case here comes from the operation of COPY then MOVE for duplicating
Expand All @@ -170,17 +180,15 @@ export class ChangeTracker {
const { parent, lft } = change.oldObj;

// Collect the affected node's siblings prior to the change
return resource.where({ parent }, false).then(siblings => {
// Search the siblings ordered by `lft` to find the first a sibling
// where we should move the node, positioned before that sibling
const relativeSibling = sortBy(siblings, 'lft').find(sibling => sibling.lft >= lft);
if (relativeSibling) {
return resource.move(change.key, relativeSibling.id, RELATIVE_TREE_POSITIONS.LEFT);
}

// this handles if there were no siblings OR if the deleted node was at the end
return resource.move(change.key, parent, RELATIVE_TREE_POSITIONS.LAST_CHILD);
});
// Search the siblings ordered by `lft` to find the first a sibling
// where we should move the node, positioned before that sibling
const relativeSibling = sortBy(siblings, 'lft').find(sibling => sibling.lft >= lft);
if (relativeSibling) {
return resource.move(change.key, relativeSibling.id, RELATIVE_TREE_POSITIONS.LEFT);
}

// this handles if there were no siblings OR if the deleted node was at the end
return resource.move(change.key, parent, RELATIVE_TREE_POSITIONS.LAST_CHILD);
} else {
if (process.env.NODE_ENV !== 'production') {
/* eslint-disable no-console */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,7 @@ export const ContentNode = new TreeResource({
return Promise.all([getNode, this.where({ parent: parent.id }, false)]).then(
([node, siblings]) => {
let lft = 1;
siblings = siblings.filter(s => s.id !== id);
if (siblings.length) {
// If we're creating, we don't need to worry about passing the ID
lft = this.getNewSortOrder(isCreate ? null : id, target, position, siblings);
Expand Down