mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01:00 
			
		
		
		
	better detection of changes in attributes and how they affect notes
This commit is contained in:
		@@ -23,8 +23,8 @@ class Attribute {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @returns {NoteShort} */
 | 
			
		||||
    async getNote() {
 | 
			
		||||
        return await this.treeCache.getNote(this.noteId);
 | 
			
		||||
    getNote() {
 | 
			
		||||
        return this.treeCache.notes[this.noteId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get jsonValue() {
 | 
			
		||||
@@ -39,6 +39,34 @@ class Attribute {
 | 
			
		||||
    get toString() {
 | 
			
		||||
        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;
 | 
			
		||||
@@ -437,6 +437,35 @@ class NoteShort {
 | 
			
		||||
        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.
 | 
			
		||||
     * 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)) {
 | 
			
		||||
                missingNoteIds.push(attr.value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!(attr.noteId in existingNotes) && !noteIds.has(attr.noteId)) {
 | 
			
		||||
                missingNoteIds.push(attr.noteId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (missingNoteIds.length > 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -270,13 +270,30 @@ export default class NoteDetailWidget extends TabAwareWidget {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async entitiesReloadedEvent({loadResults}) {
 | 
			
		||||
        // FIXME: we should test what happens when the loaded note is deleted
 | 
			
		||||
 | 
			
		||||
        if (loadResults.isNoteContentReloaded(this.noteId, this.componentId)
 | 
			
		||||
            || (loadResults.isNoteReloaded(this.noteId, this.componentId) && (this.type !== await this.getWidgetType() || this.mime !== this.note.mime))) {
 | 
			
		||||
 | 
			
		||||
            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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -268,13 +268,8 @@ export default class PromotedAttributesWidget extends TabAwareWidget {
 | 
			
		||||
        $attr.prop("attribute-id", result.attributeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    entitiesReloadedEvent({loadResults}) {console.log("loadResults", loadResults);
 | 
			
		||||
        // relation/label definitions are very often inherited by tree or template,
 | 
			
		||||
        // 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))) {
 | 
			
		||||
 | 
			
		||||
    entitiesReloadedEvent({loadResults}) {
 | 
			
		||||
        if (loadResults.getAttributes(this.componentId).find(attr => attr.isAffecting(this.note))) {
 | 
			
		||||
            this.refresh();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user