mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
proper syncing of note positions
This commit is contained in:
parent
c3d776ae13
commit
a7f95e95e9
@ -40,16 +40,17 @@ router.put('/:noteId/moveBefore/:beforeNoteId', async (req, res, next) => {
|
|||||||
const beforeNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [beforeNoteId]);
|
const beforeNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [beforeNoteId]);
|
||||||
|
|
||||||
if (beforeNote) {
|
if (beforeNote) {
|
||||||
const now = utils.nowTimestamp();
|
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
await sql.execute("update notes_tree set note_pos = note_pos + 1, date_modified = ? where note_id = ?", [now, beforeNoteId]);
|
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||||
|
await sql.execute("update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos >= ? and is_deleted = 0",
|
||||||
|
[beforeNote['note_pid'], beforeNote['note_pos']]);
|
||||||
|
|
||||||
await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_id = ?",
|
await sql.execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?",
|
||||||
[beforeNote['note_pid'], beforeNote['note_pos'], now, noteId]);
|
[beforeNote['note_pid'], beforeNote['note_pos'], noteId]);
|
||||||
|
|
||||||
await sql.addNoteTreeSync(noteId);
|
await sql.addNoteTreeSync(noteId);
|
||||||
await sql.addAudit(audit_category.CHANGE_POSITION, req, noteId);
|
await sql.addNoteReorderingSync(beforeNote['note_pid']);
|
||||||
|
await sql.addAudit(audit_category.CHANGE_POSITION, req, beforeNote['note_pid']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,17 +64,17 @@ router.put('/:noteId/moveAfter/:afterNoteId', async (req, res, next) => {
|
|||||||
const afterNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [afterNoteId]);
|
const afterNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [afterNoteId]);
|
||||||
|
|
||||||
if (afterNote) {
|
if (afterNote) {
|
||||||
const now = utils.nowTimestamp();
|
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
await sql.execute("update notes_tree set note_pos = note_pos + 1, date_modified = ? where note_pid = ? and note_pos > ? and is_deleted = 0",
|
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||||
[now, afterNote['note_pid'], afterNote['note_pos']]);
|
await sql.execute("update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ? and is_deleted = 0",
|
||||||
|
[afterNote['note_pid'], afterNote['note_pos']]);
|
||||||
|
|
||||||
await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_id = ?",
|
await sql.execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?",
|
||||||
[afterNote['note_pid'], afterNote['note_pos'] + 1, now, noteId]);
|
[afterNote['note_pid'], afterNote['note_pos'] + 1, noteId]);
|
||||||
|
|
||||||
await sql.addNoteTreeSync(noteId);
|
await sql.addNoteTreeSync(noteId);
|
||||||
await sql.addAudit(audit_category.CHANGE_POSITION, req, noteId);
|
await sql.addNoteReorderingSync(afterNote['note_pid']);
|
||||||
|
await sql.addAudit(audit_category.CHANGE_POSITION, req, afterNote['note_pid']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +87,8 @@ router.put('/:noteId/expanded/:expanded', async (req, res, next) => {
|
|||||||
const now = utils.nowTimestamp();
|
const now = utils.nowTimestamp();
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
await sql.execute("update notes_tree set is_expanded = ?, date_modified = ? where note_id = ?", [expanded, now, noteId]);
|
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||||
|
await sql.execute("update notes_tree set is_expanded = ? where note_id = ?", [expanded, noteId]);
|
||||||
|
|
||||||
await sql.addNoteTreeSync(noteId);
|
await sql.addNoteTreeSync(noteId);
|
||||||
await sql.addAudit(audit_category.CHANGE_EXPANDED, req, noteId, null, expanded);
|
await sql.addAudit(audit_category.CHANGE_EXPANDED, req, noteId, null, expanded);
|
||||||
|
@ -55,6 +55,15 @@ router.get('/options/:optName', auth.checkApiAuth, async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/notes_reordering/:noteParentId', auth.checkApiAuth, async (req, res, next) => {
|
||||||
|
const noteParentId = req.params.noteParentId;
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
note_pid: noteParentId,
|
||||||
|
ordering: await sql.getMap("SELECT note_id, note_pos FROM notes_tree WHERE note_pid = ?", [noteParentId])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.put('/notes', auth.checkApiAuth, async (req, res, next) => {
|
router.put('/notes', auth.checkApiAuth, async (req, res, next) => {
|
||||||
await sync.updateNote(req.body.entity, req.body.links, req.body.sourceId);
|
await sync.updateNote(req.body.entity, req.body.links, req.body.sourceId);
|
||||||
|
|
||||||
@ -73,6 +82,12 @@ router.put('/notes_history', auth.checkApiAuth, async (req, res, next) => {
|
|||||||
res.send({});
|
res.send({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.put('/notes_reordering', auth.checkApiAuth, async (req, res, next) => {
|
||||||
|
await sync.updateNoteReordering(req.body.entity, req.body.sourceId);
|
||||||
|
|
||||||
|
res.send({});
|
||||||
|
});
|
||||||
|
|
||||||
router.put('/options', auth.checkApiAuth, async (req, res, next) => {
|
router.put('/options', auth.checkApiAuth, async (req, res, next) => {
|
||||||
await sync.updateOptions(req.body.entity, req.body.sourceId);
|
await sync.updateOptions(req.body.entity, req.body.sourceId);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
UPDATE_CONTENT: 'CONTENT',
|
UPDATE_CONTENT: 'CONTENT',
|
||||||
UPDATE_TITLE: 'TITLE',
|
UPDATE_TITLE: 'TITLE',
|
||||||
|
// associated noteId is parent of notes where position changes happened
|
||||||
CHANGE_POSITION: 'POSITION',
|
CHANGE_POSITION: 'POSITION',
|
||||||
CHANGE_EXPANDED: 'EXPANDED',
|
CHANGE_EXPANDED: 'EXPANDED',
|
||||||
CREATE_NOTE: 'CREATE',
|
CREATE_NOTE: 'CREATE',
|
||||||
|
@ -62,6 +62,19 @@ async function getResults(query, params = []) {
|
|||||||
return await wrap(async () => db.all(query, ...params));
|
return await wrap(async () => db.all(query, ...params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getMap(query, params = []) {
|
||||||
|
const map = {};
|
||||||
|
const results = await getResults(query, params);
|
||||||
|
|
||||||
|
for (const row of results) {
|
||||||
|
const keys = Object.keys(row);
|
||||||
|
|
||||||
|
map[row[keys[0]]] = row[keys[1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
async function getFlattenedResults(key, query, params = []) {
|
async function getFlattenedResults(key, query, params = []) {
|
||||||
const list = [];
|
const list = [];
|
||||||
const result = await getResults(query, params);
|
const result = await getResults(query, params);
|
||||||
@ -123,6 +136,10 @@ async function addNoteTreeSync(noteId, sourceId) {
|
|||||||
await addEntitySync("notes_tree", noteId, sourceId)
|
await addEntitySync("notes_tree", noteId, sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addNoteReorderingSync(noteId, sourceId) {
|
||||||
|
await addEntitySync("notes_reordering", noteId, sourceId)
|
||||||
|
}
|
||||||
|
|
||||||
async function addNoteHistorySync(noteHistoryId, sourceId) {
|
async function addNoteHistorySync(noteHistoryId, sourceId) {
|
||||||
await addEntitySync("notes_history", noteHistoryId, sourceId);
|
await addEntitySync("notes_history", noteHistoryId, sourceId);
|
||||||
}
|
}
|
||||||
@ -180,6 +197,7 @@ module.exports = {
|
|||||||
getSingleResult,
|
getSingleResult,
|
||||||
getSingleResultOrNull,
|
getSingleResultOrNull,
|
||||||
getResults,
|
getResults,
|
||||||
|
getMap,
|
||||||
getFlattenedResults,
|
getFlattenedResults,
|
||||||
execute,
|
execute,
|
||||||
executeScript,
|
executeScript,
|
||||||
@ -190,6 +208,7 @@ module.exports = {
|
|||||||
doInTransaction,
|
doInTransaction,
|
||||||
addNoteSync,
|
addNoteSync,
|
||||||
addNoteTreeSync,
|
addNoteTreeSync,
|
||||||
|
addNoteReorderingSync,
|
||||||
addNoteHistorySync,
|
addNoteHistorySync,
|
||||||
addOptionsSync
|
addOptionsSync
|
||||||
};
|
};
|
@ -60,6 +60,9 @@ async function pullSync(syncContext, syncLog) {
|
|||||||
else if (sync.entity_name === 'notes_history') {
|
else if (sync.entity_name === 'notes_history') {
|
||||||
await updateNoteHistory(resp, syncContext.sourceId, syncLog);
|
await updateNoteHistory(resp, syncContext.sourceId, syncLog);
|
||||||
}
|
}
|
||||||
|
else if (sync.entity_name === 'notes_reordering') {
|
||||||
|
await updateNoteReordering(resp, syncContext.sourceId, syncLog);
|
||||||
|
}
|
||||||
else if (sync.entity_name === 'options') {
|
else if (sync.entity_name === 'options') {
|
||||||
await updateOptions(resp, syncContext.sourceId, syncLog);
|
await updateOptions(resp, syncContext.sourceId, syncLog);
|
||||||
}
|
}
|
||||||
@ -110,6 +113,12 @@ async function readAndPushEntity(sync, syncLog, syncContext) {
|
|||||||
else if (sync.entity_name === 'notes_history') {
|
else if (sync.entity_name === 'notes_history') {
|
||||||
entity = await sql.getSingleResult('SELECT * FROM notes_history WHERE note_history_id = ?', [sync.entity_id]);
|
entity = await sql.getSingleResult('SELECT * FROM notes_history WHERE note_history_id = ?', [sync.entity_id]);
|
||||||
}
|
}
|
||||||
|
else if (sync.entity_name === 'notes_reordering') {
|
||||||
|
entity = {
|
||||||
|
note_pid: sync.entity_id,
|
||||||
|
ordering: await sql.getMap('SELECT note_id, note_pos FROM notes_tree WHERE note_pid = ?', [sync.entity_id])
|
||||||
|
};
|
||||||
|
}
|
||||||
else if (sync.entity_name === 'options') {
|
else if (sync.entity_name === 'options') {
|
||||||
entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]);
|
entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]);
|
||||||
}
|
}
|
||||||
@ -306,6 +315,17 @@ async function updateNoteHistory(entity, sourceId, syncLog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateNoteReordering(entity, sourceId, syncLog) {
|
||||||
|
await sql.doInTransaction(async () => {
|
||||||
|
Object.keys(entity.ordering).forEach(async key => {
|
||||||
|
await sql.execute("UPDATE notes_tree SET note_pos = ? WHERE note_id = ?", [entity.ordering[key], key]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await sql.addNoteReorderingSync(entity.note_pid, sourceId);
|
||||||
|
await sql.addSyncAudit(audit_category.CHANGE_POSITION, sourceId, entity.note_pid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function updateOptions(entity, sourceId, syncLog) {
|
async function updateOptions(entity, sourceId, syncLog) {
|
||||||
if (!options.SYNCED_OPTIONS.includes(entity.opt_name)) {
|
if (!options.SYNCED_OPTIONS.includes(entity.opt_name)) {
|
||||||
return;
|
return;
|
||||||
@ -344,6 +364,7 @@ module.exports = {
|
|||||||
updateNote,
|
updateNote,
|
||||||
updateNoteTree,
|
updateNoteTree,
|
||||||
updateNoteHistory,
|
updateNoteHistory,
|
||||||
|
updateNoteReordering,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
isSyncSetup
|
isSyncSetup
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user