shortcuts improvements

This commit is contained in:
zadam 2022-11-26 14:57:39 +01:00
parent 6883b71ce7
commit 6a9ac6f90a
9 changed files with 97 additions and 23 deletions

View File

@ -83,8 +83,10 @@ function getNoteTitleArrayForPath(notePathArray) {
throw new Error(`${notePathArray} is not an array.`);
}
if (notePathArray.length === 1 && notePathArray[0] === cls.getHoistedNoteId()) {
return [getNoteTitle(cls.getHoistedNoteId())];
const hoistedNoteId = cls.getHoistedNoteId();
if (notePathArray.length === 1 && notePathArray[0] === hoistedNoteId) {
return [getNoteTitle(hoistedNoteId)];
}
const titles = [];
@ -92,6 +94,9 @@ function getNoteTitleArrayForPath(notePathArray) {
let parentNoteId = 'root';
let hoistedNotePassed = false;
// this is a notePath from outside of hoisted subtree so full title path needs to be returned
const outsideOfHoistedSubtree = !notePathArray.includes(hoistedNoteId);
for (const noteId of notePathArray) {
// start collecting path segment titles only after hoisted note
if (hoistedNotePassed) {
@ -100,7 +105,7 @@ function getNoteTitleArrayForPath(notePathArray) {
titles.push(title);
}
if (noteId === cls.getHoistedNoteId()) {
if (!hoistedNotePassed && (noteId === hoistedNoteId || outsideOfHoistedSubtree)) {
hoistedNotePassed = true;
}

View File

@ -193,9 +193,15 @@ class Branch extends AbstractEntity {
beforeSaving() {
if (this.notePosition === undefined || this.notePosition === null) {
// TODO finding new position can be refactored into becca
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
let maxNotePos = 0;
for (const childBranch of this.parentNote.getChildBranches()) {
if (maxNotePos < childBranch.notePosition && childBranch.branchId !== 'hidden') {
maxNotePos = childBranch.notePosition;
}
}
this.notePosition = maxNotePos + 10;
}
if (!this.isExpanded) {

View File

@ -396,6 +396,10 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
autoExpandMS: 600,
preventLazyParents: false,
dragStart: (node, data) => {
if (['root', 'hidden', 'lb_root', 'lb_availableshortcuts', 'lb_visibleshortcuts'].includes(node.data.noteId)) {
return false;
}
const notes = this.getSelectedOrActiveNodes(node).map(node => ({
noteId: node.data.noteId,
branchId: node.data.branchId,
@ -417,7 +421,19 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
data.dataTransfer.setData("text", JSON.stringify(notes));
return true; // allow dragging to start
},
dragEnter: (node, data) => node.data.noteType !== 'search',
dragEnter: (node, data) => {
console.log(data, node.data.noteType);
if (node.data.noteType === 'search') {
return false;
} else if (node.data.noteId === 'lb_root') {
return false;
} else if (node.data.noteType === 'shortcut') {
return ['before', 'after'];
} else {
return true;
}
},
dragDrop: async (node, data) => {
if ((data.hitMode === 'over' && node.data.noteType === 'search') ||
(['after', 'before'].includes(data.hitMode)

View File

@ -20,8 +20,12 @@ function updateNoteAttribute(req) {
if (body.attributeId) {
attribute = becca.getAttribute(body.attributeId);
if (!attribute) {
return [404, `Attribute '${body.attributeId}' does not exist.`];
}
if (attribute.noteId !== noteId) {
return [400, `Attribute ${body.attributeId} is not owned by ${noteId}`];
return [400, `Attribute '${body.attributeId}' is not owned by ${noteId}`];
}
if (body.type !== attribute.type

View File

@ -73,10 +73,7 @@ function ensureNoteIsPresentInParent(noteId, parentNoteId, prefix) {
const parentNote = becca.getNote(parentNoteId);
if (parentNote.type === 'search') {
return {
success: false,
message: "Can't clone into a search note"
};
return { success: false, message: "Can't clone into a search note" };
}
const validationResult = treeService.validateParentChild(parentNoteId, noteId);
@ -122,6 +119,12 @@ function toggleNoteInParent(present, noteId, parentNoteId, prefix) {
}
function cloneNoteAfter(noteId, afterBranchId) {
if (['hidden', 'root'].includes(noteId)) {
return { success: false, message: 'Cloning the given note is forbidden.' };
} else if (afterBranchId === 'hidden') {
return { success: false, message: 'Cannot clone after the hidden branch.' };
}
const afterNote = becca.getBranch(afterBranchId);
if (isNoteDeleted(noteId) || isNoteDeleted(afterNote.parentNoteId)) {

View File

@ -0,0 +1,27 @@
const cls = require("./cls");
const becca = require("../becca/becca");
function getHoistedNoteId() {
return cls.getHoistedNoteId();
}
function isHoistedInHiddenSubtree() {
const hoistedNoteId = getHoistedNoteId();
if (hoistedNoteId === 'root') {
return false;
}
const hoistedNote = becca.getNote(hoistedNoteId);
if (!hoistedNote) {
throw new Error(`Cannot find hoisted note ${hoistedNoteId}`);
}
return hoistedNote.hasAncestor('hidden');
}
module.exports = {
getHoistedNoteId,
isHoistedInHiddenSubtree
};

View File

@ -1,6 +1,6 @@
"use strict";
const cls = require('../cls');
const hoistedNoteService = require("../hoisted_note");
class SearchContext {
constructor(params = {}) {
@ -9,8 +9,10 @@ class SearchContext {
this.ignoreHoistedNote = !!params.ignoreHoistedNote;
this.ancestorNoteId = params.ancestorNoteId;
if (!this.ancestorNoteId && !this.ignoreHoistedNote) {
this.ancestorNoteId = cls.getHoistedNoteId();
if (!this.ancestorNoteId && !this.ignoreHoistedNote && !hoistedNoteService.isHoistedInHiddenSubtree()) {
// hoisting in hidden subtree should not limit autocomplete
// since we want to link (create relations) to the normal non-hidden notes
this.ancestorNoteId = hoistedNoteService.getHoistedNoteId();
}
this.ancestorDepth = params.ancestorDepth;

View File

@ -53,6 +53,16 @@ function getHiddenRoot() {
hidden.addLabel("docName", "hidden");
}
const MAX_POS = 999_999_999;
const branch = hidden.getBranches()[0];
if (branch.notePosition !== MAX_POS) {
// we want to keep the hidden subtree always last, otherwise there will be problems with e.g. keyboard navigation
// over tree when it's in the middle
branch.notePosition = MAX_POS;
branch.save();
}
return hidden;
}

View File

@ -30,13 +30,13 @@ function getNotes(noteIds) {
}
function validateParentChild(parentNoteId, childNoteId, branchId = null) {
if (childNoteId === 'root') {
return { success: false, message: 'Cannot move root note.'};
if (['root', 'hidden'].includes(childNoteId)) {
return { success: false, message: `Cannot change this note's location.`};
}
if (parentNoteId === 'none') {
// this shouldn't happen
return { success: false, message: 'Cannot move anything into root parent.' };
return { success: false, message: `Cannot move anything into 'none' parent.` };
}
const existing = getExistingBranch(parentNoteId, childNoteId);
@ -58,13 +58,10 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) {
};
}
const parentNoteIsShortcut = becca.getNote(parentNoteId).type === 'shortcut';
const childNoteIsShortcut = becca.getNote(childNoteId).type === 'shortcut';
if (parentNoteIsShortcut !== childNoteIsShortcut) {
if (becca.getNote(parentNoteId).type === 'shortcut') {
return {
success: false,
message: 'Moving/cloning is not possible between shortcuts / normal notes.'
message: 'Shortcut note cannot have any children.'
};
}
@ -189,6 +186,10 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder
for (const note of notes) {
const branch = note.getParentBranches().find(b => b.parentNoteId === parentNoteId);
if (branch.branchId === 'hidden') {
position = 999_999_999;
}
sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?",
[position, branch.branchId]);