diff --git a/src/public/javascripts/services/branches.js b/src/public/javascripts/services/branches.js
index dda7097cd..adad473bd 100644
--- a/src/public/javascripts/services/branches.js
+++ b/src/public/javascripts/services/branches.js
@@ -58,6 +58,11 @@ async function moveToNode(nodesToMove, toNode) {
nodesToMove = await filterRootNote(nodesToMove);
for (const nodeToMove of nodesToMove) {
+ if (nodeToMove.data.noteId === await hoistedNoteService.getHoistedNoteId()
+ || nodeToMove.getParent().data.noteType === 'search') {
+ continue;
+ }
+
const resp = await server.put('branches/' + nodeToMove.data.branchId + '/move-to/' + toNode.data.noteId);
if (!resp.success) {
@@ -152,7 +157,9 @@ async function deleteNodes(nodes) {
}
async function moveNodeUpInHierarchy(node) {
- if (await hoistedNoteService.isRootNode(node) || await hoistedNoteService.isTopLevelNode(node)) {
+ if (await hoistedNoteService.isRootNode(node)
+ || await hoistedNoteService.isTopLevelNode(node)
+ || node.getParent().data.noteType === 'search') {
return;
}
diff --git a/src/public/javascripts/services/clipboard.js b/src/public/javascripts/services/clipboard.js
index a13c335ed..ec198bf1c 100644
--- a/src/public/javascripts/services/clipboard.js
+++ b/src/public/javascripts/services/clipboard.js
@@ -2,6 +2,7 @@ import treeUtils from "./tree_utils.js";
import treeChangesService from "./branches.js";
import cloningService from "./cloning.js";
import toastService from "./toast.js";
+import hoistedNoteService from "./hoisted_note.js";
let clipboardIds = [];
let clipboardMode = null;
@@ -66,10 +67,16 @@ function copy(nodes) {
}
function cut(nodes) {
- clipboardIds = nodes.map(node => node.key);
- clipboardMode = 'cut';
+ clipboardIds = nodes
+ .filter(node => node.data.noteId !== hoistedNoteService.getHoistedNoteNoPromise())
+ .filter(node => node.getParent().data.noteType !== 'search')
+ .map(node => node.data.noteId);
- toastService.showMessage("Note(s) have been cut into clipboard.");
+ if (clipboardIds.length > 0) {
+ clipboardMode = 'cut';
+
+ toastService.showMessage("Note(s) have been cut into clipboard.");
+ }
}
function isEmpty() {
diff --git a/src/public/javascripts/services/drag_and_drop.js b/src/public/javascripts/services/drag_and_drop.js
index 2fa1f9087..0b2025e8f 100644
--- a/src/public/javascripts/services/drag_and_drop.js
+++ b/src/public/javascripts/services/drag_and_drop.js
@@ -1,11 +1,13 @@
import treeService from './tree.js';
import treeChangesService from './branches.js';
+import hoistedNoteService from './hoisted_note.js';
const dragAndDropSetup = {
autoExpandMS: 600,
dragStart: (node, data) => {
// don't allow dragging root node
- if (node.data.noteId === 'root') {
+ if (node.data.noteId === hoistedNoteService.getHoistedNoteNoPromise()
+ || node.getParent().data.noteType === 'search') {
return false;
}
@@ -25,6 +27,17 @@ const dragAndDropSetup = {
dragEnter: (node, data) => true, // allow drop on any node
dragOver: (node, data) => true,
dragDrop: async (node, data) => {
+ if ((data.hitMode === 'over' && node.data.noteType === 'search') ||
+ (['after', 'before'].includes(data.hitMode)
+ && (node.data.noteId === hoistedNoteService.getHoistedNoteNoPromise() || node.getParent().data.noteType === 'search'))) {
+
+ const infoDialog = await import('../dialogs/info.js');
+
+ await infoDialog.info("Dropping notes into this location is not allowed.");
+
+ return;
+ }
+
const dataTransfer = data.dataTransfer;
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
diff --git a/src/public/javascripts/services/hoisted_note.js b/src/public/javascripts/services/hoisted_note.js
index e7741baf4..ca5b218b1 100644
--- a/src/public/javascripts/services/hoisted_note.js
+++ b/src/public/javascripts/services/hoisted_note.js
@@ -3,12 +3,16 @@ import server from "./server.js";
import tree from "./tree.js";
import noteDetailService from "./note_detail.js";
-let hoistedNoteId;
+let hoistedNoteId = 'root';
optionsService.waitForOptions().then(options => {
hoistedNoteId = options.get('hoistedNoteId');
});
+function getHoistedNoteNoPromise() {
+ return hoistedNoteId;
+}
+
async function getHoistedNoteId() {
await optionsService.waitForOptions();
@@ -49,6 +53,7 @@ async function isRootNode(node) {
export default {
getHoistedNoteId,
+ getHoistedNoteNoPromise,
setHoistedNoteId,
unhoist,
isTopLevelNode,
diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js
index 370fbb89a..6754136de 100644
--- a/src/public/javascripts/services/tree.js
+++ b/src/public/javascripts/services/tree.js
@@ -676,6 +676,7 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
refKey: branchEntity.noteId,
branchId: branchEntity.branchId,
isProtected: extraOptions.isProtected,
+ type: noteEntity.type,
extraClasses: await treeBuilder.getExtraClasses(noteEntity),
icon: await treeBuilder.getIcon(noteEntity),
folder: extraOptions.type === 'search',
diff --git a/src/public/javascripts/services/tree_builder.js b/src/public/javascripts/services/tree_builder.js
index 8ff5e2ae0..9cfe9b44c 100644
--- a/src/public/javascripts/services/tree_builder.js
+++ b/src/public/javascripts/services/tree_builder.js
@@ -70,6 +70,7 @@ async function prepareNode(branch) {
parentNoteId: branch.parentNoteId,
branchId: branch.branchId,
isProtected: note.isProtected,
+ noteType: note.type,
title: utils.escapeHtml(title),
extraClasses: await getExtraClasses(note),
icon: await getIcon(note),
diff --git a/src/public/javascripts/services/tree_context_menu.js b/src/public/javascripts/services/tree_context_menu.js
index fcace29df..dda3f31d4 100644
--- a/src/public/javascripts/services/tree_context_menu.js
+++ b/src/public/javascripts/services/tree_context_menu.js
@@ -65,7 +65,7 @@ class TreeContextMenu {
{ title: "Copy / clone Ctrl+C", cmd: "copy", uiIcon: "files",
enabled: isNotRoot },
{ title: "Cut Ctrl+X", cmd: "cut", uiIcon: "scissors",
- enabled: isNotRoot },
+ enabled: isNotRoot && !isHoisted && parentNotSearch },
{ title: "Paste into Ctrl+V", cmd: "pasteInto", uiIcon: "clipboard",
enabled: !clipboard.isEmpty() && notSearch && noSelectedNotes },
{ title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard",