diff --git a/public/javascripts/tree_changes.js b/public/javascripts/tree_changes.js index 7cbb1952e..4c94df2b0 100644 --- a/public/javascripts/tree_changes.js +++ b/public/javascripts/tree_changes.js @@ -27,12 +27,17 @@ const treeChanges = (function() { // beware that first arg is noteId and second is noteTreeId! async function cloneNoteAfter(noteId, afterNoteTreeId) { - await $.ajax({ + const resp = await $.ajax({ url: baseApiUrl + 'notes/' + noteId + '/cloneAfter/' + afterNoteTreeId, type: 'PUT', error: () => showError("Error cloning note.") }); + if (!resp.success) { + alert(resp.message); + return; + } + await noteTree.reload(); } @@ -54,12 +59,17 @@ const treeChanges = (function() { } async function cloneNoteTo(childNoteId, parentNoteId) { - await $.ajax({ + const resp = await $.ajax({ url: baseApiUrl + 'notes/' + childNoteId + '/cloneTo/' + parentNoteId, type: 'PUT', error: () => showError("Error cloning note.") }); + if (!resp.success) { + alert(resp.message); + return; + } + await noteTree.reload(); } diff --git a/routes/api/notes_move.js b/routes/api/notes_move.js index 0cffbc8c5..33c550716 100644 --- a/routes/api/notes_move.js +++ b/routes/api/notes_move.js @@ -92,31 +92,37 @@ router.put('/:childNoteId/cloneTo/:parentNoteId', auth.checkApiAuth, async (req, const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND note_pid = ?', [childNoteId, parentNoteId]); - if (!existing) { - 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 noteTreeId = utils.newNoteTreeId(); - - await sql.doInTransaction(async () => { - await sync_table.addNoteTreeSync(noteTreeId); - - await sql.insert("notes_tree", { - 'note_tree_id': noteTreeId, - 'note_id': childNoteId, - 'note_pid': parentNoteId, - 'note_pos': newNotePos, - 'is_expanded': 0, - 'date_modified': utils.nowTimestamp(), - 'is_deleted': 0 - }); + if (existing && !existing.is_deleted) { + res.send({ + success: false, + message: 'This note already exists in target parent note.' }); - } - else if (existing && existing.is_deleted) { - await sql.execute("UPDATE notes_tree SET is_deleted = 0 WHERE note_tree_id = ?", [existing.note_tree_id]); + + return; } - res.send({}); + 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; + + await sql.doInTransaction(async () => { + const noteTree = { + 'note_tree_id': utils.newNoteTreeId(), + 'note_id': childNoteId, + 'note_pid': parentNoteId, + 'note_pos': newNotePos, + 'is_expanded': 0, + 'date_modified': utils.nowTimestamp(), + 'is_deleted': 0 + }; + + await sql.replace("notes_tree", noteTree); + + await sync_table.addNoteTreeSync(noteTree.note_tree_id); + + res.send({ + success: true + }); + }); }); router.put('/:noteId/cloneAfter/:afterNoteTreeId', async (req, res, next) => { @@ -125,34 +131,47 @@ router.put('/:noteId/cloneAfter/:afterNoteTreeId', async (req, res, next) => { const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); - if (afterNote) { - await sql.doInTransaction(async () => { - // 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", - [afterNote.note_pid, afterNote.note_pos]); + if (!afterNote) { + res.status(500).send("After note " + afterNoteTreeId + " doesn't exist."); + return; + } - const noteTreeId = utils.newNoteTreeId(); + const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND note_pid = ?', [noteId, afterNote.note_pid]); - await sql.insert("notes_tree", { - 'note_tree_id': noteTreeId, - 'note_id': noteId, - 'note_pid': afterNote.note_pid, - 'note_pos': afterNote.note_pos + 1, - 'is_expanded': 0, - 'date_modified': utils.nowTimestamp(), - 'is_deleted': 0 - }); - - 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); + if (existing && !existing.is_deleted) { + res.send({ + success: false, + message: 'This note already exists in target parent note.' }); - res.send({}); - } - else { - res.status(500).send("After note " + afterNoteTreeId + " doesn't exist."); + return; } + + await sql.doInTransaction(async () => { + // 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", + [afterNote.note_pid, afterNote.note_pos]); + + const noteTree = { + 'note_tree_id': utils.newNoteTreeId(), + 'note_id': noteId, + 'note_pid': afterNote.note_pid, + 'note_pos': afterNote.note_pos + 1, + 'is_expanded': 0, + 'date_modified': utils.nowTimestamp(), + 'is_deleted': 0 + }; + + await sql.replace("notes_tree", noteTree); + + await sync_table.addNoteTreeSync(noteTree.note_tree_id); + await sync_table.addNoteReorderingSync(afterNote.note_pid); + await sql.addAudit(audit_category.CHANGE_POSITION, utils.browserId(req), afterNote.note_pid); + + res.send({ + success: true + }); + }); }); router.put('/:noteTreeId/expanded/:expanded', async (req, res, next) => {