mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
Merge branch 'master' into m41
# Conflicts: # src/public/javascripts/dialogs/add_link.js # src/public/javascripts/dialogs/export.js # src/public/javascripts/dialogs/import.js # src/public/javascripts/dialogs/note_info.js # src/public/javascripts/services/search_notes.js
This commit is contained in:
commit
4401a8e1e8
@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.40.2",
|
"version": "0.40.3",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -811,8 +811,10 @@ class Note extends Entity {
|
|||||||
FROM attributes
|
FROM attributes
|
||||||
WHERE noteId = ? AND
|
WHERE noteId = ? AND
|
||||||
isDeleted = 0 AND
|
isDeleted = 0 AND
|
||||||
type = 'relation' AND
|
((type = 'relation' AND
|
||||||
name IN ('internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink')`, [this.noteId]);
|
name IN ('internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'))
|
||||||
|
OR
|
||||||
|
(type = 'label' AND name = 'externalLink'))`, [this.noteId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,8 +10,6 @@ const $buildRevision = $("#build-revision");
|
|||||||
const $dataDirectory = $("#data-directory");
|
const $dataDirectory = $("#data-directory");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
const appInfo = await server.get('app-info');
|
const appInfo = await server.get('app-info');
|
||||||
|
|
||||||
$appVersion.text(appInfo.appVersion);
|
$appVersion.text(appInfo.appVersion);
|
||||||
@ -22,7 +20,5 @@ export async function showDialog() {
|
|||||||
$buildRevision.attr('href', 'https://github.com/zadam/trilium/commit/' + appInfo.buildRevision);
|
$buildRevision.attr('href', 'https://github.com/zadam/trilium/commit/' + appInfo.buildRevision);
|
||||||
$dataDirectory.text(appInfo.dataDirectory);
|
$dataDirectory.text(appInfo.dataDirectory);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
}
|
}
|
@ -10,8 +10,6 @@ const $linkTitle = $("#link-title");
|
|||||||
const $addLinkTitleFormGroup = $("#add-link-title-form-group");
|
const $addLinkTitleFormGroup = $("#add-link-title-form-group");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
appContext.trigger('executeInActiveEditor', {
|
appContext.trigger('executeInActiveEditor', {
|
||||||
callback: textEditor => {
|
callback: textEditor => {
|
||||||
const hasSelection = !textEditor.model.document.selection.isCollapsed;
|
const hasSelection = !textEditor.model.document.selection.isCollapsed;
|
||||||
@ -20,9 +18,7 @@ export async function showDialog() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
$autoComplete.val('').trigger('focus');
|
$autoComplete.val('').trigger('focus');
|
||||||
$linkTitle.val('');
|
$linkTitle.val('');
|
||||||
|
@ -279,8 +279,6 @@ function initKoPlugins() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
await libraryLoader.requireLibrary(libraryLoader.KNOCKOUT);
|
await libraryLoader.requireLibrary(libraryLoader.KNOCKOUT);
|
||||||
|
|
||||||
// lazily apply bindings on first use
|
// lazily apply bindings on first use
|
||||||
@ -292,11 +290,9 @@ export async function showDialog() {
|
|||||||
ko.applyBindings(attributesModel, $dialog[0]);
|
ko.applyBindings(attributesModel, $dialog[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
await attributesModel.loadAttributes();
|
await attributesModel.loadAttributes();
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dialog.on('focus', '.attribute-name', function (e) {
|
$dialog.on('focus', '.attribute-name', function (e) {
|
||||||
|
@ -6,11 +6,7 @@ const $backendLogTextArea = $("#backend-log-textarea");
|
|||||||
const $refreshBackendLog = $("#refresh-backend-log-button");
|
const $refreshBackendLog = $("#refresh-backend-log-button");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,6 @@ const $noteTitle = $('#branch-prefix-note-title');
|
|||||||
let branchId;
|
let branchId;
|
||||||
|
|
||||||
export async function showDialog(node) {
|
export async function showDialog(node) {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
branchId = node.data.branchId;
|
branchId = node.data.branchId;
|
||||||
const branch = treeCache.getBranch(branchId);
|
const branch = treeCache.getBranch(branchId);
|
||||||
|
|
||||||
@ -29,7 +25,7 @@ export async function showDialog(node) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$treePrefixInput.val(branch.prefix);
|
$treePrefixInput.val(branch.prefix);
|
||||||
|
|
||||||
|
@ -22,11 +22,7 @@ export async function showDialog(noteIds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
$noteAutoComplete.val('').trigger('focus');
|
$noteAutoComplete.val('').trigger('focus');
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ let taskId = '';
|
|||||||
let branchId = null;
|
let branchId = null;
|
||||||
|
|
||||||
export async function showDialog(notePath, defaultType) {
|
export async function showDialog(notePath, defaultType) {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
// each opening of the dialog resets the taskId so we don't associate it with previous exports anymore
|
// each opening of the dialog resets the taskId so we don't associate it with previous exports anymore
|
||||||
taskId = '';
|
taskId = '';
|
||||||
$exportButton.removeAttr("disabled");
|
$exportButton.removeAttr("disabled");
|
||||||
@ -39,9 +37,7 @@ export async function showDialog(notePath, defaultType) {
|
|||||||
|
|
||||||
$("#opml-v2").prop("checked", true); // setting default
|
$("#opml-v2").prop("checked", true); // setting default
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
const {noteId, parentNoteId} = treeService.getNoteIdAndParentIdFromNotePath(notePath);
|
const {noteId, parentNoteId} = treeService.getNoteIdAndParentIdFromNotePath(notePath);
|
||||||
|
|
||||||
|
@ -3,9 +3,5 @@ import utils from "../services/utils.js";
|
|||||||
const $dialog = $("#help-dialog");
|
const $dialog = $("#help-dialog");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
}
|
}
|
@ -16,8 +16,6 @@ const $explodeArchivesCheckbox = $("#explode-archives-checkbox");
|
|||||||
let parentNoteId = null;
|
let parentNoteId = null;
|
||||||
|
|
||||||
export async function showDialog(noteId) {
|
export async function showDialog(noteId) {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
$fileUploadInput.val('').trigger('change'); // to trigger Import button disabling listener below
|
$fileUploadInput.val('').trigger('change'); // to trigger Import button disabling listener below
|
||||||
|
|
||||||
$safeImportCheckbox.prop("checked", true);
|
$safeImportCheckbox.prop("checked", true);
|
||||||
@ -26,13 +24,11 @@ export async function showDialog(noteId) {
|
|||||||
$codeImportedAsCodeCheckbox.prop("checked", true);
|
$codeImportedAsCodeCheckbox.prop("checked", true);
|
||||||
$explodeArchivesCheckbox.prop("checked", true);
|
$explodeArchivesCheckbox.prop("checked", true);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
parentNoteId = noteId;
|
parentNoteId = noteId;
|
||||||
|
|
||||||
$noteTitle.text(await treeService.getNoteTitle(parentNoteId));
|
$noteTitle.text(await treeService.getNoteTitle(parentNoteId));
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
$form.on('submit', () => {
|
$form.on('submit', () => {
|
||||||
|
@ -10,13 +10,9 @@ let callback = null;
|
|||||||
export async function showDialog(cb) {
|
export async function showDialog(cb) {
|
||||||
callback = cb;
|
callback = cb;
|
||||||
|
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$autoComplete.val('');
|
$autoComplete.val('');
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true });
|
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true });
|
||||||
noteAutocompleteService.showRecentNotes($autoComplete);
|
noteAutocompleteService.showRecentNotes($autoComplete);
|
||||||
|
@ -10,13 +10,9 @@ let $originallyFocused; // element focused before the dialog was opened so we ca
|
|||||||
export function info(message) {
|
export function info(message) {
|
||||||
$originallyFocused = $(':focus');
|
$originallyFocused = $(':focus');
|
||||||
|
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$infoContent.text(message);
|
$infoContent.text(message);
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
return new Promise((res, rej) => { resolve = res; });
|
return new Promise((res, rej) => { resolve = res; });
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,9 @@ const $autoComplete = $("#jump-to-note-autocomplete");
|
|||||||
const $showInFullTextButton = $("#show-in-full-text-button");
|
const $showInFullTextButton = $("#show-in-full-text-button");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$autoComplete.val('');
|
$autoComplete.val('');
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true })
|
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true })
|
||||||
.on('autocomplete:selected', function(event, suggestion, dataset) {
|
.on('autocomplete:selected', function(event, suggestion, dataset) {
|
||||||
|
@ -16,10 +16,6 @@ function getOptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
// set default settings
|
// set default settings
|
||||||
$maxNotesInput.val(20);
|
$maxNotesInput.val(20);
|
||||||
|
|
||||||
@ -27,7 +23,7 @@ export async function showDialog() {
|
|||||||
|
|
||||||
$linkMapContainer.empty();
|
$linkMapContainer.empty();
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dialog.on('shown.bs.modal', () => {
|
$dialog.on('shown.bs.modal', () => {
|
||||||
|
@ -40,9 +40,7 @@ export async function importMarkdownInline() {
|
|||||||
convertMarkdownToHtml(text);
|
convertMarkdownToHtml(text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glob.activeDialog = $dialog;
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,11 +15,7 @@ let movedNodes;
|
|||||||
export async function showDialog(nodes) {
|
export async function showDialog(nodes) {
|
||||||
movedNodes = nodes;
|
movedNodes = nodes;
|
||||||
|
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
$noteAutoComplete.val('').trigger('focus');
|
$noteAutoComplete.val('').trigger('focus');
|
||||||
|
|
||||||
|
@ -10,11 +10,7 @@ const $mime = $("#note-info-mime");
|
|||||||
const $okButton = $("#note-info-ok-button");
|
const $okButton = $("#note-info-ok-button");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
const activeTabContext = appContext.tabManager.getActiveTabContext();
|
const activeTabContext = appContext.tabManager.getActiveTabContext();
|
||||||
const {note} = activeTabContext;
|
const {note} = activeTabContext;
|
||||||
|
@ -29,11 +29,7 @@ export async function showCurrentNoteRevisions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function showNoteRevisionsDialog(noteId, noteRevisionId) {
|
export async function showNoteRevisionsDialog(noteId, noteRevisionId) {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
await loadNoteRevisions(noteId, noteRevisionId);
|
await loadNoteRevisions(noteId, noteRevisionId);
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,7 @@ const $dialog = $("#note-source-dialog");
|
|||||||
const $noteSource = $("#note-source");
|
const $noteSource = $("#note-source");
|
||||||
|
|
||||||
export function showDialog() {
|
export function showDialog() {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
const noteText = appContext.tabManager.getActiveTabNote().content;
|
const noteText = appContext.tabManager.getActiveTabNote().content;
|
||||||
|
|
||||||
|
@ -6,13 +6,9 @@ import utils from "../services/utils.js";
|
|||||||
const $dialog = $("#options-dialog");
|
const $dialog = $("#options-dialog");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
const options = await server.get('options');
|
const options = await server.get('options');
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
(await Promise.all([
|
(await Promise.all([
|
||||||
import('./options/advanced.js'),
|
import('./options/advanced.js'),
|
||||||
|
@ -12,10 +12,6 @@ let resolve;
|
|||||||
let shownCb;
|
let shownCb;
|
||||||
|
|
||||||
export function ask({ message, defaultValue, shown }) {
|
export function ask({ message, defaultValue, shown }) {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
shownCb = shown;
|
shownCb = shown;
|
||||||
|
|
||||||
$question = $("<label>")
|
$question = $("<label>")
|
||||||
@ -34,7 +30,7 @@ export function ask({ message, defaultValue, shown }) {
|
|||||||
.append($question)
|
.append($question)
|
||||||
.append($answer));
|
.append($answer));
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
return new Promise((res, rej) => { resolve = res; });
|
return new Promise((res, rej) => { resolve = res; });
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import protectedSessionService from "../services/protected_session.js";
|
import protectedSessionService from "../services/protected_session.js";
|
||||||
|
import utils from "../services/utils.js";
|
||||||
|
|
||||||
const $dialog = $("#protected-session-password-dialog");
|
const $dialog = $("#protected-session-password-dialog");
|
||||||
const $passwordForm = $dialog.find(".protected-session-password-form");
|
const $passwordForm = $dialog.find(".protected-session-password-form");
|
||||||
const $passwordInput = $dialog.find(".protected-session-password");
|
const $passwordInput = $dialog.find(".protected-session-password");
|
||||||
|
|
||||||
export function show() {
|
export function show() {
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
$passwordInput.trigger('focus');
|
$passwordInput.trigger('focus');
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,7 @@ const $dialog = $("#recent-changes-dialog");
|
|||||||
const $content = $("#recent-changes-content");
|
const $content = $("#recent-changes-content");
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
$dialog.modal();
|
|
||||||
|
|
||||||
const result = await server.get('recent-changes');
|
const result = await server.get('recent-changes');
|
||||||
|
|
||||||
|
@ -14,13 +14,9 @@ let codeEditor;
|
|||||||
$dialog.on("shown.bs.modal", e => initEditor());
|
$dialog.on("shown.bs.modal", e => initEditor());
|
||||||
|
|
||||||
export async function showDialog() {
|
export async function showDialog() {
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
|
||||||
|
|
||||||
await showTableSchemas();
|
await showTableSchemas();
|
||||||
|
|
||||||
$dialog.modal();
|
utils.openDialog($dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initEditor() {
|
async function initEditor() {
|
||||||
|
@ -66,6 +66,11 @@ class TreeContextMenu {
|
|||||||
!isHoisted || !isNotRoot ? null : { title: 'Unhoist note <kbd data-kb-action="ToggleNoteHoisting"></kbd>', cmd: "unhoist", uiIcon: "arrow-up" },
|
!isHoisted || !isNotRoot ? null : { title: 'Unhoist note <kbd data-kb-action="ToggleNoteHoisting"></kbd>', cmd: "unhoist", uiIcon: "arrow-up" },
|
||||||
{ title: 'Edit branch prefix <kbd data-kb-action="EditBranchPrefix"></kbd>', cmd: "editBranchPrefix", uiIcon: "empty",
|
{ title: 'Edit branch prefix <kbd data-kb-action="EditBranchPrefix"></kbd>', cmd: "editBranchPrefix", uiIcon: "empty",
|
||||||
enabled: isNotRoot && parentNotSearch && noSelectedNotes},
|
enabled: isNotRoot && parentNotSearch && noSelectedNotes},
|
||||||
|
{ title: "Advanced", uiIcon: "empty", enabled: true, items: [
|
||||||
|
{ title: 'Collapse subtree <kbd data-kb-action="CollapseSubtree"></kbd>', cmd: "collapseSubtree", uiIcon: "align-justify", enabled: noSelectedNotes },
|
||||||
|
{ title: "Force note sync", cmd: "forceNoteSync", uiIcon: "recycle", enabled: noSelectedNotes },
|
||||||
|
{ title: 'Sort alphabetically <kbd data-kb-action="SortChildNotes"></kbd>', cmd: "sortAlphabetically", uiIcon: "empty", enabled: noSelectedNotes && notSearch }
|
||||||
|
] },
|
||||||
{ title: "----" },
|
{ title: "----" },
|
||||||
{ title: "Protect subtree", cmd: "protectSubtree", uiIcon: "check-shield", enabled: noSelectedNotes },
|
{ title: "Protect subtree", cmd: "protectSubtree", uiIcon: "check-shield", enabled: noSelectedNotes },
|
||||||
{ title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes },
|
{ title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes },
|
||||||
@ -88,12 +93,7 @@ class TreeContextMenu {
|
|||||||
{ title: "Export", cmd: "export", uiIcon: "empty",
|
{ title: "Export", cmd: "export", uiIcon: "empty",
|
||||||
enabled: notSearch && noSelectedNotes },
|
enabled: notSearch && noSelectedNotes },
|
||||||
{ title: "Import into note", cmd: "importIntoNote", uiIcon: "empty",
|
{ title: "Import into note", cmd: "importIntoNote", uiIcon: "empty",
|
||||||
enabled: notSearch && noSelectedNotes },
|
enabled: notSearch && noSelectedNotes }
|
||||||
{ title: "Advanced", uiIcon: "empty", enabled: true, items: [
|
|
||||||
{ title: 'Collapse subtree <kbd data-kb-action="CollapseSubtree"></kbd>', cmd: "collapseSubtree", uiIcon: "align-justify", enabled: noSelectedNotes },
|
|
||||||
{ title: "Force note sync", cmd: "forceNoteSync", uiIcon: "recycle", enabled: noSelectedNotes },
|
|
||||||
{ title: 'Sort alphabetically <kbd data-kb-action="SortChildNotes"></kbd>', cmd: "sortAlphabetically", uiIcon: "empty", enabled: noSelectedNotes && notSearch }
|
|
||||||
] },
|
|
||||||
].filter(row => row !== null);
|
].filter(row => row !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,9 +209,50 @@ function getMimeTypeClass(mime) {
|
|||||||
function closeActiveDialog() {
|
function closeActiveDialog() {
|
||||||
if (glob.activeDialog) {
|
if (glob.activeDialog) {
|
||||||
glob.activeDialog.modal('hide');
|
glob.activeDialog.modal('hide');
|
||||||
|
glob.activeDialog = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let $lastFocusedElement = null;
|
||||||
|
|
||||||
|
function saveFocusedElement() {
|
||||||
|
$lastFocusedElement = $(":focus");
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusSavedElement() {
|
||||||
|
if (!$lastFocusedElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lastFocusedElement.hasClass("ck")) {
|
||||||
|
// must handle CKEditor separately because of this bug: https://github.com/ckeditor/ckeditor5/issues/607
|
||||||
|
|
||||||
|
import("./note_detail.js").then(noteDetail => {
|
||||||
|
noteDetail.default.getActiveEditor().editing.view.focus();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$lastFocusedElement.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastFocusedElement = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDialog($dialog) {
|
||||||
|
closeActiveDialog();
|
||||||
|
|
||||||
|
glob.activeDialog = $dialog;
|
||||||
|
|
||||||
|
saveFocusedElement();
|
||||||
|
|
||||||
|
$dialog.modal();
|
||||||
|
|
||||||
|
$dialog.on('hidden.bs.modal', () => {
|
||||||
|
if (!glob.activeDialog || glob.activeDialog === $dialog) {
|
||||||
|
focusSavedElement();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function isHtmlEmpty(html) {
|
function isHtmlEmpty(html) {
|
||||||
html = html.toLowerCase();
|
html = html.toLowerCase();
|
||||||
|
|
||||||
@ -281,6 +322,9 @@ export default {
|
|||||||
getNoteTypeClass,
|
getNoteTypeClass,
|
||||||
getMimeTypeClass,
|
getMimeTypeClass,
|
||||||
closeActiveDialog,
|
closeActiveDialog,
|
||||||
|
openDialog,
|
||||||
|
saveFocusedElement,
|
||||||
|
focusSavedElement,
|
||||||
isHtmlEmpty,
|
isHtmlEmpty,
|
||||||
clearBrowserCache,
|
clearBrowserCache,
|
||||||
getUrlForDownload,
|
getUrlForDownload,
|
||||||
|
@ -69,7 +69,19 @@ export default class AttributesWidget extends CollapsibleWidget {
|
|||||||
async renderAttributes(attributes, $container) {
|
async renderAttributes(attributes, $container) {
|
||||||
for (const attribute of attributes) {
|
for (const attribute of attributes) {
|
||||||
if (attribute.type === 'label') {
|
if (attribute.type === 'label') {
|
||||||
|
if (attribute.name === 'externalLink') {
|
||||||
|
$container.append('@' + attribute.name + "=");
|
||||||
|
$container.append(
|
||||||
|
$('<a>')
|
||||||
|
.text(attribute.value)
|
||||||
|
.attr('href', attribute.value)
|
||||||
|
.addClass('external')
|
||||||
|
);
|
||||||
|
$container.append(" ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
$container.append(utils.formatLabel(attribute) + " ");
|
$container.append(utils.formatLabel(attribute) + " ");
|
||||||
|
}
|
||||||
} else if (attribute.type === 'relation') {
|
} else if (attribute.type === 'relation') {
|
||||||
if (attribute.value) {
|
if (attribute.value) {
|
||||||
$container.append('@' + attribute.name + "=");
|
$container.append('@' + attribute.name + "=");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const attributeService = require("../../services/attributes");
|
||||||
const noteService = require('../../services/notes');
|
const noteService = require('../../services/notes');
|
||||||
const dateNoteService = require('../../services/date_notes');
|
const dateNoteService = require('../../services/date_notes');
|
||||||
const dateUtils = require('../../services/date_utils');
|
const dateUtils = require('../../services/date_utils');
|
||||||
@ -23,16 +24,26 @@ async function findClippingNote(todayNote, pageUrl) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getClipperInboxNote() {
|
||||||
|
let clipperInbox = await attributeService.getNoteWithLabel('clipperInbox');
|
||||||
|
|
||||||
|
if (!clipperInbox) {
|
||||||
|
clipperInbox = await dateNoteService.getDateNote(dateUtils.localNowDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
return clipperInbox;
|
||||||
|
}
|
||||||
|
|
||||||
async function addClipping(req) {
|
async function addClipping(req) {
|
||||||
const {title, content, pageUrl, images} = req.body;
|
const {title, content, pageUrl, images} = req.body;
|
||||||
|
|
||||||
const todayNote = await dateNoteService.getDateNote(dateUtils.localNowDate());
|
const clipperInbox = await getClipperInboxNote();
|
||||||
|
|
||||||
let clippingNote = await findClippingNote(todayNote, pageUrl);
|
let clippingNote = await findClippingNote(clipperInbox, pageUrl);
|
||||||
|
|
||||||
if (!clippingNote) {
|
if (!clippingNote) {
|
||||||
clippingNote = (await noteService.createNewNote({
|
clippingNote = (await noteService.createNewNote({
|
||||||
parentNoteId: todayNote.noteId,
|
parentNoteId: clipperInbox.noteId,
|
||||||
title: title,
|
title: title,
|
||||||
content: '',
|
content: '',
|
||||||
type: 'text'
|
type: 'text'
|
||||||
@ -54,10 +65,10 @@ async function addClipping(req) {
|
|||||||
async function createNote(req) {
|
async function createNote(req) {
|
||||||
const {title, content, pageUrl, images, clipType} = req.body;
|
const {title, content, pageUrl, images, clipType} = req.body;
|
||||||
|
|
||||||
const todayNote = await dateNoteService.getDateNote(dateUtils.localNowDate());
|
const clipperInbox = await getClipperInboxNote();
|
||||||
|
|
||||||
const {note} = await noteService.createNewNote({
|
const {note} = await noteService.createNewNote({
|
||||||
parentNoteId: todayNote.noteId,
|
parentNoteId: clipperInbox.noteId,
|
||||||
title,
|
title,
|
||||||
content,
|
content,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
|
@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2020-02-01T10:17:51+01:00", buildRevision: "0f25c8a95f381d99b66735b9c0af3e319edb72ed" };
|
module.exports = { buildDate:"2020-02-09T10:48:23+01:00", buildRevision: "88bd65c6798609a39206722305fab4f8d91d618b" };
|
||||||
|
@ -152,6 +152,11 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attr.type === 'label' && attr.name === 'externalLink') {
|
||||||
|
// also created automatically
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (attr.type === 'relation') {
|
if (attr.type === 'relation') {
|
||||||
attr.value = getNewNoteId(attr.value);
|
attr.value = getNewNoteId(attr.value);
|
||||||
}
|
}
|
||||||
|
@ -242,6 +242,20 @@ function findInternalLinks(content, foundLinks) {
|
|||||||
return content.replace(/href="[^"]*#root/g, 'href="#root');
|
return content.replace(/href="[^"]*#root/g, 'href="#root');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findExternalLinks(content, foundLinks) {
|
||||||
|
const re = /href="([a-zA-Z]+:\/\/[^"]*)"/g;
|
||||||
|
let match;
|
||||||
|
|
||||||
|
while (match = re.exec(content)) {
|
||||||
|
foundLinks.push({
|
||||||
|
name: 'externalLink',
|
||||||
|
value: match[1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
function findIncludeNoteLinks(content, foundLinks) {
|
function findIncludeNoteLinks(content, foundLinks) {
|
||||||
const re = /<section class="include-note" data-note-id="([a-zA-Z0-9]+)">/g;
|
const re = /<section class="include-note" data-note-id="([a-zA-Z0-9]+)">/g;
|
||||||
let match;
|
let match;
|
||||||
@ -281,6 +295,7 @@ async function saveLinks(note, content) {
|
|||||||
if (note.type === 'text') {
|
if (note.type === 'text') {
|
||||||
content = findImageLinks(content, foundLinks);
|
content = findImageLinks(content, foundLinks);
|
||||||
content = findInternalLinks(content, foundLinks);
|
content = findInternalLinks(content, foundLinks);
|
||||||
|
content = findExternalLinks(content, foundLinks);
|
||||||
content = findIncludeNoteLinks(content, foundLinks);
|
content = findIncludeNoteLinks(content, foundLinks);
|
||||||
}
|
}
|
||||||
else if (note.type === 'relation-map') {
|
else if (note.type === 'relation-map') {
|
||||||
@ -293,10 +308,12 @@ async function saveLinks(note, content) {
|
|||||||
const existingLinks = await note.getLinks();
|
const existingLinks = await note.getLinks();
|
||||||
|
|
||||||
for (const foundLink of foundLinks) {
|
for (const foundLink of foundLinks) {
|
||||||
|
if (foundLink.name !== 'externalLink') {
|
||||||
const targetNote = await repository.getNote(foundLink.value);
|
const targetNote = await repository.getNote(foundLink.value);
|
||||||
if (!targetNote || targetNote.isDeleted) {
|
if (!targetNote || targetNote.isDeleted) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const existingLink = existingLinks.find(existingLink =>
|
const existingLink = existingLinks.find(existingLink =>
|
||||||
existingLink.value === foundLink.value
|
existingLink.value === foundLink.value
|
||||||
@ -305,7 +322,7 @@ async function saveLinks(note, content) {
|
|||||||
if (!existingLink) {
|
if (!existingLink) {
|
||||||
await new Attribute({
|
await new Attribute({
|
||||||
noteId: note.noteId,
|
noteId: note.noteId,
|
||||||
type: 'relation',
|
type: foundLink.name === 'externalLink' ? 'label' : 'relation',
|
||||||
name: foundLink.name,
|
name: foundLink.name,
|
||||||
value: foundLink.value,
|
value: foundLink.value,
|
||||||
}).save();
|
}).save();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user