mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
fix inverse relation detection in relation maps
This commit is contained in:
parent
847766b434
commit
63ebb46049
@ -1,8 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
const Entity = require('./entity');
|
const Entity = require('./entity');
|
||||||
const dateUtils = require('../services/date_utils');
|
const dateUtils = require('../services/date_utils');
|
||||||
const sql = require('../services/sql');
|
const sql = require('../services/sql');
|
||||||
|
const promotedAttributeDefinitionParser = require("../services/promoted_attribute_definition_parser");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute is key value pair owned by a note.
|
* Attribute is key value pair owned by a note.
|
||||||
@ -61,6 +63,20 @@ class Attribute extends Entity {
|
|||||||
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
|
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDefinition() {
|
||||||
|
return promotedAttributeDefinitionParser.parse(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefinedName() {
|
||||||
|
if (this.type === 'label' && this.name.startsWith('label:')) {
|
||||||
|
return this.name.substr(6);
|
||||||
|
} else if (this.type === 'label' && this.name.startsWith('relation:')) {
|
||||||
|
return this.name.substr(9);
|
||||||
|
} else {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
beforeSaving() {
|
beforeSaving() {
|
||||||
if (!this.value) {
|
if (!this.value) {
|
||||||
if (this.type === 'relation') {
|
if (this.type === 'relation') {
|
||||||
|
@ -380,15 +380,15 @@ class Note extends Entity {
|
|||||||
return firstDefinitionIndex === index;
|
return firstDefinitionIndex === index;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const definitionAttr = attributes.find(el => el.type === attr.type + '-definition' && el.name === attr.name);
|
const definitionAttr = attributes.find(el => el.type === 'label' && el.name === attr.type + ':' + attr.name);
|
||||||
|
|
||||||
if (!definitionAttr) {
|
if (!definitionAttr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const definition = definitionAttr.value;
|
const definition = definitionAttr.getDefinition();
|
||||||
|
|
||||||
if (definition.multiplicityType === 'multi') {
|
if (definition.multiplicity === 'multi') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -868,6 +868,16 @@ class Note extends Entity {
|
|||||||
return notePaths;
|
return notePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRelationDefinitions() {
|
||||||
|
return this.getLabels()
|
||||||
|
.filter(l => l.name.startsWith("relation:"));
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabelDefinitions() {
|
||||||
|
return this.getLabels()
|
||||||
|
.filter(l => l.name.startsWith("relation:"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ancestorNoteId
|
* @param ancestorNoteId
|
||||||
* @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
|
* @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
|
||||||
|
@ -139,7 +139,7 @@ function getRelationMap(req) {
|
|||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
resp.noteTitles[note.noteId] = note.title;
|
resp.noteTitles[note.noteId] = note.title;
|
||||||
|
|
||||||
resp.relations = resp.relations.concat((note.getRelations())
|
resp.relations = resp.relations.concat(note.getRelations()
|
||||||
.filter(relation => noteIds.includes(relation.value))
|
.filter(relation => noteIds.includes(relation.value))
|
||||||
.map(relation => ({
|
.map(relation => ({
|
||||||
attributeId: relation.attributeId,
|
attributeId: relation.attributeId,
|
||||||
@ -149,8 +149,10 @@ function getRelationMap(req) {
|
|||||||
})));
|
})));
|
||||||
|
|
||||||
for (const relationDefinition of note.getRelationDefinitions()) {
|
for (const relationDefinition of note.getRelationDefinitions()) {
|
||||||
if (relationDefinition.value.inverseRelation) {
|
const def = relationDefinition.getDefinition();
|
||||||
resp.inverseRelations[relationDefinition.name] = relationDefinition.value.inverseRelation;
|
|
||||||
|
if (def.inverseRelation) {
|
||||||
|
resp.inverseRelations[relationDefinition.getDefinedName()] = def.inverseRelation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
src/services/promoted_attribute_definition_parser.js
Normal file
35
src/services/promoted_attribute_definition_parser.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
function parse(value) {
|
||||||
|
const tokens = value.split(',').map(t => t.trim());
|
||||||
|
const defObj = {};
|
||||||
|
|
||||||
|
for (const token of tokens) {
|
||||||
|
if (token === 'promoted') {
|
||||||
|
defObj.isPromoted = true;
|
||||||
|
}
|
||||||
|
else if (['text', 'number', 'boolean', 'date', 'url'].includes(token)) {
|
||||||
|
defObj.labelType = token;
|
||||||
|
}
|
||||||
|
else if (['single', 'multi'].includes(token)) {
|
||||||
|
defObj.multiplicity = token;
|
||||||
|
}
|
||||||
|
else if (token.startsWith('precision')) {
|
||||||
|
const chunks = token.split('=');
|
||||||
|
|
||||||
|
defObj.numberPrecision = parseInt(chunks[1]);
|
||||||
|
}
|
||||||
|
else if (token.startsWith('inverse')) {
|
||||||
|
const chunks = token.split('=');
|
||||||
|
|
||||||
|
defObj.inverseRelation = chunks[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("Unrecognized attribute definition token:", token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parse
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user