mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
better detection of changes in attributes and how they affect notes
This commit is contained in:
parent
1db892d22f
commit
212b719ee9
@ -23,8 +23,8 @@ class Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {NoteShort} */
|
/** @returns {NoteShort} */
|
||||||
async getNote() {
|
getNote() {
|
||||||
return await this.treeCache.getNote(this.noteId);
|
return this.treeCache.notes[this.noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
get jsonValue() {
|
get jsonValue() {
|
||||||
@ -39,6 +39,34 @@ class Attribute {
|
|||||||
get toString() {
|
get toString() {
|
||||||
return `Attribute(attributeId=${this.attributeId}, type=${this.type}, name=${this.name}, value=${this.value})`;
|
return `Attribute(attributeId=${this.attributeId}, type=${this.type}, name=${this.name}, value=${this.value})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean} - returns true if this attribute has the potential to influence the note in the argument.
|
||||||
|
* That can happen in multiple ways:
|
||||||
|
* 1. attribute is owned by the note
|
||||||
|
* 2. attribute is owned by the template of the note
|
||||||
|
* 3. attribute is owned by some note's ancestor and is inheritable
|
||||||
|
*/
|
||||||
|
isAffecting(affectedNote) {
|
||||||
|
const attrNote = this.getNote();
|
||||||
|
const owningNotes = [affectedNote, ...affectedNote.getTemplateNotes()];
|
||||||
|
|
||||||
|
for (const owningNote of owningNotes) {
|
||||||
|
if (owningNote.noteId === attrNote.noteId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isInheritable) {
|
||||||
|
for (const owningNote of owningNotes) {
|
||||||
|
if (owningNote.hasAncestor(attrNote)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Attribute;
|
export default Attribute;
|
||||||
|
@ -437,6 +437,35 @@ class NoteShort {
|
|||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {NoteShort[]}
|
||||||
|
*/
|
||||||
|
getTemplateNotes() {
|
||||||
|
const relations = this.getRelations('template');
|
||||||
|
|
||||||
|
return relations.map(rel => this.treeCache.notes[rel.value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasAncestor(ancestorNote) {
|
||||||
|
if (this.noteId === ancestorNote.noteId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const templateNote of this.getTemplateNotes()) {
|
||||||
|
if (templateNote.hasAncestor(ancestorNote)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const parentNote of this.getParentNotes()) {
|
||||||
|
if (parentNote.hasAncestor(ancestorNote)) {console.log(parentNote);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear note's attributes cache to force fresh reload for next attribute request.
|
* Clear note's attributes cache to force fresh reload for next attribute request.
|
||||||
* Cache is note instance scoped.
|
* Cache is note instance scoped.
|
||||||
|
@ -54,6 +54,10 @@ class TreeCache {
|
|||||||
if (attr.type === 'relation' && attr.name === 'template' && !(attr.value in existingNotes) && !noteIds.has(attr.value)) {
|
if (attr.type === 'relation' && attr.name === 'template' && !(attr.value in existingNotes) && !noteIds.has(attr.value)) {
|
||||||
missingNoteIds.push(attr.value);
|
missingNoteIds.push(attr.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(attr.noteId in existingNotes) && !noteIds.has(attr.noteId)) {
|
||||||
|
missingNoteIds.push(attr.noteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (missingNoteIds.length > 0) {
|
if (missingNoteIds.length > 0) {
|
||||||
@ -283,4 +287,4 @@ class TreeCache {
|
|||||||
|
|
||||||
const treeCache = new TreeCache();
|
const treeCache = new TreeCache();
|
||||||
|
|
||||||
export default treeCache;
|
export default treeCache;
|
||||||
|
@ -270,13 +270,30 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async entitiesReloadedEvent({loadResults}) {
|
async entitiesReloadedEvent({loadResults}) {
|
||||||
// FIXME: we should test what happens when the loaded note is deleted
|
|
||||||
|
|
||||||
if (loadResults.isNoteContentReloaded(this.noteId, this.componentId)
|
if (loadResults.isNoteContentReloaded(this.noteId, this.componentId)
|
||||||
|| (loadResults.isNoteReloaded(this.noteId, this.componentId) && (this.type !== await this.getWidgetType() || this.mime !== this.note.mime))) {
|
|| (loadResults.isNoteReloaded(this.noteId, this.componentId) && (this.type !== await this.getWidgetType() || this.mime !== this.note.mime))) {
|
||||||
|
|
||||||
this.handleEvent('noteTypeMimeChanged', {noteId: this.noteId});
|
this.handleEvent('noteTypeMimeChanged', {noteId: this.noteId});
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
const attrs = loadResults.getAttributes();
|
||||||
|
|
||||||
|
const label = attrs.find(attr =>
|
||||||
|
attr.type === 'label'
|
||||||
|
&& ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'bookZoomLevel'].includes(attr.name)
|
||||||
|
&& attr.isAffecting(this.note));
|
||||||
|
|
||||||
|
const relation = attrs.find(attr =>
|
||||||
|
attr.type === 'relation'
|
||||||
|
&& ['template', 'runOnNoteView', 'renderNote'].includes(attr.name)
|
||||||
|
&& attr.isAffecting(this.note));
|
||||||
|
|
||||||
|
if (label || relation) {
|
||||||
|
// probably incorrect event
|
||||||
|
// calling this.refresh() is not enough since the event needs to be propagated to children as well
|
||||||
|
this.handleEvent('noteTypeMimeChanged', {noteId: this.noteId});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeUnloadEvent() {
|
beforeUnloadEvent() {
|
||||||
|
@ -268,13 +268,8 @@ export default class PromotedAttributesWidget extends TabAwareWidget {
|
|||||||
$attr.prop("attribute-id", result.attributeId);
|
$attr.prop("attribute-id", result.attributeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
entitiesReloadedEvent({loadResults}) {console.log("loadResults", loadResults);
|
entitiesReloadedEvent({loadResults}) {
|
||||||
// relation/label definitions are very often inherited by tree or template,
|
if (loadResults.getAttributes(this.componentId).find(attr => attr.isAffecting(this.note))) {
|
||||||
// it's difficult to detect inheritance so we will
|
|
||||||
if (loadResults.getAttributes(this.componentId).find(attr =>
|
|
||||||
attr.noteId === this.noteId
|
|
||||||
|| ['label-definition', 'relation-definition'].includes(attr.type))) {
|
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user