diff --git a/src/public/app/dialogs/jump_to_note.js b/src/public/app/dialogs/jump_to_note.js deleted file mode 100644 index 0d9fb13cf..000000000 --- a/src/public/app/dialogs/jump_to_note.js +++ /dev/null @@ -1,60 +0,0 @@ -import noteAutocompleteService from '../services/note_autocomplete.js'; -import utils from "../services/utils.js"; -import appContext from "../services/app_context.js"; - -const $dialog = $("#jump-to-note-dialog"); -const $autoComplete = $("#jump-to-note-autocomplete"); -const $showInFullTextButton = $("#show-in-full-text-button"); - -let lastOpenedTs = 0; -const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120; - -export async function showDialog() { - utils.openDialog($dialog); - - noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true }) - // clear any event listener added in previous invocation of this function - .off('autocomplete:noteselected') - .on('autocomplete:noteselected', function(event, suggestion, dataset) { - if (!suggestion.notePath) { - return false; - } - - appContext.tabManager.getActiveContext().setNote(suggestion.notePath); - }); - - // if you open the Jump To dialog soon after using it previously it can often mean that you - // actually want to search for the same thing (e.g. you opened the wrong note at first try) - // so we'll keep the content. - // if it's outside of this time limit then we assume it's a completely new search and show recent notes instead. - if (Date.now() - lastOpenedTs > KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000) { - noteAutocompleteService.showRecentNotes($autoComplete); - } - else { - $autoComplete - // hack, the actual search value is stored in
 element next to the search input
-            // this is important because the search input value is replaced with the suggestion note's title
-            .autocomplete("val", $autoComplete.next().text())
-            .trigger('focus')
-            .trigger('select');
-    }
-
-    lastOpenedTs = Date.now();
-}
-
-function showInFullText(e) {
-    // stop from propagating upwards (dangerous especially with ctrl+enter executable javascript notes)
-    e.preventDefault();
-    e.stopPropagation();
-
-    const searchString = $autoComplete.val();
-
-    appContext.triggerCommand('searchNotes', {searchString});
-
-    $dialog.modal('hide');
-}
-
-
-$showInFullTextButton.on('click', showInFullText);
-
-utils.bindElShortcut($dialog, 'ctrl+return', showInFullText);
diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js
index 38f41f2c2..99df11756 100644
--- a/src/public/app/layouts/desktop_layout.js
+++ b/src/public/app/layouts/desktop_layout.js
@@ -61,6 +61,7 @@ import SortChildNotesDialog from "../widgets/dialogs/sort_child_notes.js";
 import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
 import IncludeNoteDialog from "../widgets/dialogs/include_note.js";
 import NoteTypeChooserDialog from "../widgets/dialogs/note_type_chooser.js";
