diff --git a/public/javascripts/dialogs/edit_tree_prefix.js b/public/javascripts/dialogs/edit_tree_prefix.js
index 21ac6940d..8e40f064b 100644
--- a/public/javascripts/dialogs/edit_tree_prefix.js
+++ b/public/javascripts/dialogs/edit_tree_prefix.js
@@ -6,10 +6,10 @@ const editTreePrefix = (function() {
const treePrefixInputEl = $("#tree-prefix-input");
const noteTitleEl = $('#tree-prefix-note-title');
- function showDialog() {
+ async function showDialog() {
glob.activeDialog = dialogEl;
- dialogEl.dialog({
+ await dialogEl.dialog({
modal: true,
width: 800
});
@@ -36,6 +36,8 @@ const editTreePrefix = (function() {
prefix: prefix
}),
success: () => {
+ currentNode.data.prefix = prefix;
+
const noteTitle = noteTree.getNoteTitle(currentNode.data.note_id);
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js
index 8563d9808..a07101b06 100644
--- a/public/javascripts/note_tree.js
+++ b/public/javascripts/note_tree.js
@@ -346,6 +346,9 @@ const noteTree = (function() {
if (toNode !== null) {
treeChanges.moveToNode(node, toNode);
}
+ },
+ "f2": node => {
+ editTreePrefix.showDialog();
}
};
diff --git a/routes/api/notes.js b/routes/api/notes.js
index 9f0c3d532..d08d5a110 100644
--- a/routes/api/notes.js
+++ b/routes/api/notes.js
@@ -6,6 +6,7 @@ const auth = require('../../services/auth');
const sql = require('../../services/sql');
const utils = require('../../services/utils');
const notes = require('../../services/notes');
+const log = require('../../services/log');
const protected_session = require('../../services/protected_session');
const data_encryption = require('../../services/data_encryption');
const RequestContext = require('../../services/request_context');
@@ -15,6 +16,12 @@ router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => {
const detail = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]);
+ if (!detail) {
+ log.info("Note " + noteId + " has not been found.");
+
+ return res.status(404).send({});
+ }
+
if (detail.is_protected) {
const dataKey = protected_session.getDataKey(req);
diff --git a/routes/api/tree.js b/routes/api/tree.js
index 4a2b90773..85adf4b37 100644
--- a/routes/api/tree.js
+++ b/routes/api/tree.js
@@ -50,10 +50,10 @@ router.put('/:noteId/protectSubTree/:isProtected', auth.checkApiAuth, async (req
router.put('/:noteTreeId/setPrefix', auth.checkApiAuth, async (req, res, next) => {
const noteTreeId = req.params.noteTreeId;
- const prefix = req.body.prefix;
+ const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix;
await sql.doInTransaction(async () => {
- await sql.execute("UPDATE notes_tree SET prefix = ? WHERE note_tree_id = ?", [prefix, noteTreeId]);
+ await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowTimestamp(), noteTreeId]);
await sync_table.addNoteTreeSync(noteTreeId);
});
diff --git a/services/content_hash.js b/services/content_hash.js
index aaac6eb3e..0bf118761 100644
--- a/services/content_hash.js
+++ b/services/content_hash.js
@@ -17,7 +17,7 @@ async function getContentHash() {
"is_deleted FROM notes ORDER BY note_id"));
hash = updateHash(hash, await sql.getResults("SELECT note_tree_id, note_id, note_pid, note_pos, date_modified, " +
- "is_deleted FROM notes_tree ORDER BY note_tree_id"));
+ "is_deleted, prefix FROM notes_tree ORDER BY note_tree_id"));
hash = updateHash(hash, await sql.getResults("SELECT note_history_id, note_id, note_title, note_text, " +
"date_modified_from, date_modified_to FROM notes_history ORDER BY note_history_id"));
diff --git a/services/notes.js b/services/notes.js
index 8223599f8..45bac7e7e 100644
--- a/services/notes.js
+++ b/services/notes.js
@@ -11,24 +11,24 @@ async function createNewNote(parentNoteId, note) {
let newNotePos = 0;
- if (note.target === 'into') {
- const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]);
-
- newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
- }
- else if (note.target === 'after') {
- const afterNote = await sql.getSingleResult('SELECT note_pos FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]);
-
- newNotePos = afterNote.note_pos + 1;
-
- 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);
- }
-
await sql.doInTransaction(async () => {
+ if (note.target === 'into') {
+ const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]);
+
+ newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
+ }
+ else if (note.target === 'after') {
+ const afterNote = await sql.getSingleResult('SELECT note_pos FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]);
+
+ newNotePos = afterNote.note_pos + 1;
+
+ 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);
+ }
+
await sync_table.addNoteTreeSync(noteTreeId);
await sync_table.addNoteSync(noteId);
diff --git a/services/utils.js b/services/utils.js
index 5f35d173c..d0979dc12 100644
--- a/services/utils.js
+++ b/services/utils.js
@@ -66,6 +66,10 @@ function hash(text) {
return crypto.createHash('sha1').update(text).digest('base64');
}
+function isEmptyOrWhitespace(str) {
+ return str === null || str.match(/^ *$/) !== null;
+}
+
module.exports = {
randomSecureToken,
@@ -79,5 +83,6 @@ module.exports = {
hmac,
isElectron,
formatTwoTimestamps,
- hash
+ hash,
+ isEmptyOrWhitespace
};
\ No newline at end of file
diff --git a/views/index.ejs b/views/index.ejs
index e4cb3e51d..a29a5167f 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -326,7 +326,6 @@
-