mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
subtree duplication with becca
This commit is contained in:
parent
a5ee590544
commit
93cae44ba0
@ -9,6 +9,7 @@ const log = require('../../services/log');
|
|||||||
const TaskContext = require('../../services/task_context');
|
const TaskContext = require('../../services/task_context');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const noteRevisionService = require("../../services/note_revisions.js");
|
const noteRevisionService = require("../../services/note_revisions.js");
|
||||||
|
const becca = require("../../services/becca/becca.js");
|
||||||
|
|
||||||
function getNote(req) {
|
function getNote(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
@ -107,7 +108,7 @@ function sortChildNotes(req) {
|
|||||||
|
|
||||||
function protectNote(req) {
|
function protectNote(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const note = repository.getNote(noteId);
|
const note = becca.notes[noteId];
|
||||||
const protect = !!parseInt(req.params.isProtected);
|
const protect = !!parseInt(req.params.isProtected);
|
||||||
const includingSubTree = !!parseInt(req.query.subtree);
|
const includingSubTree = !!parseInt(req.query.subtree);
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ class AbstractEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUtcDateChanged() {
|
getUtcDateChanged() {
|
||||||
return this.utcDateModified || this.utcDateCreated;
|
// FIXME
|
||||||
|
return this.utcDateModified || this.utcDateCreated || "FAKE";
|
||||||
}
|
}
|
||||||
|
|
||||||
get repository() {
|
get repository() {
|
||||||
|
@ -121,7 +121,9 @@ class Attribute extends AbstractEntity {
|
|||||||
name: this.name,
|
name: this.name,
|
||||||
position: this.position,
|
position: this.position,
|
||||||
value: this.value,
|
value: this.value,
|
||||||
isInheritable: this.isInheritable
|
isInheritable: this.isInheritable,
|
||||||
|
utcDateModified: dateUtils.utcNowDateTime(),
|
||||||
|
isDeleted: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +150,6 @@ class Attribute extends AbstractEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
super.beforeSaving();
|
super.beforeSaving();
|
||||||
|
|
||||||
this.utcDateModified = dateUtils.utcNowDateTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createClone(type, name, value, isInheritable) {
|
createClone(type, name, value, isInheritable) {
|
||||||
|
@ -55,6 +55,10 @@ class Branch extends AbstractEntity {
|
|||||||
return this.becca.notes[this.noteId];
|
return this.becca.notes[this.noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNote() {
|
||||||
|
return this.childNote;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {Note} */
|
/** @return {Note} */
|
||||||
get parentNote() {
|
get parentNote() {
|
||||||
if (!(this.parentNoteId in this.becca.notes)) {
|
if (!(this.parentNoteId in this.becca.notes)) {
|
||||||
|
@ -93,14 +93,22 @@ class Note extends AbstractEntity {
|
|||||||
return this.parentBranches;
|
return this.parentBranches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBranches() {
|
||||||
|
return this.parentBranches;
|
||||||
|
}
|
||||||
|
|
||||||
getParentNotes() {
|
getParentNotes() {
|
||||||
return this.parents;
|
return this.parents;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildrenNotes() {
|
getChildNotes() {
|
||||||
return this.children;
|
return this.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getChildBranches() {
|
||||||
|
return this.children.map(childNote => this.becca.getBranch(childNote.noteId, this.noteId));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note content has quite special handling - it's not a separate entity, but a lazily loaded
|
* Note content has quite special handling - it's not a separate entity, but a lazily loaded
|
||||||
* part of Note entity with it's own sync. Reasons behind this hybrid design has been:
|
* part of Note entity with it's own sync. Reasons behind this hybrid design has been:
|
||||||
@ -525,6 +533,26 @@ class Note extends AbstractEntity {
|
|||||||
return this.getOwnedAttributes(RELATION, name);
|
return this.getOwnedAttributes(RELATION, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} [type] - (optional) attribute type to filter
|
||||||
|
* @param {string} [name] - (optional) attribute name to filter
|
||||||
|
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
|
||||||
|
*/
|
||||||
|
getOwnedAttributes(type, name) {
|
||||||
|
if (type && name) {
|
||||||
|
return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name);
|
||||||
|
}
|
||||||
|
else if (type) {
|
||||||
|
return this.ownedAttributes.filter(attr => attr.type === type);
|
||||||
|
}
|
||||||
|
else if (name) {
|
||||||
|
return this.ownedAttributes.filter(attr => attr.name === name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this.ownedAttributes.slice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get isArchived() {
|
get isArchived() {
|
||||||
return this.hasAttribute('label', 'archived');
|
return this.hasAttribute('label', 'archived');
|
||||||
}
|
}
|
||||||
@ -672,6 +700,10 @@ class Note extends AbstractEntity {
|
|||||||
return this.subtreeNotes.map(note => note.noteId);
|
return this.subtreeNotes.map(note => note.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDescendantNoteIds() {
|
||||||
|
return this.subtreeNoteIds;
|
||||||
|
}
|
||||||
|
|
||||||
get parentCount() {
|
get parentCount() {
|
||||||
return this.parents.length;
|
return this.parents.length;
|
||||||
}
|
}
|
||||||
@ -775,10 +807,6 @@ class Note extends AbstractEntity {
|
|||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildBranches() {
|
|
||||||
return this.children.map(childNote => this.becca.getBranch(childNote.noteId, this.noteId));
|
|
||||||
}
|
|
||||||
|
|
||||||
decrypt() {
|
decrypt() {
|
||||||
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
|
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
|
||||||
try {
|
try {
|
||||||
|
@ -762,7 +762,7 @@ function duplicateSubtree(origNoteId, newParentNoteId) {
|
|||||||
|
|
||||||
log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`);
|
log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`);
|
||||||
|
|
||||||
const origNote = repository.getNote(origNoteId);
|
const origNote = becca.notes[origNoteId];
|
||||||
// might be null if orig note is not in the target newParentNoteId
|
// might be null if orig note is not in the target newParentNoteId
|
||||||
const origBranch = origNote.getBranches().find(branch => branch.parentNoteId === newParentNoteId);
|
const origBranch = origNote.getBranches().find(branch => branch.parentNoteId === newParentNoteId);
|
||||||
|
|
||||||
@ -799,16 +799,16 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
|
|||||||
|
|
||||||
const newNoteId = noteIdMapping[origNote.noteId];
|
const newNoteId = noteIdMapping[origNote.noteId];
|
||||||
|
|
||||||
const newBranch = new Branch({
|
const newBranch = new BeccaBranch(becca,{
|
||||||
noteId: newNoteId,
|
noteId: newNoteId,
|
||||||
parentNoteId: newParentNoteId,
|
parentNoteId: newParentNoteId,
|
||||||
// here increasing just by 1 to make sure it's directly after original
|
// here increasing just by 1 to make sure it's directly after original
|
||||||
notePosition: origBranch ? origBranch.notePosition + 1 : null
|
notePosition: origBranch ? origBranch.notePosition + 1 : null
|
||||||
}).save();
|
}).save();
|
||||||
|
|
||||||
const existingNote = repository.getNote(newNoteId);
|
const existingNote = becca.notes[newNoteId];
|
||||||
|
|
||||||
if (existingNote) {
|
if (existingNote.title !== undefined) { // checking that it's not just note's skeleton created because of Branch above
|
||||||
// note has multiple clones and was already created from another placement in the tree
|
// note has multiple clones and was already created from another placement in the tree
|
||||||
// so a branch is all we need for this clone
|
// so a branch is all we need for this clone
|
||||||
return {
|
return {
|
||||||
@ -817,7 +817,7 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const newNote = new Note(origNote);
|
const newNote = new BeccaNote(becca, origNote);
|
||||||
newNote.noteId = newNoteId;
|
newNote.noteId = newNoteId;
|
||||||
newNote.dateCreated = dateUtils.localNowDateTime();
|
newNote.dateCreated = dateUtils.localNowDateTime();
|
||||||
newNote.utcDateCreated = dateUtils.utcNowDateTime();
|
newNote.utcDateCreated = dateUtils.utcNowDateTime();
|
||||||
@ -833,7 +833,7 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
|
|||||||
newNote.setContent(content);
|
newNote.setContent(content);
|
||||||
|
|
||||||
for (const attribute of origNote.getOwnedAttributes()) {
|
for (const attribute of origNote.getOwnedAttributes()) {
|
||||||
const attr = new Attribute(attribute);
|
const attr = new BeccaAttribute(becca, attribute);
|
||||||
attr.attributeId = undefined; // force creation of new attribute
|
attr.attributeId = undefined; // force creation of new attribute
|
||||||
attr.noteId = newNote.noteId;
|
attr.noteId = newNote.noteId;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user