Skip to content

Commit 0c00756

Browse files
committed
fixes for invalid operations on root note
1 parent bfa2b5f commit 0c00756

File tree

10 files changed

+51
-9
lines changed

10 files changed

+51
-9
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
update branches set parentNoteId = 'none' where branchId = 'root'

src/public/javascripts/services/branches.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import infoService from "./info.js";
55
import treeCache from "./tree_cache.js";
66

77
async function moveBeforeNode(nodesToMove, beforeNode) {
8+
nodesToMove = filterRootNote(nodesToMove);
9+
10+
if (beforeNode.data.noteId === 'root') {
11+
alert('Cannot move notes before root note.');
12+
return;
13+
}
14+
815
for (const nodeToMove of nodesToMove) {
916
const resp = await server.put('branches/' + nodeToMove.data.branchId + '/move-before/' + beforeNode.data.branchId);
1017

@@ -18,6 +25,13 @@ async function moveBeforeNode(nodesToMove, beforeNode) {
1825
}
1926

2027
async function moveAfterNode(nodesToMove, afterNode) {
28+
nodesToMove = filterRootNote(nodesToMove);
29+
30+
if (afterNode.data.noteId === 'root') {
31+
alert('Cannot move notes after root note.');
32+
return;
33+
}
34+
2135
nodesToMove.reverse(); // need to reverse to keep the note order
2236

2337
for (const nodeToMove of nodesToMove) {
@@ -33,6 +47,8 @@ async function moveAfterNode(nodesToMove, afterNode) {
3347
}
3448

3549
async function moveToNode(nodesToMove, toNode) {
50+
nodesToMove = filterRootNote(nodesToMove);
51+
3652
for (const nodeToMove of nodesToMove) {
3753
const resp = await server.put('branches/' + nodeToMove.data.branchId + '/move-to/' + toNode.data.noteId);
3854

@@ -58,8 +74,13 @@ async function moveToNode(nodesToMove, toNode) {
5874
}
5975
}
6076

77+
function filterRootNote(nodes) {
78+
// some operations are not possible on root notes
79+
return nodes.filter(node => node.data.noteId !== 'root');
80+
}
81+
6182
async function deleteNodes(nodes) {
62-
nodes = nodes.filter(node => node.data.noteId !== 'root');
83+
nodes = filterRootNote(nodes);
6384

6485
if (nodes.length === 0 || !confirm('Are you sure you want to delete select note(s) and all the sub-notes?')) {
6586
return;
@@ -94,7 +115,7 @@ async function deleteNodes(nodes) {
94115
}
95116

96117
async function moveNodeUpInHierarchy(node) {
97-
if (utils.isTopLevelNode(node)) {
118+
if (utils.isRootNode(node) || utils.isTopLevelNode(node)) {
98119
return;
99120
}
100121

src/public/javascripts/services/drag_and_drop.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const dragAndDropSetup = {
1414
preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
1515

1616
dragStart: (node, data) => {
17+
if (node.data.noteId === 'root') {
18+
return false;
19+
}
20+
1721
// This function MUST be defined to enable dragging for the tree.
1822
// Return false to cancel dragging of node.
1923
return true;

src/public/javascripts/services/tree_keybindings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ const keyBindings = {
105105
return false;
106106
},
107107
"backspace": node => {
108-
if (!utils.isTopLevelNode(node)) {
108+
if (!utils.isRootNode(node)) {
109109
node.getParent().setActive().then(treeService.clearSelectedNodes);
110110
}
111111
},

src/public/javascripts/services/tree_utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import treeCache from "./tree_cache.js";
44
const $tree = $("#tree");
55

66
function getParentProtectedStatus(node) {
7-
return utils.isTopLevelNode(node) ? 0 : node.getParent().data.isProtected;
7+
return utils.isRootNode(node) ? 0 : node.getParent().data.isProtected;
88
}
99

1010
function getNodeByKey(key) {
@@ -32,6 +32,8 @@ function getNotePath(node) {
3232
node = node.getParent();
3333
}
3434

35+
path.push('root');
36+
3537
return path.reverse().join("/");
3638
}
3739

src/public/javascripts/services/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function isTopLevelNode(node) {
5959
}
6060

6161
function isRootNode(node) {
62-
return node.key === "root_1";
62+
return node.data.noteId === "root";
6363
}
6464

6565
function escapeHtml(str) {

src/routes/api/branches.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async function moveBranchToParent(req) {
2121
const validationResult = await tree.validateParentChild(parentNoteId, noteToMove.noteId, branchId);
2222

2323
if (!validationResult.success) {
24-
return [400, validationResult];
24+
return [200, validationResult];
2525
}
2626

2727
const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
@@ -45,7 +45,7 @@ async function moveBranchBeforeNote(req) {
4545
const validationResult = await tree.validateParentChild(beforeNote.parentNoteId, noteToMove.noteId, branchId);
4646

4747
if (!validationResult.success) {
48-
return [400, validationResult];
48+
return [200, validationResult];
4949
}
5050

5151
// we don't change dateModified so other changes are prioritized in case of conflict
@@ -73,7 +73,7 @@ async function moveBranchAfterNote(req) {
7373
const validationResult = await tree.validateParentChild(afterNote.parentNoteId, noteToMove.noteId, branchId);
7474

7575
if (!validationResult.success) {
76-
return [400, validationResult];
76+
return [200, validationResult];
7777
}
7878

7979
// we don't change dateModified so other changes are prioritized in case of conflict

src/services/app_info.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const build = require('./build');
44
const packageJson = require('../../package');
55

6-
const APP_DB_VERSION = 113;
6+
const APP_DB_VERSION = 114;
77
const SYNC_VERSION = 1;
88

99
module.exports = {

src/services/consistency_checks.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ async function checkTreeCycles(errorList) {
3737
return;
3838
}
3939

40+
if (!childToParents[noteId] || childToParents[noteId].length === 0) {
41+
errorList.push(`No parents found for noteId=${noteId}`);
42+
return;
43+
}
44+
4045
for (const parentNoteId of childToParents[noteId]) {
4146
if (path.includes(parentNoteId)) {
4247
errorList.push(`Tree cycle detected at parent-child relationship: ${parentNoteId} - ${noteId}, whole path: ${path}`);

src/services/tree.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ const syncTableService = require('./sync_table');
77
const protectedSessionService = require('./protected_session');
88

99
async function validateParentChild(parentNoteId, childNoteId, branchId = null) {
10+
if (childNoteId === 'root') {
11+
return { success: false, message: 'Cannot move root note.'};
12+
}
13+
14+
if (parentNoteId === 'none') {
15+
// this shouldn't happen
16+
return { success: false, message: 'Cannot move anything into root parent.' };
17+
}
18+
1019
const existing = await getExistingBranch(parentNoteId, childNoteId);
1120

1221
if (existing && (branchId === null || existing.branchId !== branchId)) {

0 commit comments

Comments
 (0)