From 392b89e6dd4e5b46a28e837b3bf0348c7caa2b32 Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 23 Dec 2022 23:08:30 +0100 Subject: [PATCH] exported links to "named" notes should be preserved upon import --- src/public/app/services/link.js | 9 +++++++-- .../app/widgets/type_widgets/editable_text.js | 8 ++++++-- src/services/export/zip.js | 13 ++++++++++++- src/services/import/zip.js | 15 +++++++++++++-- src/services/search/search_result.js | 7 ++++++- src/services/search/services/search.js | 7 ------- 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/public/app/services/link.js b/src/public/app/services/link.js index 88a587249..c7d75c132 100644 --- a/src/public/app/services/link.js +++ b/src/public/app/services/link.js @@ -170,10 +170,15 @@ async function loadReferenceLinkTitle(noteId, $el) { title = note.isDeleted ? `${note.title} (deleted)` : note.title; } - $el.addClass(note.getColorClass()); + if (note) { + $el.addClass(note.getColorClass()); + } + $el.text(title); - $el.prepend($("").addClass(note.getIcon())); + if (note) { + $el.prepend($("").addClass(note.getIcon())); + } } $(document).on('click', "a", goToLink); diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index 0343e9bf7..46bf218b2 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -361,12 +361,16 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { } async createNoteForReferenceLink(title) { - const {note} = await noteCreateService.createNoteWithTypePrompt(this.notePath, { + const resp = await noteCreateService.createNoteWithTypePrompt(this.notePath, { activate: false, title: title }); - return treeService.getSomeNotePath(note); + if (!resp) { + return; + } + + return treeService.getSomeNotePath(resp.note); } async refreshIncludedNoteEvent({noteId}) { diff --git a/src/services/export/zip.js b/src/services/export/zip.js index 17135c879..9b73d1b8c 100644 --- a/src/services/export/zip.js +++ b/src/services/export/zip.js @@ -432,7 +432,18 @@ ${markdownContent}`; for (const noteMeta of Object.values(noteIdToMeta)) { // filter out relations which are not inside this export - noteMeta.attributes = noteMeta.attributes.filter(attr => attr.type !== 'relation' || attr.value in noteIdToMeta); + noteMeta.attributes = noteMeta.attributes.filter(attr => { + if (attr.type !== 'relation') { + return true; + } else if (attr.value in noteIdToMeta) { + return true; + } else if (attr.value === 'root' || attr.value?.startsWith("_")) { + // relations to "named" noteIds can be preserved + return true; + } else { + return false; + } + }); } if (!rootMeta) { // corner case of disabled export for exported note diff --git a/src/services/import/zip.js b/src/services/import/zip.js index 41bfbffdb..1add38a08 100644 --- a/src/services/import/zip.js +++ b/src/services/import/zip.js @@ -39,6 +39,11 @@ async function importZip(taskContext, fileBuffer, importRootNote) { return ""; } + if (origNoteId === 'root' || origNoteId.startsWith("_")) { + // these "named" noteIds don't differ between Trilium instances + return origNoteId; + } + if (!noteIdMap[origNoteId]) { noteIdMap[origNoteId] = utils.newEntityId(); } @@ -318,7 +323,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) { return `href="${url}"`; } - if (isUrlAbsolute(url)) { + if (url.startsWith('#') || isUrlAbsolute(url)) { return match; } @@ -330,7 +335,13 @@ async function importZip(taskContext, fileBuffer, importRootNote) { content = content.replace(/data-note-path="([^"]*)"/g, (match, notePath) => { const noteId = notePath.split("/").pop(); - const targetNoteId = noteIdMap[noteId]; + let targetNoteId; + + if (noteId === 'root' || noteId.startsWith("_")) { // named noteIds stay identical across instances + targetNoteId = noteId; + } else { + targetNoteId = noteIdMap[noteId]; + } return `data-note-path="root/${targetNoteId}"`; }); diff --git a/src/services/search/search_result.js b/src/services/search/search_result.js index 0d85d8a8f..15b036e9a 100644 --- a/src/services/search/search_result.js +++ b/src/services/search/search_result.js @@ -26,7 +26,12 @@ class SearchResult { // add one more time for note title alone (already contained in the notePathTitle), // thus preferring notes with matches on its own note title as opposed to ancestors or descendants - this.addScoreForStrings(tokens, becca.notes[this.noteId].title, 1.5); + const note = becca.notes[this.noteId]; + this.addScoreForStrings(tokens, note.title, 1.5); + + if (note.isInHiddenSubtree()) { + this.score = this.score / 2; + } } addScoreForStrings(tokens, str, factor) { diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index 954817c78..206ec63b4 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -151,9 +151,6 @@ function findResultsWithExpression(expression, searchContext) { noteIdToNotePath: {} }; - const ancestorNote = becca.getNote(searchContext.ancestorNoteId || 'root'); - const showNotesInHiddenSubtree = ancestorNote.hasAncestor('_hidden'); - const noteSet = expression.execute(allNoteSet, executionContext, searchContext); const searchResults = noteSet.notes @@ -168,10 +165,6 @@ function findResultsWithExpression(expression, searchContext) { throw new Error(`Can't find note path for note ${JSON.stringify(note.getPojo())}`); } - if (!showNotesInHiddenSubtree && notePathArray.includes('_hidden')) { - return null; - } - return new SearchResult(notePathArray); }) .filter(note => !!note);