From e99208772080afb5b1269dd48665eb85fdefc0a0 Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 19 Nov 2017 18:16:50 -0500 Subject: [PATCH] recovery if note path changes, plus change of note path after note move --- public/javascripts/note_tree.js | 29 +++++++++--- public/javascripts/tree_changes.js | 18 ++++++-- routes/api/notes_move.js | 72 +++++++++++++++--------------- services/notes.js | 10 ++--- 4 files changed, 75 insertions(+), 54 deletions(-) diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js index 9441b3a93..7dc9e101b 100644 --- a/public/javascripts/note_tree.js +++ b/public/javascripts/note_tree.js @@ -139,15 +139,24 @@ const noteTree = (function() { const effectivePath = []; let childNoteId = null; + let i = 0; + + while (true) { + const parentNoteId = i < path.length ? path[i] : null; + i++; - for (const parentNoteId of path) { if (childNoteId !== null) { const parents = childToParents[childNoteId]; - if (!parents.includes(parentNoteId)) { + if (parentNoteId === null || !parents.includes(parentNoteId)) { console.log("Did not find parent " + parentNoteId + " for child " + childNoteId); if (parents.length > 0) { + if (parents[0] === 'root') { + console.log("Reached root."); + break; + } + childNoteId = parents[0]; effectivePath.push(childNoteId); @@ -196,6 +205,14 @@ const noteTree = (function() { }); } + function setCurrentNotePathToHash(node) { + const currentNotePath = treeUtils.getNotePath(node); + + document.location.hash = currentNotePath; + + recentNotes.addRecentNote(currentNotePath); + } + function initFancyTree(noteTree) { const keybindings = { "insert": node => { @@ -246,11 +263,8 @@ const noteTree = (function() { scrollParent: $("#tree"), activate: (event, data) => { const node = data.node.data; - const currentNotePath = treeUtils.getNotePath(data.node); - document.location.hash = currentNotePath; - - recentNotes.addRecentNote(currentNotePath); + setCurrentNotePathToHash(data.node); noteEditor.switchToNote(node.note_id); }, @@ -471,6 +485,7 @@ const noteTree = (function() { getCurrentNoteTreeId, activateNode, getCurrentNotePath, - getNoteTitle + getNoteTitle, + setCurrentNotePathToHash }; })(); \ No newline at end of file diff --git a/public/javascripts/tree_changes.js b/public/javascripts/tree_changes.js index b5073c56b..07264dac3 100644 --- a/public/javascripts/tree_changes.js +++ b/public/javascripts/tree_changes.js @@ -3,29 +3,33 @@ const treeChanges = (function() { function moveBeforeNode(node, beforeNode) { $.ajax({ - url: baseApiUrl + 'notes/' + node.key + '/moveBefore/' + beforeNode.key, + url: baseApiUrl + 'notes/' + node.data.note_tree_id + '/moveBefore/' + beforeNode.data.note_tree_id, type: 'PUT', contentType: "application/json", success: () => { node.moveTo(beforeNode, 'before'); + + noteTree.setCurrentNotePathToHash(node); } }); } function moveAfterNode(node, afterNode) { $.ajax({ - url: baseApiUrl + 'notes/' + node.key + '/moveAfter/' + afterNode.key, + url: baseApiUrl + 'notes/' + node.data.note_tree_id + '/moveAfter/' + afterNode.data.note_tree_id, type: 'PUT', contentType: "application/json", success: () => { node.moveTo(afterNode, 'after'); + + noteTree.setCurrentNotePathToHash(node); } }); } function moveToNode(node, toNode) { $.ajax({ - url: baseApiUrl + 'notes/' + node.key + '/moveTo/' + toNode.key, + url: baseApiUrl + 'notes/' + node.data.note_tree_id + '/moveTo/' + toNode.data.note_id, type: 'PUT', contentType: "application/json", success: () => { @@ -35,6 +39,8 @@ const treeChanges = (function() { toNode.folder = true; toNode.renderTitle(); + + noteTree.setCurrentNotePathToHash(node); } }); } @@ -63,6 +69,8 @@ const treeChanges = (function() { // activate next element after this one is deleted so we don't lose focus next.setActive(); + + noteTree.setCurrentNotePathToHash(next); } }); } @@ -71,7 +79,7 @@ const treeChanges = (function() { function moveNodeUp(node) { if (node.getParent() !== null) { $.ajax({ - url: baseApiUrl + 'notes/' + node.key + '/moveAfter/' + node.getParent().key, + url: baseApiUrl + 'notes/' + node.data.note_tree_id + '/moveAfter/' + node.getParent().data.note_tree_id, type: 'PUT', contentType: "application/json", success: () => { @@ -81,6 +89,8 @@ const treeChanges = (function() { } node.moveTo(node.getParent(), 'after'); + + noteTree.setCurrentNotePathToHash(node); } }); } diff --git a/routes/api/notes_move.js b/routes/api/notes_move.js index ec0e9688a..3a8044f6d 100644 --- a/routes/api/notes_move.js +++ b/routes/api/notes_move.js @@ -8,37 +8,31 @@ const audit_category = require('../../services/audit_category'); const auth = require('../../services/auth'); const sync_table = require('../../services/sync_table'); -router.put('/:noteId/moveTo/:parentId', auth.checkApiAuth, async (req, res, next) => { - let noteId = req.params.noteId; - let parentId = req.params.parentId; +router.put('/:noteTreeId/moveTo/:parentNoteId', auth.checkApiAuth, async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; + const parentNoteId = req.params.parentNoteId; - const row = await sql.getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ? and is_deleted = 0', [parentId]); - const maxNotePos = row.max_note_pos; - let newNotePos = 0; - - if (maxNotePos === null) // no children yet - newNotePos = 0; - else - newNotePos = maxNotePos + 1; + const maxNotePos = await sql.getSingleValue('select max(note_pos) from notes_tree where note_pid = ? and is_deleted = 0', [parentNoteId]); + const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; const now = utils.nowTimestamp(); await sql.doInTransaction(async () => { - await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_id = ?", - [parentId, newNotePos, now, noteId]); + await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_tree_id = ?", + [parentNoteId, newNotePos, now, noteTreeId]); - await sync_table.addNoteTreeSync(noteId); - await sql.addAudit(audit_category.CHANGE_PARENT, utils.browserId(req), noteId, null, parentId); + await sync_table.addNoteTreeSync(noteTreeId); + await sql.addAudit(audit_category.CHANGE_PARENT, utils.browserId(req), null, null, parentNoteId); }); res.send({}); }); -router.put('/:noteId/moveBefore/:beforeNoteId', async (req, res, next) => { - let noteId = req.params.noteId; - let beforeNoteId = req.params.beforeNoteId; +router.put('/:noteTreeId/moveBefore/:beforeNoteTreeId', async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; + const beforeNoteTreeId = req.params.beforeNoteTreeId; - const beforeNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [beforeNoteId]); + const beforeNote = await sql.getSingleResult("select * from notes_tree where note_tree_id = ?", [beforeNoteTreeId]); if (beforeNote) { await sql.doInTransaction(async () => { @@ -48,23 +42,26 @@ router.put('/:noteId/moveBefore/:beforeNoteId', async (req, res, next) => { const now = utils.nowTimestamp(); - await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_id = ?", - [beforeNote.note_pid, beforeNote.note_pos, now, noteId]); + await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_tree_id = ?", + [beforeNote.note_pid, beforeNote.note_pos, now, noteTreeId]); - await sync_table.addNoteTreeSync(noteId); + await sync_table.addNoteTreeSync(noteTreeId); await sync_table.addNoteReorderingSync(beforeNote.note_pid); await sql.addAudit(audit_category.CHANGE_POSITION, utils.browserId(req), beforeNote.note_pid); }); - } - res.send({}); + res.send({}); + } + else { + res.status(500).send("Before note " + beforeNoteTreeId + " doesn't exist."); + } }); -router.put('/:noteId/moveAfter/:afterNoteId', async (req, res, next) => { - let noteId = req.params.noteId; - let afterNoteId = req.params.afterNoteId; +router.put('/:noteTreeId/moveAfter/:afterNoteTreeId', async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; + const afterNoteTreeId = req.params.afterNoteTreeId; - const afterNote = await sql.getSingleResult("select * from notes_tree where note_id = ?", [afterNoteId]); + const afterNote = await sql.getSingleResult("select * from notes_tree where note_tree_id = ?", [afterNoteTreeId]); if (afterNote) { await sql.doInTransaction(async () => { @@ -74,24 +71,27 @@ router.put('/:noteId/moveAfter/:afterNoteId', async (req, res, next) => { const now = utils.nowTimestamp(); - await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_id = ?", - [afterNote.note_pid, afterNote.note_pos + 1, now, noteId]); + await sql.execute("update notes_tree set note_pid = ?, note_pos = ?, date_modified = ? where note_tree_id = ?", + [afterNote.note_pid, afterNote.note_pos + 1, now, noteTreeId]); - await sync_table.addNoteTreeSync(noteId); + await sync_table.addNoteTreeSync(noteTreeId); await sync_table.addNoteReorderingSync(afterNote.note_pid); await sql.addAudit(audit_category.CHANGE_POSITION, utils.browserId(req), afterNote.note_pid); }); - } - res.send({}); + res.send({}); + } + else { + res.status(500).send("After note " + afterNoteTreeId + " doesn't exist."); + } }); -router.put('/:noteId/expanded/:expanded', async (req, res, next) => { - const noteId = req.params.noteId; +router.put('/:noteTreeId/expanded/:expanded', async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; const expanded = req.params.expanded; await sql.doInTransaction(async () => { - await sql.execute("update notes_tree set is_expanded = ? where note_id = ?", [expanded, noteId]); + await sql.execute("update notes_tree set is_expanded = ? where note_tree_id = ?", [expanded, noteTreeId]); }); res.send({}); diff --git a/services/notes.js b/services/notes.js index 6bb372c5e..26cc454b1 100644 --- a/services/notes.js +++ b/services/notes.js @@ -15,19 +15,15 @@ async function createNewNote(parentNoteId, note, browserId) { if (note.target === 'into') { const maxNotePos = await sql.getSingleValue('select max(note_pos) from notes_tree where note_pid = ? and is_deleted = 0', [parentNoteId]); - if (maxNotePos === null) // no children yet - newNotePos = 0; - else - newNotePos = maxNotePos + 1 + newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; } else if (note.target === 'after') { const afterNote = await sql.getSingleResult('select note_pos from notes_tree where note_id = ?', [note.target_note_id]); newNotePos = afterNote.note_pos + 1; - const now = utils.nowTimestamp(); - - await sql.execute('update notes_tree set note_pos = note_pos + 1, date_modified = ? where note_pid = ? and note_pos > ? and is_deleted = 0', [now, parentNoteId, afterNote['note_pos']]); + await sql.execute('update notes_tree set note_pos = note_pos + 1, date_modified = ? where note_pid = ? and note_pos > ? and is_deleted = 0', + [utils.nowTimestamp(), parentNoteId, afterNote.note_pos]); } else { throw new Error('Unknown target: ' + note.target);