Merge branch 'stable'

# Conflicts:
#	src/services/build.js
This commit is contained in:
zadam 2023-04-09 23:30:41 +02:00
commit dba0c9f373
11 changed files with 80 additions and 21 deletions

View File

@ -96,7 +96,7 @@ class BAttribute extends AbstractBeccaEntity {
}
if (this.type === 'relation' && !(this.value in this.becca.notes)) {
throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it target not existing note '${this.value}'.`);
throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it targets not existing note '${this.value}'.`);
}
}

View File

@ -97,7 +97,7 @@ class BNote extends AbstractBeccaEntity {
* @private */
this.parents = [];
/** @type {BNote[]}
* @private*/
* @private */
this.children = [];
/** @type {BAttribute[]}
* @private */
@ -107,11 +107,11 @@ class BNote extends AbstractBeccaEntity {
* @private */
this.__attributeCache = null;
/** @type {BAttribute[]|null}
* @private*/
* @private */
this.inheritableAttributeCache = null;
/** @type {BAttribute[]}
* @private*/
* @private */
this.targetRelations = [];
this.becca.addNote(this.noteId, this);
@ -532,6 +532,20 @@ class BNote extends AbstractBeccaEntity {
*/
hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); }
/**
* @param {string} name - label name
* @returns {boolean} true if label exists (including inherited) and does not have "false" value.
*/
isLabelTruthy(name) {
const label = this.getLabel(name);
if (!label) {
return false;
}
return label && label.value !== 'false';
}
/**
* @param {string} name - label name
* @param {string} [value] - label value

View File

@ -595,6 +595,20 @@ class FNote {
*/
hasLabel(name) { return this.hasAttribute(LABEL, name); }
/**
* @param {string} name - label name
* @returns {boolean} true if label exists (including inherited) and does not have "false" value.
*/
isLabelTruthy(name) {
const label = this.getLabel(name);
if (!label) {
return false;
}
return label && label.value !== 'false';
}
/**
* @param {string} name - relation name
* @returns {boolean} true if relation exists (excluding inherited)

View File

@ -128,6 +128,10 @@ export default class DesktopLayout {
)
.child(
new RibbonContainer()
// order of the widgets matter. Some of these want to "activate" themselves
// when visible, when this happens to multiple of them, the first one "wins".
// promoted attributes should always win.
.ribbon(new PromotedAttributesWidget())
.ribbon(new ScriptExecutorWidget())
.ribbon(new SearchDefinitionWidget())
.ribbon(new EditedNotesWidget())
@ -135,7 +139,6 @@ export default class DesktopLayout {
.ribbon(new NotePropertiesWidget())
.ribbon(new FilePropertiesWidget())
.ribbon(new ImagePropertiesWidget())
.ribbon(new PromotedAttributesWidget())
.ribbon(new BasicPropertiesWidget())
.ribbon(new OwnedAttributeListWidget())
.ribbon(new InheritedAttributesWidget())

View File

@ -14,7 +14,7 @@ async function processEntityChanges(entityChanges) {
if (ec.entityName === 'notes') {
processNoteChange(loadResults, ec);
} else if (ec.entityName === 'branches') {
processBranchChange(loadResults, ec);
await processBranchChange(loadResults, ec);
} else if (ec.entityName === 'attributes') {
processAttributeChange(loadResults, ec);
} else if (ec.entityName === 'note_reordering') {
@ -105,7 +105,7 @@ function processNoteChange(loadResults, ec) {
}
}
function processBranchChange(loadResults, ec) {
async function processBranchChange(loadResults, ec) {
if (ec.isErased && ec.entityId in froca.branches) {
utils.reloadFrontendApp(`${ec.entityName} ${ec.entityId} is erased, need to do complete reload.`);
return;
@ -139,7 +139,15 @@ function processBranchChange(loadResults, ec) {
loadResults.addBranch(ec.entityId, ec.componentId);
const childNote = froca.notes[ec.entity.noteId];
const parentNote = froca.notes[ec.entity.parentNoteId];
let parentNote = froca.notes[ec.entity.parentNoteId];
if (childNote && !parentNote) {
// a branch cannot exist without the parent
// a note loaded into froca has to also contain all its ancestors
// this problem happened e.g. in sharing where _share was hidden and thus not loaded
// sharing meant cloning into _share, which crashed because _share was not loaded
parentNote = await froca.getNote(ec.entity.parentNoteId);
}
if (branch) {
branch.update(ec.entity);

View File

@ -65,7 +65,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.getActiveContext().setNote(notePath);
appContext.triggerEvent('focusAndSelectTitle');
await appContext.triggerEvent('focusAndSelectTitle');
};
/**
@ -82,7 +82,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
await appContext.tabManager.openContextWithNote(notePath, { activate });
if (activate) {
appContext.triggerEvent('focusAndSelectTitle');
await appContext.triggerEvent('focusAndSelectTitle');
}
};
@ -100,10 +100,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
const {ntxId} = subContexts[subContexts.length - 1];
appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
await appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
if (activate) {
appContext.triggerEvent('focusAndSelectTitle');
await appContext.triggerEvent('focusAndSelectTitle');
}
};

View File

@ -285,7 +285,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.$title = this.$widget.find('.attr-detail-title');
this.$inputName = this.$widget.find('.attr-input-name');
this.$inputName.on('keyup', () => this.userEditedAttribute());
this.$inputName.on('input', ev => {
if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812
this.userEditedAttribute();
}
});
this.$inputName.on('change', () => this.userEditedAttribute());
this.$inputName.on('autocomplete:closed', () => this.userEditedAttribute());
@ -299,7 +303,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.$rowValue = this.$widget.find('.attr-row-value');
this.$inputValue = this.$widget.find('.attr-input-value');
this.$inputValue.on('keyup', () => this.userEditedAttribute());
this.$inputValue.on('input', ev => {
if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812
this.userEditedAttribute();
}
});
this.$inputValue.on('change', () => this.userEditedAttribute());
this.$inputValue.on('autocomplete:closed', () => this.userEditedAttribute());
this.$inputValue.on('focus', () => {
@ -328,7 +336,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.$rowInverseRelation = this.$widget.find('.attr-row-inverse-relation');
this.$inputInverseRelation = this.$widget.find('.attr-input-inverse-relation');
this.$inputInverseRelation.on('keyup', () => this.userEditedAttribute());
this.$inputInverseRelation.on('input', ev => {
if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812
this.userEditedAttribute();
}
});
this.$rowTargetNote = this.$widget.find('.attr-row-target-note');
this.$inputTargetNote = this.$widget.find('.attr-input-target-note');

View File

@ -63,7 +63,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget {
return {
show: true,
activate: true,
title: "Promoted attributes",
title: "Promoted Attributes",
icon: "bx bx-table"
};
}

View File

@ -180,7 +180,7 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
return {
show: this.isEnabled(),
activate: true,
title: 'Search parameters',
title: 'Search Parameters',
icon: 'bx bx-search'
};
}

View File

@ -39,7 +39,14 @@ export default class SharedInfoWidget extends NoteContextAwareWidget {
this.$sharedText.text("This note is shared publicly on");
}
else {
link = `${location.protocol}//${location.host}${location.pathname}share/${shareId}`;
let host = location.host;
if (host.endsWith('/')) {
// seems like IE has trailing slash
// https://github.com/zadam/trilium/issues/3782
host = host.substr(0, host.length - 1);
}
link = `${location.protocol}//${host}${location.pathname}share/${shareId}`;
this.$sharedText.text("This note is shared locally on");
}

View File

@ -23,7 +23,7 @@ const ValidationError = require("../errors/validation_error");
const noteTypesService = require("./note_types");
function getNewNotePosition(parentNote) {
if (parentNote.hasLabel('newNotesOnTop')) {
if (parentNote.isLabelTruthy('newNotesOnTop')) {
const minNotePos = parentNote.getChildBranches()
.reduce((min, note) => Math.min(min, note.notePosition), 0);
@ -841,7 +841,7 @@ function duplicateSubtree(origNoteId, newParentNoteId) {
throw new Error('Duplicating root is not possible');
}
log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`);
log.info(`Duplicating '${origNoteId}' subtree into '${newParentNoteId}'`);
const origNote = becca.notes[origNoteId];
// might be null if orig note is not in the target newParentNoteId
@ -919,7 +919,8 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
attr.value = noteIdMapping[attr.value];
}
attr.save();
// the relation targets may not be created yet, the mapping is pre-generated
attr.save({skipValidation: true});
}
for (const childBranch of origNote.getChildBranches()) {