mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	moved "global buttons" on the tree
This commit is contained in:
		| @@ -4,9 +4,6 @@ import TabRowWidget from "../widgets/tab_row.js"; | |||||||
| import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js"; | import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js"; | ||||||
| import StandardTopWidget from "../widgets/standard_top_widget.js"; | import StandardTopWidget from "../widgets/standard_top_widget.js"; | ||||||
| import SidePaneContainer from "../widgets/side_pane_container.js"; | import SidePaneContainer from "../widgets/side_pane_container.js"; | ||||||
| import GlobalButtonsWidget from "../widgets/global_buttons.js"; |  | ||||||
| import SearchBoxWidget from "../widgets/search_box.js"; |  | ||||||
| import SearchResultsWidget from "../widgets/search_results.js"; |  | ||||||
| import NoteTreeWidget from "../widgets/note_tree.js"; | import NoteTreeWidget from "../widgets/note_tree.js"; | ||||||
| import TabCachingWidget from "../widgets/tab_caching_widget.js"; | import TabCachingWidget from "../widgets/tab_caching_widget.js"; | ||||||
| import NotePathsWidget from "../widgets/note_paths.js"; | import NotePathsWidget from "../widgets/note_paths.js"; | ||||||
| @@ -142,9 +139,6 @@ export default class DesktopMainWindowLayout { | |||||||
|                 .filling() |                 .filling() | ||||||
|                 .child(new SidePaneContainer('left') |                 .child(new SidePaneContainer('left') | ||||||
|                     .hideInZenMode() |                     .hideInZenMode() | ||||||
|                     .child(new GlobalButtonsWidget()) |  | ||||||
|                     .child(new SearchBoxWidget()) |  | ||||||
|                     .child(new SearchResultsWidget()) |  | ||||||
|                     .child(new TabCachingWidget(() => new NotePathsWidget())) |                     .child(new TabCachingWidget(() => new NotePathsWidget())) | ||||||
|                     .child(appContext.mainTreeWidget) |                     .child(appContext.mainTreeWidget) | ||||||
|                     .child(...this.customWidgets.get('left-pane')) |                     .child(...this.customWidgets.get('left-pane')) | ||||||
|   | |||||||
| @@ -1,40 +0,0 @@ | |||||||
| import BasicWidget from "./basic_widget.js"; |  | ||||||
|  |  | ||||||
| const WIDGET_TPL = ` |  | ||||||
| <div class="global-buttons"> |  | ||||||
|     <style> |  | ||||||
|     .global-buttons { |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: space-around; |  | ||||||
|         border: 1px solid var(--main-border-color); |  | ||||||
|         border-radius: 7px; |  | ||||||
|         margin: 3px 5px 5px 5px; |  | ||||||
|     } |  | ||||||
|     </style> |  | ||||||
|  |  | ||||||
|     <a data-trigger-command="createTopLevelNote" |  | ||||||
|        title="Create new top level note"  |  | ||||||
|        class="icon-action bx bx-folder-plus"></a> |  | ||||||
|  |  | ||||||
|     <a data-trigger-command="collapseTree" |  | ||||||
|        title="Collapse note tree"  |  | ||||||
|        class="icon-action bx bx-layer-minus"></a> |  | ||||||
|  |  | ||||||
|     <a data-trigger-command="scrollToActiveNote" |  | ||||||
|        title="Scroll to active note"   |  | ||||||
|        class="icon-action bx bx-crosshair"></a> |  | ||||||
|  |  | ||||||
|     <a data-trigger-command="searchNotes" |  | ||||||
|        title="Search in notes" |  | ||||||
|        class="icon-action bx bx-search"></a> |  | ||||||
| </div> |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| class GlobalButtonsWidget extends BasicWidget { |  | ||||||
|     doRender() { |  | ||||||
|         this.$widget = $(WIDGET_TPL); |  | ||||||
|         this.overflowing(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export default GlobalButtonsWidget; |  | ||||||
| @@ -49,10 +49,24 @@ const TPL = ` | |||||||
|         border-color: var(--button-border-color); |         border-color: var(--button-border-color); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     .collapse-tree-button { | ||||||
|  |         position: absolute; | ||||||
|  |         top: 10px; | ||||||
|  |         right: 70px; | ||||||
|  |         z-index: 100; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .scroll-to-active-note-button { | ||||||
|  |         position: absolute; | ||||||
|  |         top: 10px; | ||||||
|  |         right: 35px; | ||||||
|  |         z-index: 100; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     .tree-settings-button { |     .tree-settings-button { | ||||||
|         position: absolute; |         position: absolute; | ||||||
|         top: 10px; |         top: 10px; | ||||||
|         right: 10px; |         right: 0px; | ||||||
|         z-index: 100; |         z-index: 100; | ||||||
|     } |     } | ||||||
|      |      | ||||||
| @@ -130,6 +144,10 @@ const TPL = ` | |||||||
|     } |     } | ||||||
|     </style> |     </style> | ||||||
|      |      | ||||||
|  |     <button class="btn btn-sm icon-button bx bx-layer-minus collapse-tree-button" title="Collapse note tree" data-trigger-command="collapseTree"></button> | ||||||
|  |      | ||||||
|  |     <button class="btn btn-sm icon-button bx bx-crosshair scroll-to-active-note-button" title="Scroll to active note" data-trigger-command="scrollToActiveNote"></button> | ||||||
|  |      | ||||||
|     <button class="btn btn-sm icon-button bx bx-cog tree-settings-button" title="Tree settings"></button> |     <button class="btn btn-sm icon-button bx bx-cog tree-settings-button" title="Tree settings"></button> | ||||||
|      |      | ||||||
|     <div class="tree-settings-popup"> |     <div class="tree-settings-popup"> | ||||||
| @@ -697,6 +715,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         await this.setExpandedStatusForSubtree(node, false); |         await this.setExpandedStatusForSubtree(node, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     collapseTreeCommand() { this.collapseTree(); } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @return {FancytreeNode|null} |      * @return {FancytreeNode|null} | ||||||
|      */ |      */ | ||||||
| @@ -719,7 +739,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async scrollToActiveNoteEvent() { |     async scrollToActiveNoteCommand() { | ||||||
|         const activeContext = appContext.tabManager.getActiveTabContext(); |         const activeContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|         if (activeContext && activeContext.notePath) { |         if (activeContext && activeContext.notePath) { | ||||||
| @@ -829,9 +849,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null |         return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // must be event since it's triggered from outside the tree |  | ||||||
|     collapseTreeEvent() { this.collapseTree(); } |  | ||||||
|  |  | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
|         return !!this.tabContext; |         return !!this.tabContext; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,182 +0,0 @@ | |||||||
| import BasicWidget from "./basic_widget.js"; |  | ||||||
| import toastService from "../services/toast.js"; |  | ||||||
| import appContext from "../services/app_context.js"; |  | ||||||
| import noteCreateService from "../services/note_create.js"; |  | ||||||
| import utils from "../services/utils.js"; |  | ||||||
| import treeCache from "../services/tree_cache.js"; |  | ||||||
|  |  | ||||||
| const TPL = ` |  | ||||||
| <div class="search-box"> |  | ||||||
|     <style> |  | ||||||
|     .search-box { |  | ||||||
|         display: none; |  | ||||||
|         padding: 10px; |  | ||||||
|         margin-top: 10px; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .search-text { |  | ||||||
|         border: 1px solid var(--main-border-color); |  | ||||||
|     } |  | ||||||
|     </style> |  | ||||||
|  |  | ||||||
|     <div class="form-group"> |  | ||||||
|         <div class="input-group"> |  | ||||||
|             <input name="search-text" class="search-text form-control" |  | ||||||
|                    placeholder="Search text, labels" autocomplete="off"> |  | ||||||
|  |  | ||||||
|             <div class="input-group-append"> |  | ||||||
|                 <button class="do-search-button btn btn-sm icon-button bx bx-search" title="Search (enter)"></button> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div style="display: flex; align-items: center; justify-content: space-evenly; flex-wrap: wrap;"> |  | ||||||
|         <button class="save-search-button btn btn-sm" |  | ||||||
|             title="This will create new saved search note under active note."> |  | ||||||
|             <span class="bx bx-save"></span> Save search |  | ||||||
|         </button> |  | ||||||
|  |  | ||||||
|         <button class="close-search-button btn btn-sm"> |  | ||||||
|             <span class="bx bx-x"></span> Close search |  | ||||||
|         </button> |  | ||||||
|     </div> |  | ||||||
| </div>`; |  | ||||||
|  |  | ||||||
| export default class SearchBoxWidget extends BasicWidget { |  | ||||||
|     doRender() { |  | ||||||
|         this.$widget = $(TPL); |  | ||||||
|         this.contentSized(); |  | ||||||
|  |  | ||||||
|         this.$searchBox = this.$widget; |  | ||||||
|         this.$closeSearchButton = this.$widget.find(".close-search-button"); |  | ||||||
|         this.$searchInput = this.$widget.find("input[name='search-text']"); |  | ||||||
|         this.$resetSearchButton = this.$widget.find(".reset-search-button"); |  | ||||||
|         this.$doSearchButton = this.$widget.find(".do-search-button"); |  | ||||||
|         this.$saveSearchButton = this.$widget.find(".save-search-button"); |  | ||||||
|  |  | ||||||
|         this.$searchInput.on('keyup',e => { |  | ||||||
|             const searchText = this.$searchInput.val(); |  | ||||||
|  |  | ||||||
|             if (e && e.which === $.ui.keyCode.ESCAPE || $.trim(searchText) === "") { |  | ||||||
|                 this.$resetSearchButton.trigger('click'); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (e && e.which === $.ui.keyCode.ENTER) { |  | ||||||
|                 this.doSearch(); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         this.$doSearchButton.on('click', () => this.doSearch()); // keep long form because of argument |  | ||||||
|         this.$resetSearchButton.on('click', () => this.resetSearchEvent()); |  | ||||||
|  |  | ||||||
|         this.$saveSearchButton.on('click', () => this.saveSearch()); |  | ||||||
|  |  | ||||||
|         this.$closeSearchButton.on('click', () => this.hideSearch()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     doSearch(searchText) { |  | ||||||
|         if (searchText) { |  | ||||||
|             this.$searchInput.val(searchText); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             searchText = this.$searchInput.val(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (searchText.trim().length === 0) { |  | ||||||
|             toastService.showMessage("Please enter search criteria first."); |  | ||||||
|  |  | ||||||
|             this.$searchInput.trigger('focus'); |  | ||||||
|  |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.triggerCommand('searchForResults', { |  | ||||||
|             searchText: this.$searchInput.val() |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         this.$searchBox.tooltip("hide"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async saveSearch() { |  | ||||||
|         const searchString = this.$searchInput.val().trim(); |  | ||||||
|  |  | ||||||
|         if (searchString.length === 0) { |  | ||||||
|             alert("Write some search criteria first so there is something to save."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let parent = appContext.tabManager.getActiveTabNote(); |  | ||||||
|  |  | ||||||
|         if (parent.type === 'search') { |  | ||||||
|             parent = await treeCache.getNote('root'); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         await noteCreateService.createNote(parent.noteId, { |  | ||||||
|             type: "search", |  | ||||||
|             mime: "application/json", |  | ||||||
|             title: searchString, |  | ||||||
|             content: JSON.stringify({ searchString: searchString }) |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         this.resetSearchEvent(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     showSearchEvent(data = {}) { |  | ||||||
|         const {searchText} = data; |  | ||||||
|  |  | ||||||
|         utils.saveFocusedElement(); |  | ||||||
|  |  | ||||||
|         this.$searchBox.slideDown(); |  | ||||||
|  |  | ||||||
|         this.$searchBox.tooltip({ |  | ||||||
|             trigger: 'focus', |  | ||||||
|             html: true, |  | ||||||
|             title: window.glob.SEARCH_HELP_TEXT, |  | ||||||
|             placement: 'right', |  | ||||||
|             delay: { |  | ||||||
|                 show: 500, // necessary because sliding out may cause wrong position |  | ||||||
|                 hide: 200 |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         if (searchText) { |  | ||||||
|             this.$searchInput.val(searchText); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.$searchInput.trigger('focus'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     hideSearch() { |  | ||||||
|         this.resetSearchEvent(); |  | ||||||
|  |  | ||||||
|         this.$searchBox.slideUp(); |  | ||||||
|  |  | ||||||
|         this.triggerCommand('searchFlowEnded'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     toggleSearchEvent() { |  | ||||||
|         if (this.$searchBox.is(":hidden")) { |  | ||||||
|             this.showSearchEvent(); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             this.hideSearch(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // searchNotesEvent() { |  | ||||||
|     //     this.toggleSearchEvent(); |  | ||||||
|     // } |  | ||||||
|  |  | ||||||
|     resetSearchEvent() { |  | ||||||
|         this.$searchInput.val(""); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     searchInSubtreeEvent({node}) { |  | ||||||
|         const noteId = node.data.noteId; |  | ||||||
|  |  | ||||||
|         this.showSearchEvent(); |  | ||||||
|  |  | ||||||
|         this.$searchInput.val(`YOUR_SEARCH_TEXT note.ancestors.noteId=${noteId}`); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,61 +0,0 @@ | |||||||
| import BasicWidget from "./basic_widget.js"; |  | ||||||
|  |  | ||||||
| const TPL = ` |  | ||||||
| <div class="search-results"> |  | ||||||
|     <style> |  | ||||||
|     .search-results { |  | ||||||
|         padding: 0 5px 5px 15px; |  | ||||||
|         flex-basis: 40%; |  | ||||||
|         flex-grow: 1; |  | ||||||
|         flex-shrink: 1; |  | ||||||
|         margin-top: 10px; |  | ||||||
|         display: none; |  | ||||||
|         overflow: auto; |  | ||||||
|         border-bottom: 2px solid var(--main-border-color); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .search-results-list { |  | ||||||
|         padding: 5px 5px 5px 15px; |  | ||||||
|     } |  | ||||||
|     </style> |  | ||||||
|  |  | ||||||
|     <strong>Search results:</strong> |  | ||||||
|  |  | ||||||
|     <ul class="search-results-list"></ul> |  | ||||||
| </div> |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| export default class SearchResultsWidget extends BasicWidget { |  | ||||||
|     doRender() { |  | ||||||
|         this.$widget = $(TPL); |  | ||||||
|  |  | ||||||
|         this.$searchResults = this.$widget; |  | ||||||
|         this.$searchResultsInner = this.$widget.find(".search-results-list"); |  | ||||||
|  |  | ||||||
|         this.toggleInt(false); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     searchResultsEvent({results}) { |  | ||||||
|         this.toggleInt(true); |  | ||||||
|  |  | ||||||
|         this.$searchResultsInner.empty(); |  | ||||||
|         this.$searchResults.show(); |  | ||||||
|  |  | ||||||
|         for (const result of results) { |  | ||||||
|             const link = $('<a>', { |  | ||||||
|                 href: 'javascript:', |  | ||||||
|                 text: result.notePathTitle, |  | ||||||
|                 'data-action': 'note', |  | ||||||
|                 'data-note-path': result.notePathArray.join('/') |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             const $result = $('<li>').append(link); |  | ||||||
|  |  | ||||||
|             this.$searchResultsInner.append($result); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     searchFlowEndedEvent() { |  | ||||||
|         this.$searchResults.hide(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -33,12 +33,17 @@ const TPL = ` | |||||||
|     </style> |     </style> | ||||||
|  |  | ||||||
|     <div style="flex-grow: 100; display: flex;"> |     <div style="flex-grow: 100; display: flex;"> | ||||||
|         <button class="btn btn-sm jump-to-note-dialog-button" data-command="jumpToNote"> |         <button class="btn btn-sm search-button" data-trigger-command="searchNotes" data-command="searchNotes"> | ||||||
|  |             <span class="bx bx-search"></span> | ||||||
|  |             Search | ||||||
|  |         </button> | ||||||
|  |      | ||||||
|  |         <button class="btn btn-sm jump-to-note-dialog-button" data-trigger-command="jumpToNote"> | ||||||
|             <span class="bx bx-crosshair"></span> |             <span class="bx bx-crosshair"></span> | ||||||
|             Jump to note |             Jump to note | ||||||
|         </button> |         </button> | ||||||
|      |      | ||||||
|         <button class="btn btn-sm recent-changes-button" data-command="showRecentChanges"> |         <button class="btn btn-sm recent-changes-button" data-trigger-command="showRecentChanges"> | ||||||
|             <span class="bx bx-history"></span> |             <span class="bx bx-history"></span> | ||||||
|      |      | ||||||
|             Recent changes |             Recent changes | ||||||
| @@ -73,9 +78,6 @@ export default class StandardTopWidget extends BasicWidget { | |||||||
|  |  | ||||||
|         this.$widget.prepend(historyNavigationWidget.render()); |         this.$widget.prepend(historyNavigationWidget.render()); | ||||||
|  |  | ||||||
|         this.$widget.find(".jump-to-note-dialog-button").on('click', () => this.triggerCommand('jumpToNote')); |  | ||||||
|         this.$widget.find(".recent-changes-button").on('click', () => this.triggerCommand('showRecentChanges')); |  | ||||||
|  |  | ||||||
|         this.$enterProtectedSessionButton = this.$widget.find(".enter-protected-session-button"); |         this.$enterProtectedSessionButton = this.$widget.find(".enter-protected-session-button"); | ||||||
|         this.$enterProtectedSessionButton.on('click', protectedSessionService.enterProtectedSession); |         this.$enterProtectedSessionButton.on('click', protectedSessionService.enterProtectedSession); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user