Files
Trilium/src/public/app/services/tree_builder.js

188 lines
4.7 KiB
JavaScript
Raw Normal View History

2018-03-26 23:18:50 -04:00
import utils from "./utils.js";
import treeCache from "./tree_cache.js";
2019-08-26 20:21:43 +02:00
import ws from "./ws.js";
2018-12-11 21:53:56 +01:00
import hoistedNoteService from "./hoisted_note.js";
2018-03-26 23:18:50 -04:00
2020-03-31 20:52:41 +02:00
async function prepareRootNode() {
await treeCache.initializedPromise;
2020-02-10 20:57:56 +01:00
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
2018-12-12 20:39:56 +01:00
let hoistedBranch;
if (hoistedNoteId === 'root') {
hoistedBranch = treeCache.getBranch('root');
2018-12-12 20:39:56 +01:00
}
else {
const hoistedNote = await treeCache.getNote(hoistedNoteId);
hoistedBranch = (await hoistedNote.getBranches())[0];
}
2018-12-11 21:53:56 +01:00
2020-03-31 20:52:41 +02:00
return await prepareNode(hoistedBranch);
2018-03-26 23:18:50 -04:00
}
2020-04-30 23:58:34 +02:00
async function prepareChildren(note) {
2018-03-26 23:18:50 -04:00
if (note.type === 'search') {
2020-04-30 23:58:34 +02:00
return await prepareSearchNoteChildren(note);
2018-03-26 23:18:50 -04:00
}
else {
2020-04-30 23:58:34 +02:00
return await prepareNormalNoteChildren(note);
2018-03-26 23:18:50 -04:00
}
}
const NOTE_TYPE_ICONS = {
"file": "bx bx-file",
"image": "bx bx-image",
"code": "bx bx-code",
"render": "bx bx-extension",
"search": "bx bx-file-find",
"relation-map": "bx bx-map-alt",
"book": "bx bx-book"
};
function getIconClass(note) {
const labels = note.getLabels('iconClass');
2020-01-25 14:48:53 +01:00
return labels.map(l => l.value).join(' ');
}
function getIcon(note) {
2020-02-10 20:57:56 +01:00
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
const iconClass = getIconClass(note);
2020-01-25 14:48:53 +01:00
if (iconClass) {
return iconClass;
}
else if (note.noteId === 'root') {
return "bx bx-chevrons-right";
}
else if (note.noteId === hoistedNoteId) {
return "bx bxs-arrow-from-bottom";
}
else if (note.type === 'text') {
if (note.hasChildren()) {
return "bx bx-folder";
}
else {
return "bx bx-note";
}
}
else {
return NOTE_TYPE_ICONS[note.type];
}
}
2018-05-26 16:16:34 -04:00
async function prepareNode(branch) {
const note = await branch.getNote();
if (!note) {
2019-12-16 22:47:07 +01:00
throw new Error(`Branch has no note ` + branch.noteId);
}
2018-05-26 16:16:34 -04:00
const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title;
2020-02-10 20:57:56 +01:00
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
2018-05-26 16:16:34 -04:00
const node = {
noteId: note.noteId,
parentNoteId: branch.parentNoteId,
branchId: branch.branchId,
isProtected: note.isProtected,
noteType: note.type,
2018-05-26 16:16:34 -04:00
title: utils.escapeHtml(title),
extraClasses: getExtraClasses(note),
icon: getIcon(note),
2018-05-26 16:16:34 -04:00
refKey: note.noteId,
expanded: branch.isExpanded || hoistedNoteId === note.noteId,
2019-06-28 21:50:15 +02:00
key: utils.randomString(12) // this should prevent some "duplicate key" errors
2018-05-26 16:16:34 -04:00
};
2020-04-30 23:58:34 +02:00
const childBranches = getChildBranchesWithoutImages(note);
node.folder = childBranches.length > 0
|| note.type === 'search'
node.lazy = node.folder && !node.expanded;
if (node.folder && node.expanded) {
node.children = await prepareChildren(note);
}
2018-05-26 16:16:34 -04:00
return node;
}
2020-04-30 23:58:34 +02:00
async function prepareNormalNoteChildren(parentNote) {
2018-03-26 23:18:50 -04:00
utils.assertArguments(parentNote);
const noteList = [];
for (const branch of getChildBranchesWithoutImages(parentNote)) {
2018-05-26 16:16:34 -04:00
const node = await prepareNode(branch);
2018-03-26 23:18:50 -04:00
noteList.push(node);
}
return noteList;
}
function getChildBranchesWithoutImages(parentNote) {
const childBranches = parentNote.getChildBranches();
if (!childBranches) {
ws.logError(`No children for ${parentNote}. This shouldn't happen.`);
return;
}
const imageLinks = parentNote.getRelations('imageLink');
// image is already visible in the parent note so no need to display it separately in the book
return childBranches.filter(branch => !imageLinks.find(rel => rel.value === branch.noteId));
}
2020-04-30 23:58:34 +02:00
async function prepareSearchNoteChildren(note) {
await treeCache.reloadNotes([note.noteId]);
2018-03-26 23:18:50 -04:00
2019-10-27 19:17:32 +01:00
const newNote = await treeCache.getNote(note.noteId);
2018-03-26 23:18:50 -04:00
2020-04-30 23:58:34 +02:00
return await prepareNormalNoteChildren(newNote);
2018-03-26 23:18:50 -04:00
}
function getExtraClasses(note) {
2018-03-26 23:18:50 -04:00
utils.assertArguments(note);
const extraClasses = [];
if (note.isProtected) {
extraClasses.push("protected");
}
2018-04-16 23:34:56 -04:00
if (note.getParentNoteIds().length > 1) {
2018-03-26 23:18:50 -04:00
extraClasses.push("multiple-parents");
}
const cssClass = note.getCssClass();
2020-01-25 14:48:53 +01:00
if (cssClass) {
extraClasses.push(cssClass);
2018-08-13 10:59:31 +02:00
}
extraClasses.push(utils.getNoteTypeClass(note.type));
2018-03-26 23:18:50 -04:00
if (note.mime) { // some notes should not have mime type (e.g. render)
extraClasses.push(utils.getMimeTypeClass(note.mime));
}
if (note.hasLabel('archived')) {
2019-10-15 19:16:44 +02:00
extraClasses.push("archived");
}
2018-03-26 23:18:50 -04:00
return extraClasses.join(" ");
}
export default {
2020-03-31 20:52:41 +02:00
prepareRootNode,
2020-04-30 23:58:34 +02:00
prepareBranch: prepareChildren,
2018-11-14 08:42:00 +01:00
getExtraClasses,
getIcon,
getChildBranchesWithoutImages
2018-03-26 23:18:50 -04:00
}