Compare commits

...

8 Commits

Author SHA1 Message Date
zadam
fbdf089d5d release 0.44.1-beta 2020-09-05 23:43:06 +02:00
zadam
a7505682ed more compact note revisions widget 2020-09-05 23:35:24 +02:00
zadam
b148f3d032 more compact note info widget 2020-09-05 22:49:30 +02:00
zadam
874972a3d3 fix broken what links here widget 2020-09-05 22:45:26 +02:00
zadam
6d095b7250 fix popups/tooltips not disappearing after loading new note, closes #1214 2020-09-05 21:51:00 +02:00
zadam
ceb762e56b fix zen mode with attributes, closes #1213 2020-09-04 23:35:10 +02:00
zadam
0c72d29684 fix zen mode with attributes, closes #1213 2020-09-04 22:54:50 +02:00
zadam
29efe3a492 fix showing a search box, closes #1212 2020-09-04 21:10:54 +02:00
22 changed files with 164 additions and 93 deletions

View File

@@ -2,7 +2,7 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.44.0-beta",
"version": "0.44.1-beta",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {

View File

@@ -481,6 +481,17 @@ class NoteShort {
.map(attributeId => this.treeCache.attributes[attributeId]);
}
/**
* Get relations which target this note
*
* @returns {NoteShort[]}
*/
async getTargetRelationSourceNotes() {
const targetRelations = this.getTargetRelations();
return await this.treeCache.getNotes(targetRelations.map(tr => tr.noteId));
}
/**
* Return note complement which is most importantly note's content
*

View File

@@ -15,7 +15,6 @@ import AttributeListWidget from "../widgets/attribute_list.js";
import RunScriptButtonsWidget from "../widgets/run_script_buttons.js";
import NoteTypeWidget from "../widgets/note_type.js";
import NoteActionsWidget from "../widgets/note_actions.js";
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import NoteDetailWidget from "../widgets/note_detail.js";
import NoteInfoWidget from "../widgets/collapsible_widgets/note_info.js";
import CalendarWidget from "../widgets/collapsible_widgets/calendar.js";

View File

@@ -11,19 +11,15 @@ function renderAttribute(attribute, $container, renderIsInheritable) {
$container.append('=');
$container.append(document.createTextNode(formatValue(attribute.value)));
}
$container.append(" ");
} else if (attribute.type === 'relation') {
if (attribute.isAutoLink) {
return;
}
// when the relation has just been created then it might not have a value
if (attribute.value) {
$container.append(document.createTextNode('~' + attribute.name + isInheritable + "="));
$container.append(createNoteLink(attribute.value));
$container.append(" ");
} else {
ws.logError(`Relation ${attribute.attributeId} has empty target`);
}
} else {
ws.logError("Unknown attr type: " + attribute.type);

View File

@@ -219,4 +219,16 @@ export default class Entrypoints extends Component {
toastService.showMessage("Note executed");
}
hideAllTooltips() {
$(".tooltip").removeClass("show");
}
tabNoteSwitchedEvent() {
this.hideAllTooltips();
}
activeTabChangedEvent() {
this.hideAllTooltips();
}
}

View File

@@ -3,7 +3,6 @@ import noteCreateService from "./note_create.js";
import treeService from "./tree.js";
import hoistedNoteService from "./hoisted_note.js";
import Component from "../widgets/component.js";
import ws from "./ws.js";
/**
* This class contains command executors which logically belong to the NoteTree widget, but for better user experience

View File

@@ -141,7 +141,7 @@ class TreeCache {
const note = this.notes[attributeRow.noteId];
if (!note.attributes.includes(attributeId)) {
if (note && !note.attributes.includes(attributeId)) {
note.attributes.push(attributeId);
}

View File

@@ -230,6 +230,7 @@ function closeActiveDialog() {
let $lastFocusedElement = null;
// perhaps there should be saved focused element per tab?
function saveFocusedElement() {
$lastFocusedElement = $(":focus");
}

View File

@@ -156,7 +156,9 @@ async function consumeSyncData() {
logError(`Encountered error ${e.message}: ${e.stack}, reloading frontend.`);
// if there's an error in updating the frontend then the easy option to recover is to reload the frontend completely
utils.reloadApp();
if (!glob.isDev) {
utils.reloadApp();
}
}
for (const syncRow of nonProcessedSyncRows) {

View File

@@ -215,7 +215,9 @@ const ATTR_HELP = {
export default class AttributeDetailWidget extends TabAwareWidget {
async refresh() {
// this widget is not activated in a standard way
// switching note/tab should close the widget
this.hide();
}
doRender() {
@@ -327,46 +329,6 @@ export default class AttributeDetailWidget extends TabAwareWidget {
});
}
async saveAndClose() {
await this.triggerCommand('saveAttributes');
this.hide();
this.triggerCommand('focusOnAttributes', {tabId: this.tabContext.tabId});
}
async cancelAndClose() {
await this.triggerCommand('reloadAttributes');
this.hide();
this.triggerCommand('focusOnAttributes', {tabId: this.tabContext.tabId});
}
userEditedAttribute() {
this.updateAttributeInEditor();
this.updateHelp();
this.relatedNotesSpacedUpdate.scheduleUpdate();
}
updateHelp() {
const attrName = this.$inputName.val();
if (this.attrType in ATTR_HELP && attrName in ATTR_HELP[this.attrType]) {
this.$attrHelp
.empty()
.append($("<td colspan=2>")
.append($("<strong>").text(attrName))
.append(" - ")
.append(ATTR_HELP[this.attrType][attrName])
)
.show();
}
else {
this.$attrHelp.empty().hide();
}
}
async showAttributeDetail({allAttributes, attribute, isOwned, x, y, focus}) {
if (!attribute) {
this.hide();
@@ -374,6 +336,8 @@ export default class AttributeDetailWidget extends TabAwareWidget {
return;
}
utils.saveFocusedElement();
this.attrType = this.getAttrType(attribute);
const attrName =
@@ -444,12 +408,20 @@ export default class AttributeDetailWidget extends TabAwareWidget {
.attr('readonly', () => !isOwned);
}
else if (attribute.type === 'relation') {
const targetNote = await treeCache.getNote(attribute.value);
this.$inputTargetNote
.attr('readonly', () => !isOwned)
.val(targetNote ? targetNote.title : "")
.setSelectedNotePath(attribute.value);
.val("")
.setSelectedNotePath("");
if (attribute.value) {
const targetNote = await treeCache.getNote(attribute.value);
if (targetNote) {
this.$inputTargetNote
.val(targetNote ? targetNote.title : "")
.setSelectedNotePath(attribute.value);
}
}
}
this.$inputInheritable
@@ -497,6 +469,46 @@ export default class AttributeDetailWidget extends TabAwareWidget {
return {left, right};
}
async saveAndClose() {
await this.triggerCommand('saveAttributes');
this.hide();
utils.focusSavedElement();
}
async cancelAndClose() {
await this.triggerCommand('reloadAttributes');
this.hide();
utils.focusSavedElement();
}
userEditedAttribute() {
this.updateAttributeInEditor();
this.updateHelp();
this.relatedNotesSpacedUpdate.scheduleUpdate();
}
updateHelp() {
const attrName = this.$inputName.val();
if (this.attrType in ATTR_HELP && attrName in ATTR_HELP[this.attrType]) {
this.$attrHelp
.empty()
.append($("<td colspan=2>")
.append($("<strong>").text(attrName))
.append(" - ")
.append(ATTR_HELP[this.attrType][attrName])
)
.show();
}
else {
this.$attrHelp.empty().hide();
}
}
async updateRelatedNotes() {
let {results, count} = await server.post('search-related', this.attribute);

View File

@@ -232,13 +232,17 @@ export default class AttributeEditorWidget extends TabAwareWidget {
}
// triggered from keyboard shortcut
addNewLabelEvent() {
this.handleAddNewAttributeCommand('addNewLabel');
addNewLabelEvent({tabId}) {
if (this.isTab(tabId)) {
this.handleAddNewAttributeCommand('addNewLabel');
}
}
// triggered from keyboard shortcut
addNewRelationEvent() {
this.handleAddNewAttributeCommand('addNewRelation');
addNewRelationEvent({tabId}) {
if (this.isTab(tabId)) {
this.handleAddNewAttributeCommand('addNewRelation');
}
}
async handleAddNewAttributeCommand(command) {
@@ -459,11 +463,17 @@ export default class AttributeEditorWidget extends TabAwareWidget {
}
async renderOwnedAttributes(ownedAttributes, saved) {
ownedAttributes = ownedAttributes.filter(oa => !oa.isDeleted);
const $attributesContainer = $("<div>");
for (const attribute of ownedAttributes) {
if (!attribute.isDeleted) {
attributeRenderer.renderAttribute(attribute, $attributesContainer, true);
for (let i = 0; i < ownedAttributes.length; i++) {
const attribute = ownedAttributes[i];
attributeRenderer.renderAttribute(attribute, $attributesContainer, true);
if (i < ownedAttributes.length - 1) {
$attributesContainer.append(" ");
}
}

View File

@@ -220,9 +220,9 @@ export default class AttributeListWidget extends TabAwareWidget {
y: e.pageY
}));
$container.append($span);
attributeRenderer.renderAttribute(attribute, $span, false);
$container.append($span);
}
}

View File

@@ -4,7 +4,10 @@ const TPL = `
<table class="note-info-widget-table">
<style>
.note-info-widget-table {
width: 100%;
max-width: 100%;
display: block;
overflow-x: auto;
white-space: nowrap;
}
.note-info-widget-table td, .note-info-widget-table th {
@@ -22,16 +25,6 @@ const TPL = `
<tr>
<th>Note ID:</th>
<td class="note-info-note-id"></td>
</tr>
<tr>
<th>Created:</th>
<td class="note-info-date-created"></td>
</tr>
<tr>
<th>Modified:</th>
<td class="note-info-date-modified"></td>
</tr>
<tr>
<th>Type:</th>
<td>
<span class="note-info-type"></span>
@@ -39,6 +32,12 @@ const TPL = `
<span class="note-info-mime"></span>
</td>
</tr>
<tr>
<th>Created:</th>
<td class="note-info-date-created"></td>
<th>Modified:</th>
<td class="note-info-date-modified"></td>
</tr>
</table>
`;

View File

@@ -46,6 +46,8 @@ class NoteRevisionsWidget extends CollapsibleWidget {
return;
}
const groupedRevisionItems = this.getGroupedRevisionItems(revisionItems);
if (note.noteId !== this.noteId) {
return;
}
@@ -54,23 +56,47 @@ class NoteRevisionsWidget extends CollapsibleWidget {
const $list = this.$body.find('.note-revision-list');
for (const item of revisionItems) {
const $listItem = $('<li>').append($("<a>", {
'data-action': 'note-revision',
'data-note-path': note.noteId,
'data-note-revision-id': item.noteRevisionId,
title: 'This revision was last edited on ' + item.dateLastEdited,
href: 'javascript:'
}).text(item.dateLastEdited.substr(0, 16)));
for (const [date, items] of groupedRevisionItems) {
const $listItem = $('<li>').append($("<strong>").text(date + ": "));
const revsWithinADay = [];
if (item.contentLength !== null) {
$listItem.append($("<span>").text(` (${item.contentLength} bytes)`))
for (const item of items) {
const $rev = $("<span>");
$rev.append($("<a>", {
'data-action': 'note-revision',
'data-note-path': note.noteId,
'data-note-revision-id': item.noteRevisionId,
title: 'This revision was last edited on ' + item.dateLastEdited,
href: 'javascript:'
})
.text(item.dateLastEdited.substr(11, 5)));
revsWithinADay.push($rev.html());
}
$listItem.append(revsWithinADay.join(", "));
$list.append($listItem);
}
}
getGroupedRevisionItems(revisionItems) {
const grouped = new Map(); // map preserves order of insertion
for (const item of revisionItems) {
const [date] = item.dateLastEdited.substr(0, 16).split(" ");
if (!grouped.has(date)) {
grouped.set(date, []);
}
grouped.get(date).push(item);
}
return grouped;
}
entitiesReloadedEvent({loadResults}) {
if (loadResults.hasNoteRevisionForNote(this.noteId)) {
this.refresh();

View File

@@ -66,4 +66,4 @@ export default class SimilarNotesWidget extends CollapsibleWidget {
this.refresh();
}
}
}
}

View File

@@ -53,4 +53,4 @@ export default class WhatLinksHereWidget extends CollapsibleWidget {
this.refresh();
}
}
}
}

View File

@@ -9,6 +9,7 @@ const TPL = `
<style>
.note-title-container {
flex-grow: 100;
height: 34px;
}
.note-title-container input.note-title {

View File

@@ -905,6 +905,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
async refresh() {
this.toggleInt(this.isEnabled());
this.$treeSettingsPopup.hide();
this.activityDetected();

View File

@@ -122,7 +122,9 @@ export default class SearchBoxWidget extends BasicWidget {
this.resetSearchEvent();
}
showSearchEvent({searchText}) {
showSearchEvent(data = {}) {
const {searchText} = data;
utils.saveFocusedElement();
this.$searchBox.slideDown();

View File

@@ -38,7 +38,8 @@ function getNotesAndBranchesAndAttributes(noteIds) {
position,
isInheritable
FROM attributes
WHERE isDeleted = 0 AND noteId IN (???)`, noteIds);
WHERE isDeleted = 0
AND (noteId IN (???) OR (type = 'relation' AND value IN (???)))`, noteIds);
// sorting in memory is faster
attributes.sort((a, b) => a.position - b.position < 0 ? -1 : 1);

View File

@@ -10,7 +10,6 @@ const repository = require('./repository');
const axios = require('axios');
const dayjs = require('dayjs');
const cloningService = require('./cloning');
const ws = require('./ws.js');
const appInfo = require('./app_info');
const searchService = require('./search/services/search.js');
@@ -88,7 +87,7 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString
@@ -98,7 +97,7 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString

View File

@@ -1 +1 @@
module.exports = { buildDate:"2020-09-03T23:26:51+02:00", buildRevision: "11c63b7778011130b2a88b7896d52d0a476983d1" };
module.exports = { buildDate:"2020-09-05T23:43:06+02:00", buildRevision: "a7505682eddb754f0ba951716f63f9e9ffe61131" };