Skip to content

Commit 855a897

Browse files
authored
Merge pull request #3700 from bjester/fix-revert
Generate a reverse move when reverting a move
2 parents 796b011 + 4ea3285 commit 855a897

1 file changed

Lines changed: 36 additions & 19 deletions

File tree

  • contentcuration/contentcuration/frontend/shared/data

contentcuration/contentcuration/frontend/shared/data/changes.js

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import Dexie from 'dexie';
2+
import sortBy from 'lodash/sortBy';
23
import db from 'shared/data/db';
34
import { promiseChunk } from 'shared/utils/helpers';
4-
import { CHANGES_TABLE, CHANGE_TYPES, IGNORED_SOURCE } from 'shared/data/constants';
5-
import { Session } from 'shared/data/resources';
5+
import {
6+
CHANGES_TABLE,
7+
CHANGE_TYPES,
8+
IGNORED_SOURCE,
9+
RELATIVE_TREE_POSITIONS,
10+
} from 'shared/data/constants';
611
import { INDEXEDDB_RESOURCES } from 'shared/data/registry';
712

813
/**
@@ -61,15 +66,9 @@ export class ChangeTracker {
6166
}
6267

6368
// Grab the most recent change in the changes table, if it exists, which it might not
64-
// if everything has been synced and applied, otherwise check the session for its max rev
65-
const [mostRecentChange, session] = await Promise.all([
66-
db[CHANGES_TABLE].orderBy('rev').last(),
67-
Session.getSession(),
68-
]);
69-
70-
this._startingRev = mostRecentChange
71-
? mostRecentChange.rev
72-
: session.max_rev[Session.currentChannelId];
69+
const mostRecentChange = await db[CHANGES_TABLE].orderBy('rev').last();
70+
71+
this._startingRev = mostRecentChange ? mostRecentChange.rev : null;
7372
}
7473

7574
/**
@@ -78,10 +77,16 @@ export class ChangeTracker {
7877
*/
7978
async stop() {
8079
// Collect the changes
81-
const changes = db[CHANGES_TABLE].where('rev')
82-
.above(this._startingRev)
83-
.filter(change => !change.source.match(IGNORED_SOURCE));
84-
this._changes = await changes.sortBy('rev');
80+
let changes = db[CHANGES_TABLE];
81+
82+
// If we had a starting rev, filter to only those changes added since
83+
if (this._startingRev) {
84+
changes = changes.where('rev').above(this._startingRev);
85+
}
86+
87+
this._changes = await changes
88+
.filter(change => !change.source.match(IGNORED_SOURCE))
89+
.sortBy('rev');
8590
}
8691

8792
/**
@@ -131,7 +136,7 @@ export class ChangeTracker {
131136
}
132137
return Promise.resolve();
133138
}
134-
return resource.transaction({}, () => {
139+
return resource.transaction({}, CHANGES_TABLE, () => {
135140
// If we had created something, we'll delete it
136141
// Special MOVED case here comes from the operation of COPY then MOVE for duplicating
137142
// content nodes, which in this case would be on the Tree table, so we're removing
@@ -151,9 +156,21 @@ export class ChangeTracker {
151156
// If we updated or deleted it, we just want the old stuff back
152157
return resource.table.put(change.oldObj);
153158
} else if (change.type === CHANGE_TYPES.MOVED && change.oldObj) {
154-
// Lastly if this is a MOVE, then this was likely a single operation, so we just roll
155-
// it back
156-
return resource.table.put(change.oldObj);
159+
// Lastly if this is a MOVE, we generate a reverse move back to its old position
160+
const { parent, lft } = change.oldObj;
161+
162+
// Collect the affected node's siblings prior to the change
163+
return resource.where({ parent }, false).then(siblings => {
164+
// Search the siblings ordered by `lft` to find the first a sibling
165+
// where we should move the node, positioned before that sibling
166+
let relativeSibling = sortBy(siblings, 'lft').find(sibling => sibling.lft >= lft);
167+
if (relativeSibling) {
168+
return resource.move(change.key, relativeSibling.id, RELATIVE_TREE_POSITIONS.LEFT);
169+
}
170+
171+
// this handles if there were no siblings OR if the deleted node was at the end
172+
return resource.move(change.key, parent, RELATIVE_TREE_POSITIONS.LAST_CHILD);
173+
});
157174
} else {
158175
if (process.env.NODE_ENV !== 'production') {
159176
/* eslint-disable no-console */

0 commit comments

Comments
 (0)