core: add support for linking notes with notebooks

this basically allows notes to exist at the top-level in a notebook
This commit is contained in:
Abdullah Atta
2023-03-07 14:33:29 +05:00
committed by Abdullah Atta
parent 74c86c1e5f
commit 86770b32bb
4 changed files with 77 additions and 40 deletions

View File

@@ -144,6 +144,10 @@ export default class Notebooks extends Collection {
return new Notebook(notebook, this._db);
}
exists(id) {
return this._collection.exists(id);
}
async delete(...ids) {
for (let id of ids) {
let notebook = this.notebook(id);

View File

@@ -25,7 +25,7 @@ import qclone from "qclone";
import { deleteItem, findById } from "../utils/array";
/**
* @typedef {{ id: string, topic: string, rebuildCache?: boolean }} NotebookReference
* @typedef {{ id: string, topic?: string, rebuildCache?: boolean }} NotebookReference
*/
export default class Notes extends Collection {
@@ -290,10 +290,7 @@ export default class Notes extends Collection {
*/
async addToNotebook(to, ...noteIds) {
if (!to) throw new Error("The destination notebook cannot be undefined.");
if (!to.id || !to.topic)
throw new Error(
"The destination notebook must contain notebookId and topic."
);
if (!to.id) throw new Error("The destination notebook must contain id.");
const { id: notebookId, topic: topicId } = to;
@@ -301,28 +298,35 @@ export default class Notes extends Collection {
let note = this._db.notes.note(noteId);
if (!note || note.data.deleted) continue;
const notebooks = note.notebooks || [];
if (topicId) {
const notebooks = note.notebooks || [];
const noteNotebook = notebooks.find((nb) => nb.id === notebookId);
const noteHasNotebook = !!noteNotebook;
const noteHasTopic =
noteHasNotebook && noteNotebook.topics.indexOf(topicId) > -1;
if (noteHasNotebook && !noteHasTopic) {
// 1 note can be inside multiple topics
noteNotebook.topics.push(topicId);
} else if (!noteHasNotebook) {
notebooks.push({
id: notebookId,
topics: [topicId]
});
}
const noteNotebook = notebooks.find((nb) => nb.id === notebookId);
const noteHasNotebook = !!noteNotebook;
const noteHasTopic =
noteHasNotebook && noteNotebook.topics.indexOf(topicId) > -1;
if (noteHasNotebook && !noteHasTopic) {
// 1 note can be inside multiple topics
noteNotebook.topics.push(topicId);
} else if (!noteHasNotebook) {
notebooks.push({
id: notebookId,
topics: [topicId]
});
}
if (!noteHasNotebook || !noteHasTopic) {
await this._db.notes.add({
id: noteId,
notebooks
});
this.topicReferences.add(topicId, noteId);
if (!noteHasNotebook || !noteHasTopic) {
await this._db.notes.add({
id: noteId,
notebooks
});
this.topicReferences.add(topicId, noteId);
}
} else {
await this._db.relations.add(
{ id: notebookId, type: "notebook" },
note.data
);
}
}
}
@@ -332,10 +336,7 @@ export default class Notes extends Collection {
*/
async removeFromNotebook(to, ...noteIds) {
if (!to) throw new Error("The destination notebook cannot be undefined.");
if (!to.id || !to.topic)
throw new Error(
"The destination notebook must contain notebookId and topic."
);
if (!to.id) throw new Error("The destination notebook must contain id.");
const { id: notebookId, topic: topicId, rebuildCache = true } = to;
@@ -345,20 +346,27 @@ export default class Notes extends Collection {
continue;
}
const { notebooks } = note;
if (topicId) {
const { notebooks } = note;
const notebook = findById(notebooks, notebookId);
if (!notebook) continue;
const notebook = findById(notebooks, notebookId);
if (!notebook) continue;
const { topics } = notebook;
if (!deleteItem(topics, topicId)) continue;
const { topics } = notebook;
if (!deleteItem(topics, topicId)) continue;
if (topics.length <= 0) deleteItem(notebooks, notebook);
if (topics.length <= 0) deleteItem(notebooks, notebook);
await this._db.notes.add({
id: noteId,
notebooks
});
await this._db.notes.add({
id: noteId,
notebooks
});
} else {
await this._db.relations.unlink(
{ id: notebookId, type: "notebook" },
note.data
);
}
}
if (rebuildCache) this.topicReferences.rebuild();
}

View File

@@ -116,6 +116,21 @@ export default class Relations extends Collection {
}
}
/**
*
* @param {ItemReference} from
* @param {ItemReference} to
*/
async unlink(from, to) {
const relation = this.all.find(
(a) =>
compareItemReference(a.from, from) && compareItemReference(a.to, to)
);
if (!relation) return;
await this.remove(relation.id);
}
/**
* @param {Relation[]} relations
* @param {"from" | "to"} resolveType
@@ -127,7 +142,6 @@ export default class Relations extends Collection {
const items = [];
for (const relation of relations) {
const reference = resolveType === "from" ? relation.from : relation.to;
let item = null;
switch (reference.type) {
case "reminder":
@@ -139,6 +153,12 @@ export default class Relations extends Collection {
item = note.data;
break;
}
case "notebook": {
const notebook = this._db.notebooks.notebook(reference.id);
if (!notebook) continue;
item = notebook.data;
break;
}
}
if (item) items.push(item);
}
@@ -160,6 +180,11 @@ export default class Relations extends Collection {
this._db.notes.exists(reference.id) ||
this._db.trash.exists(reference.id);
break;
case "notebook":
exists =
this._db.notebooks.exists(reference.id) ||
this._db.trash.exists(reference.id);
break;
}
if (!exists) await this.remove(relation.id);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB