mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01: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:
		@@ -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();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user