mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
change the heuristics to choose the best note path when ambiguous/incomplete/just noteId is provided, #1711
This commit is contained in:
parent
060d4fc27b
commit
9f002fa802
@ -253,6 +253,32 @@ class NoteShort {
|
|||||||
return noteAttributeCache.attributes[this.noteId];
|
return noteAttributeCache.attributes[this.noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAllNotePaths() {
|
||||||
|
if (this.noteId === 'root') {
|
||||||
|
return [['root']];
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentNotes = this.getParentNotes();
|
||||||
|
let paths;
|
||||||
|
|
||||||
|
if (parentNotes.length === 1) { // optimization for the most common case
|
||||||
|
paths = parentNotes[0].getAllNotePaths();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paths = [];
|
||||||
|
|
||||||
|
for (const parentNote of parentNotes) {
|
||||||
|
paths.push(...parentNote.getAllNotePaths());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const path of paths) {
|
||||||
|
path.push(this.noteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
__filterAttrs(attributes, type, name) {
|
__filterAttrs(attributes, type, name) {
|
||||||
if (!type && !name) {
|
if (!type && !name) {
|
||||||
return attributes;
|
return attributes;
|
||||||
|
@ -125,7 +125,7 @@ async function deleteNotes(branchIdsToDelete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function moveNodeUpInHierarchy(node) {
|
async function moveNodeUpInHierarchy(node) {
|
||||||
if (hoistedNoteService.isRootNode(node)
|
if (hoistedNoteService.isHoistedNode(node)
|
||||||
|| hoistedNoteService.isTopLevelNode(node)
|
|| hoistedNoteService.isTopLevelNode(node)
|
||||||
|| node.getParent().data.noteType === 'search') {
|
|| node.getParent().data.noteType === 'search') {
|
||||||
return;
|
return;
|
||||||
|
@ -16,10 +16,10 @@ async function unhoist() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isTopLevelNode(node) {
|
function isTopLevelNode(node) {
|
||||||
return isRootNode(node.getParent());
|
return isHoistedNode(node.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRootNode(node) {
|
function isHoistedNode(node) {
|
||||||
// even though check for 'root' should not be necessary, we keep it just in case
|
// even though check for 'root' should not be necessary, we keep it just in case
|
||||||
return node.data.noteId === "root"
|
return node.data.noteId === "root"
|
||||||
|| node.data.noteId === getHoistedNoteId();
|
|| node.data.noteId === getHoistedNoteId();
|
||||||
@ -55,6 +55,6 @@ export default {
|
|||||||
getHoistedNoteId,
|
getHoistedNoteId,
|
||||||
unhoist,
|
unhoist,
|
||||||
isTopLevelNode,
|
isTopLevelNode,
|
||||||
isRootNode,
|
isHoistedNode,
|
||||||
checkNoteAccess
|
checkNoteAccess
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,10 @@ async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logEr
|
|||||||
console.log(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}`);
|
console.log(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hoistedNote = await treeCache.getNote(hoistedNoteId);
|
const someNotePath = getSomeNotePath(child, hoistedNoteId);
|
||||||
|
|
||||||
const chosenParent = parents.find(parent => parent.hasAncestor(hoistedNote))
|
|
||||||
|| parents[0]; // if no parent is in hoisted subtree then it just doesn't matter and pick any
|
|
||||||
const someNotePath = getSomeNotePath(chosenParent);
|
|
||||||
|
|
||||||
if (someNotePath) { // in case it's root the path may be empty
|
if (someNotePath) { // in case it's root the path may be empty
|
||||||
const pathToRoot = someNotePath.split("/").reverse();
|
const pathToRoot = someNotePath.split("/").reverse().slice(1);
|
||||||
|
|
||||||
for (const noteId of pathToRoot) {
|
for (const noteId of pathToRoot) {
|
||||||
effectivePath.push(noteId);
|
effectivePath.push(noteId);
|
||||||
@ -100,29 +96,35 @@ async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logEr
|
|||||||
return effectivePath.reverse();
|
return effectivePath.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSomeNotePath(note) {
|
function getSomeNotePathSegments(note, hoistedNotePath = 'root') {
|
||||||
utils.assertArguments(note);
|
utils.assertArguments(note);
|
||||||
|
|
||||||
const path = [];
|
const notePaths = note.getAllNotePaths().map(path => ({
|
||||||
|
notePath: path,
|
||||||
|
isInHoistedSubTree: path.includes(hoistedNotePath),
|
||||||
|
isArchived: path.find(noteId => treeCache.notes[noteId].hasLabel('archived')),
|
||||||
|
isSearch: path.find(noteId => treeCache.notes[noteId].type === 'search')
|
||||||
|
}));
|
||||||
|
|
||||||
let cur = note;
|
notePaths.sort((a, b) => {
|
||||||
|
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
|
||||||
while (cur.noteId !== 'root') {
|
return a.isInHoistedSubTree ? -1 : 1;
|
||||||
path.push(cur.noteId);
|
} else if (a.isSearch !== b.isSearch) {
|
||||||
|
return a.isSearch ? 1 : -1;
|
||||||
const parents = cur.getParentNotes().filter(note => note.type !== 'search');
|
} else if (a.isArchived !== b.isArchived) {
|
||||||
|
return a.isArchived ? 1 : -1;
|
||||||
if (!parents.length) {
|
} else {
|
||||||
logError(`Can't find parents for note ${cur.noteId}`);
|
return a.notePath.length - b.notePath.length;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
cur = parents[0];
|
return notePaths[0].notePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
path.push('root');
|
function getSomeNotePath(note, hoistedNotePath = 'root') {
|
||||||
|
const notePath = getSomeNotePathSegments(note, hoistedNotePath);
|
||||||
|
|
||||||
return path.reverse().join('/');
|
return notePath.join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sortAlphabetically(noteId) {
|
async function sortAlphabetically(noteId) {
|
||||||
@ -142,7 +144,7 @@ ws.subscribeToMessages(message => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getParentProtectedStatus(node) {
|
function getParentProtectedStatus(node) {
|
||||||
return hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected;
|
return hoistedNoteService.isHoistedNode(node) ? 0 : node.getParent().data.isProtected;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteIdFromNotePath(notePath) {
|
function getNoteIdFromNotePath(notePath) {
|
||||||
@ -202,7 +204,7 @@ function getNotePath(node) {
|
|||||||
|
|
||||||
const path = [];
|
const path = [];
|
||||||
|
|
||||||
while (node && !hoistedNoteService.isRootNode(node)) {
|
while (node) {
|
||||||
if (node.data.noteId) {
|
if (node.data.noteId) {
|
||||||
path.push(node.data.noteId);
|
path.push(node.data.noteId);
|
||||||
}
|
}
|
||||||
@ -210,10 +212,6 @@ function getNotePath(node) {
|
|||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) { // null node can happen directly after unhoisting when tree is still hoisted but option has been changed already
|
|
||||||
path.push(node.data.noteId); // root or hoisted noteId
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.reverse().join("/");
|
return path.reverse().join("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +315,7 @@ export default {
|
|||||||
resolveNotePath,
|
resolveNotePath,
|
||||||
resolveNotePathToSegments,
|
resolveNotePathToSegments,
|
||||||
getSomeNotePath,
|
getSomeNotePath,
|
||||||
|
getSomeNotePathSegments,
|
||||||
getParentProtectedStatus,
|
getParentProtectedStatus,
|
||||||
getNotePath,
|
getNotePath,
|
||||||
getNoteIdFromNotePath,
|
getNoteIdFromNotePath,
|
||||||
|
@ -1210,18 +1210,10 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
this.tree.clearFilter();
|
this.tree.clearFilter();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let found = false;console.log(this.tabContext.notePath, this.tabContext.hoistedNoteId, "ZZZ");
|
|
||||||
|
|
||||||
// hack when hoisted note is cloned then it could be filtered multiple times while we want only 1
|
// hack when hoisted note is cloned then it could be filtered multiple times while we want only 1
|
||||||
this.tree.filterBranches(node => {
|
this.tree.filterBranches(node =>
|
||||||
if (found) {
|
node.data.noteId === this.tabContext.hoistedNoteId // optimization to not having always resolve the node path
|
||||||
return false;
|
&& treeService.getNotePath(node) === hoistedNotePath);
|
||||||
}
|
|
||||||
|
|
||||||
found = node.data.noteId === this.tabContext.hoistedNoteId;
|
|
||||||
|
|
||||||
return found;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user