+import JumpToNoteDialog from "../widgets/dialogs/jump_to_note.js";
 
 export default class DesktopLayout {
     constructor(customWidgets) {
@@ -196,6 +197,7 @@ export default class DesktopLayout {
             .child(new SortChildNotesDialog())
             .child(new PasswordNoteSetDialog())
             .child(new IncludeNoteDialog())
-            .child(new NoteTypeChooserDialog());
+            .child(new NoteTypeChooserDialog())
+            .child(new JumpToNoteDialog());
     }
 }
diff --git a/src/public/app/services/root_command_executor.js b/src/public/app/services/root_command_executor.js
index 5de1313c5..2a66e69ff 100644
--- a/src/public/app/services/root_command_executor.js
+++ b/src/public/app/services/root_command_executor.js
@@ -8,10 +8,6 @@ import options from "./options.js";
 import froca from "./froca.js";
 
 export default class RootCommandExecutor extends Component {
-    jumpToNoteCommand() {
-        import("../dialogs/jump_to_note.js").then(d => d.showDialog());
-    }
-
     showNoteRevisionsCommand() {
         import("../dialogs/note_revisions.js").then(d => d.showCurrentNoteRevisions());
     }
diff --git a/src/public/app/widgets/dialogs/jump_to_note.js b/src/public/app/widgets/dialogs/jump_to_note.js
new file mode 100644
index 000000000..4db606c01
--- /dev/null
+++ b/src/public/app/widgets/dialogs/jump_to_note.js
@@ -0,0 +1,96 @@
+import noteAutocompleteService from '../../services/note_autocomplete.js';
+import utils from "../../services/utils.js";
+import appContext from "../../services/app_context.js";
+import BasicWidget from "../basic_widget.js";
+
+const TPL = ``;
+
+const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120;
+
+export default class JumpToNoteDialog extends BasicWidget {
+    constructor() {
+        super();
+
+        this.lastOpenedTs = 0;
+    }
+
+    doRender() {
+        this.$widget = $(TPL);
+        this.$autoComplete = this.$widget.find(".jump-to-note-autocomplete");
+        this.$showInFullTextButton = this.$widget.find(".show-in-full-text-button");
+        this.$showInFullTextButton.on('click', e => this.showInFullText(e));
+
+        utils.bindElShortcut(this.$widget, 'ctrl+return', e => this.showInFullText(e));
+    }
+
+    async jumpToNoteEvent() {
+        utils.openDialog(this.$widget);
+
+        // first open dialog, then refresh since refresh is doing focus which should be visible
+        this.refresh();
+
+        this.lastOpenedTs = Date.now();
+    }
+
+    async refresh() {
+        noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {hideGoToSelectedNoteButton: true})
+            // clear any event listener added in previous invocation of this function
+            .off('autocomplete:noteselected')
+            .on('autocomplete:noteselected', function (event, suggestion, dataset) {
+                if (!suggestion.notePath) {
+                    return false;
+                }
+
+                appContext.tabManager.getActiveContext().setNote(suggestion.notePath);
+            });
+
+        // if you open the Jump To dialog soon after using it previously it can often mean that you
+        // actually want to search for the same thing (e.g. you opened the wrong note at first try)
+        // so we'll keep the content.
+        // if it's outside of this time limit then we assume it's a completely new search and show recent notes instead.
+        if (Date.now() - this.lastOpenedTs > KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000) {
+            noteAutocompleteService.showRecentNotes(this.$autoComplete);
+        } else {
+            this.$autoComplete
+                // hack, the actual search value is stored in 
 element next to the search input
+                // this is important because the search input value is replaced with the suggestion note's title
+                .autocomplete("val", this.$autoComplete.next().text())
+                .trigger('focus')
+                .trigger('select');
+        }
+    }
+
+    showInFullText(e) {
+        // stop from propagating upwards (dangerous especially with ctrl+enter executable javascript notes)
+        e.preventDefault();
+        e.stopPropagation();
+
+        const searchString = this.$autoComplete.val();
+
+        this.triggerCommand('searchNotes', {searchString});
+
+        this.$widget.modal('hide');
+    }
+}
diff --git a/src/views/desktop.ejs b/src/views/desktop.ejs
index b74be0d5d..f80e460c6 100644
--- a/src/views/desktop.ejs
+++ b/src/views/desktop.ejs
@@ -20,7 +20,6 @@
 <%- include('dialogs/add_link.ejs') %>
 <%- include('dialogs/export.ejs') %>
 <%- include('dialogs/import.ejs') %>
-<%- include('dialogs/jump_to_note.ejs') %>
 <%- include('dialogs/markdown_import.ejs') %>
 <%- include('dialogs/note_revisions.ejs') %>
 <%- include('dialogs/options.ejs') %>
diff --git a/src/views/dialogs/jump_to_note.ejs b/src/views/dialogs/jump_to_note.ejs
deleted file mode 100644
index 90549300d..000000000
--- a/src/views/dialogs/jump_to_note.ejs
+++ /dev/null
@@ -1,23 +0,0 @@
-