diff --git a/src/public/app/entities/attribute.js b/src/public/app/entities/attribute.js
index e1e34cbfb..126ad4797 100644
--- a/src/public/app/entities/attribute.js
+++ b/src/public/app/entities/attribute.js
@@ -41,44 +41,6 @@ class Attribute {
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) {
- if (!affectedNote) {
- return false;
- }
-
- const attrNote = this.getNote();
-
- if (!attrNote) {
- // the note (owner of the attribute) is not even loaded into the cache so it should not affect anything else
- return false;
- }
-
- 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;
- }
-
isDefinition() {
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
}
diff --git a/src/public/app/services/attributes.js b/src/public/app/services/attributes.js
index 2d175ba2b..d677a40e1 100644
--- a/src/public/app/services/attributes.js
+++ b/src/public/app/services/attributes.js
@@ -1,4 +1,5 @@
import server from './server.js';
+import froca from './froca.js';
async function addLabel(noteId, name, value = "") {
await server.put(`notes/${noteId}/attribute`, {
@@ -20,8 +21,47 @@ async function removeAttributeById(noteId, attributeId) {
await server.remove(`notes/${noteId}/attributes/${attributeId}`);
}
+/**
+ * @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
+ */
+function isAffecting(attrRow, affectedNote) {
+ if (!affectedNote || !attrRow) {
+ return false;
+ }
+
+ const attrNote = froca.notes[attrRow.noteId];
+
+ if (!attrNote) {
+ // the note (owner of the attribute) is not even loaded into the cache so it should not affect anything else
+ return false;
+ }
+
+ 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 {
addLabel,
setLabel,
- removeAttributeById
+ removeAttributeById,
+ isAffecting
}
diff --git a/src/public/app/widgets/attribute_widgets/attribute_editor.js b/src/public/app/widgets/attribute_widgets/attribute_editor.js
index 4a35be33c..96890e096 100644
--- a/src/public/app/widgets/attribute_widgets/attribute_editor.js
+++ b/src/public/app/widgets/attribute_widgets/attribute_editor.js
@@ -8,6 +8,7 @@ import froca from "../../services/froca.js";
import attributeRenderer from "../../services/attribute_renderer.js";
import noteCreateService from "../../services/note_create.js";
import treeService from "../../services/tree.js";
+import attributeService from "../../services/attributes.js";
const HELP_TEXT = `
To add label, just type e.g. #rock
or if you want to add also value then e.g. #year = 2020
@@ -511,7 +512,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
}
entitiesReloadedEvent({loadResults}) {
- if (loadResults.getAttributes(this.componentId).find(attr => attr.isAffecting(this.note))) {
+ if (loadResults.getAttributes(this.componentId).find(attr => attributeService.isAffecting(attr, this.note))) {
this.refresh();
}
}
diff --git a/src/public/app/widgets/note_detail.js b/src/public/app/widgets/note_detail.js
index fa37a4683..8027393eb 100644
--- a/src/public/app/widgets/note_detail.js
+++ b/src/public/app/widgets/note_detail.js
@@ -1,5 +1,4 @@
import NoteContextAwareWidget from "./note_context_aware_widget.js";
-import utils from "../services/utils.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import SpacedUpdate from "../services/spaced_update.js";
import server from "../services/server.js";
@@ -20,6 +19,7 @@ import DeletedTypeWidget from "./type_widgets/deleted.js";
import ReadOnlyTextTypeWidget from "./type_widgets/read_only_text.js";
import ReadOnlyCodeTypeWidget from "./type_widgets/read_only_code.js";
import NoneTypeWidget from "./type_widgets/none.js";
+import attributeService from "../services/attributes.js";
const TPL = `
@@ -246,12 +246,12 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
const label = attrs.find(attr =>
attr.type === 'label'
&& ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'displayRelations'].includes(attr.name)
- && attr.isAffecting(this.note));
+ && attributeService.isAffecting(attr, this.note));
const relation = attrs.find(attr =>
attr.type === 'relation'
&& ['template', 'renderNote'].includes(attr.name)
- && attr.isAffecting(this.note));
+ && attributeService.isAffecting(attr, this.note));
if (label || relation) {
// probably incorrect event
diff --git a/src/public/app/widgets/note_icon.js b/src/public/app/widgets/note_icon.js
index ffc1ae526..f43895da1 100644
--- a/src/public/app/widgets/note_icon.js
+++ b/src/public/app/widgets/note_icon.js
@@ -126,7 +126,7 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
for (const attr of loadResults.getAttributes()) {
if (attr.type === 'label'
&& ['iconClass', 'workspaceIconClass'].includes(attr.name)
- && attr.isAffecting(this.note)) {
+ && attributeService.isAffecting(attr, this.note)) {
this.refresh();
break;
diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js
index bdb418902..d63da777c 100644
--- a/src/public/app/widgets/note_tree.js
+++ b/src/public/app/widgets/note_tree.js
@@ -972,36 +972,36 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
const noteIdsToUpdate = new Set();
const noteIdsToReload = new Set();
- for (const attr of loadResults.getAttributes()) {
- if (attr.type === 'label' && ['iconClass', 'cssClass', 'workspace', 'workspaceIconClass', 'archived'].includes(attr.name)) {
- if (attr.isInheritable) {
- noteIdsToReload.add(attr.noteId);
+ for (const ecAttr of loadResults.getAttributes()) {
+ if (ecAttr.type === 'label' && ['iconClass', 'cssClass', 'workspace', 'workspaceIconClass', 'archived'].includes(ecAttr.name)) {
+ if (ecAttr.isInheritable) {
+ noteIdsToReload.add(ecAttr.noteId);
}
else {
- noteIdsToUpdate.add(attr.noteId);
+ noteIdsToUpdate.add(ecAttr.noteId);
}
}
- else if (attr.type === 'relation' && attr.name === 'template') {
+ else if (ecAttr.type === 'relation' && ecAttr.name === 'template') {
// missing handling of things inherited from template
- noteIdsToReload.add(attr.noteId);
+ noteIdsToReload.add(ecAttr.noteId);
}
- else if (attr.type === 'relation' && attr.name === 'imageLink') {
- const note = froca.getNoteFromCache(attr.noteId);
+ else if (ecAttr.type === 'relation' && ecAttr.name === 'imageLink') {
+ const note = froca.getNoteFromCache(ecAttr.noteId);
- if (note && note.getChildNoteIds().includes(attr.value)) {
+ if (note && note.getChildNoteIds().includes(ecAttr.value)) {
// there's new/deleted imageLink betwen note and its image child - which can show/hide
// the image (if there is a imageLink relation between parent and child then it is assumed to be "contained" in the note and thus does not have to be displayed in the tree)
- noteIdsToReload.add(attr.noteId);
+ noteIdsToReload.add(ecAttr.noteId);
}
}
}
- for (const branch of loadResults.getBranches()) {
+ for (const ecBranch of loadResults.getBranches()) {
// adding noteId itself to update all potential clones
- noteIdsToUpdate.add(branch.noteId);
+ noteIdsToUpdate.add(ecBranch.noteId);
- for (const node of this.getNodesByBranch(branch)) {
- if (branch.isDeleted) {
+ for (const node of this.getNodesByBranch(ecBranch)) {
+ if (ecBranch.isDeleted) {
if (node.isActive()) {
const newActiveNode = node.getNextSibling()
|| node.getPrevSibling()
@@ -1016,22 +1016,22 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
node.remove();
}
- noteIdsToUpdate.add(branch.parentNoteId);
+ noteIdsToUpdate.add(ecBranch.parentNoteId);
}
}
- if (!branch.isDeleted) {
- for (const parentNode of this.getNodesByNoteId(branch.parentNoteId)) {
+ if (!ecBranch.isDeleted) {
+ for (const parentNode of this.getNodesByNoteId(ecBranch.parentNoteId)) {
if (parentNode.isFolder() && !parentNode.isLoaded()) {
continue;
}
- const found = (parentNode.getChildren() || []).find(child => child.data.noteId === branch.noteId);
+ const found = (parentNode.getChildren() || []).find(child => child.data.noteId === ecBranch.noteId);
if (!found) {
// make sure it's loaded
- await froca.getNote(branch.noteId);
- const frocaBranch = froca.getBranch(branch.branchId);
+ await froca.getNote(ecBranch.noteId);
+ const frocaBranch = froca.getBranch(ecBranch.branchId);
// we're forcing lazy since it's not clear if the whole required subtree is in froca
parentNode.addChildren([this.prepareNode(frocaBranch, true)]);
@@ -1039,7 +1039,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
this.sortChildren(parentNode);
// this might be a first child which would force an icon change
- noteIdsToUpdate.add(branch.parentNoteId);
+ noteIdsToUpdate.add(ecBranch.parentNoteId);
}
}
}
diff --git a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js
index c1a041bdb..cb91cae8a 100644
--- a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js
+++ b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js
@@ -1,6 +1,7 @@
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import AttributeDetailWidget from "../attribute_widgets/attribute_detail.js";
import attributeRenderer from "../../services/attribute_renderer.js";
+import attributeService from "../../services/attributes.js";
const TPL = `