Notes/src/becca/becca_service.js

215 lines
5.2 KiB
JavaScript
Raw Normal View History

2020-05-17 09:48:24 +02:00
"use strict";
2021-04-16 23:01:56 +02:00
const becca = require('./becca.js');
2021-05-17 22:10:00 +02:00
const cls = require('../services/cls');
const protectedSessionService = require('../services/protected_session');
const log = require('../services/log');
2020-05-17 09:48:24 +02:00
2020-05-16 23:12:29 +02:00
function isNotePathArchived(notePath) {
const noteId = notePath[notePath.length - 1];
2021-04-16 23:00:08 +02:00
const note = becca.notes[noteId];
2020-05-16 23:12:29 +02:00
2021-05-18 20:56:49 +02:00
if (note.isArchived) {
2020-05-16 23:12:29 +02:00
return true;
}
for (let i = 0; i < notePath.length - 1; i++) {
2021-04-16 23:00:08 +02:00
const note = becca.notes[notePath[i]];
2020-05-16 23:12:29 +02:00
// this is going through parents so archived must be inheritable
2021-05-17 22:35:36 +02:00
if (note.hasInheritableOwnedArchivedLabel()) {
2020-05-16 23:12:29 +02:00
return true;
}
}
return false;
}
/**
* This assumes that note is available. "archived" note means that there isn't a single non-archived note-path
* leading to this note.
*
* @param noteId
*/
function isArchived(noteId) {
const notePath = getSomePath(noteId);
return isNotePathArchived(notePath);
}
/**
* @param {string} noteId
* @param {string} ancestorNoteId
* @return {boolean} - true if given noteId has ancestorNoteId in any of its paths (even archived)
*/
function isInAncestor(noteId, ancestorNoteId) {
if (ancestorNoteId === 'root' || ancestorNoteId === noteId) {
return true;
}
2021-04-16 23:00:08 +02:00
const note = becca.notes[noteId];
2020-05-16 23:12:29 +02:00
if (!note) {
return false;
}
2020-05-16 23:12:29 +02:00
for (const parentNote of note.parents) {
if (isInAncestor(parentNote.noteId, ancestorNoteId)) {
return true;
}
}
return false;
}
function getNoteTitle(childNoteId, parentNoteId) {
2021-04-16 23:00:08 +02:00
const childNote = becca.notes[childNoteId];
const parentNote = becca.notes[parentNoteId];
2020-05-16 23:12:29 +02:00
if (!childNote) {
log.info(`Cannot find note in cache for noteId ${childNoteId}`);
return "[error fetching title]";
}
2020-05-16 23:12:29 +02:00
let title;
if (childNote.isProtected) {
title = protectedSessionService.isProtectedSessionAvailable() ? childNote.title : '[protected]';
}
else {
title = childNote.title;
}
const branch = parentNote ? becca.getBranchFromChildAndParent(childNote.noteId, parentNote.noteId) : null;
2020-05-16 23:12:29 +02:00
return ((branch && branch.prefix) ? `${branch.prefix} - ` : '') + title;
}
function getNoteTitleArrayForPath(notePathArray) {
2020-11-23 23:11:21 +01:00
if (notePathArray.length === 1 && notePathArray[0] === cls.getHoistedNoteId()) {
return [getNoteTitle(cls.getHoistedNoteId())];
}
2020-05-16 23:12:29 +02:00
const titles = [];
let parentNoteId = 'root';
let hoistedNotePassed = false;
for (const noteId of notePathArray) {
// start collecting path segment titles only after hoisted note
if (hoistedNotePassed) {
const title = getNoteTitle(noteId, parentNoteId);
titles.push(title);
}
2020-11-23 22:52:48 +01:00
if (noteId === cls.getHoistedNoteId()) {
2020-05-16 23:12:29 +02:00
hoistedNotePassed = true;
}
parentNoteId = noteId;
}
return titles;
}
function getNoteTitleForPath(notePathArray) {
const titles = getNoteTitleArrayForPath(notePathArray);
return titles.join(' / ');
}
/**
* Returns notePath for noteId from cache. Note hoisting is respected.
* Archived notes are also returned, but non-archived paths are preferred if available
* - this means that archived paths is returned only if there's no non-archived path
2021-05-18 20:56:49 +02:00
* - you can check whether returned path is archived using isArchived
2020-05-16 23:12:29 +02:00
*/
2021-04-07 21:12:55 +02:00
function getSomePath(note, path = []) {
// first try to find note within hoisted note, otherwise take any existing note path
2021-04-07 21:12:55 +02:00
return getSomePathInner(note, path, true)
|| getSomePathInner(note, path, false);
}
function getSomePathInner(note, path, respectHoistng) {
2021-07-20 13:29:11 +02:00
if (note.isRoot()) {
2020-05-16 23:12:29 +02:00
path.push(note.noteId);
path.reverse();
if (respectHoistng && !path.includes(cls.getHoistedNoteId())) {
2020-05-16 23:12:29 +02:00
return false;
}
return path;
}
const parents = note.parents;
if (parents.length === 0) {
return false;
}
for (const parentNote of parents) {
const retPath = getSomePathInner(parentNote, path.concat([note.noteId]), respectHoistng);
2020-05-16 23:12:29 +02:00
if (retPath) {
return retPath;
}
}
return false;
}
function getNotePath(noteId) {
2021-04-16 23:00:08 +02:00
const note = becca.notes[noteId];
2020-08-28 23:20:22 +02:00
if (!note) {
console.trace(`Cannot find note ${noteId} in cache.`);
return;
}
2020-05-16 23:12:29 +02:00
const retPath = getSomePath(note);
if (retPath) {
const noteTitle = getNoteTitleForPath(retPath);
let branchId;
2021-07-20 13:29:11 +02:00
if (note.isRoot()) {
branchId = 'root';
}
else {
const parentNote = note.parents[0];
branchId = becca.getBranchFromChildAndParent(noteId, parentNote.noteId).branchId;
}
2020-05-16 23:12:29 +02:00
return {
noteId: noteId,
branchId: branchId,
2020-05-16 23:12:29 +02:00
title: noteTitle,
notePath: retPath,
path: retPath.join('/')
};
}
}
/**
* @param noteId
* @returns {boolean} - true if note exists (is not deleted) and is available in current note hoisting
*/
function isAvailable(noteId) {
const notePath = getNotePath(noteId);
return !!notePath;
}
module.exports = {
2020-05-17 10:11:19 +02:00
getSomePath,
2020-05-16 23:12:29 +02:00
getNotePath,
2020-05-17 10:11:19 +02:00
getNoteTitle,
2020-05-16 23:12:29 +02:00
getNoteTitleForPath,
isAvailable,
isArchived,
isInAncestor,
2020-09-15 16:46:03 +02:00
isNotePathArchived
2020-05-16 23:12:29 +02:00
};