mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	added "save search to note" button
This commit is contained in:
		
							
								
								
									
										3
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								TODO
									
									
									
									
									
								
							| @@ -2,3 +2,6 @@ | ||||
| - all ribbon tabs should have assignable shortcut | ||||
| - new icon | ||||
| - green theme | ||||
| - polish becca entities API | ||||
| - separate private and public APIs in becca entities | ||||
| - handle FIXMEs | ||||
|   | ||||
| @@ -1008,6 +1008,24 @@ class Note extends AbstractEntity { | ||||
|      */ | ||||
|     removeRelation(name, value) { return this.removeAttribute(RELATION, name, value); } | ||||
|  | ||||
|     searchNotesInSubtree(searchString) { | ||||
|         const searchService = require("../../services/search/services/search"); | ||||
|  | ||||
|         return searchService.searchNotes(searchString); | ||||
|     } | ||||
|  | ||||
|     searchNoteInSubtree(searchString) { | ||||
|         return this.searchNotesInSubtree(searchString)[0]; | ||||
|     } | ||||
|  | ||||
|     cloneTo(parentNoteId) { | ||||
|         const cloningService = require("../../services/cloning"); | ||||
|  | ||||
|         const branch = this.becca.getNote(parentNoteId).getParentBranches()[0]; | ||||
|  | ||||
|         return cloningService.cloneNoteToParent(this.noteId, branch.branchId); | ||||
|     } | ||||
|  | ||||
|     decrypt() { | ||||
|         if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { | ||||
|             try { | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js"; | ||||
| import froca from "../../services/froca.js"; | ||||
| import ws from "../../services/ws.js"; | ||||
| import toastService from "../../services/toast.js"; | ||||
| import treeService from "../../services/tree.js"; | ||||
|  | ||||
| import DeleteNoteSearchAction from "../search_actions/delete_note.js"; | ||||
| import DeleteLabelSearchAction from "../search_actions/delete_label.js"; | ||||
| @@ -21,6 +22,8 @@ import SearchScript from "../search_options/search_script.js"; | ||||
| import Limit from "../search_options/limit.js"; | ||||
| import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js"; | ||||
| import Debug from "../search_options/debug.js"; | ||||
| import appContext from "../../services/app_context.js"; | ||||
| import toast from "../../services/toast.js"; | ||||
|  | ||||
| const TPL = ` | ||||
| <div class="search-definition-widget"> | ||||
| @@ -164,6 +167,11 @@ const TPL = ` | ||||
|                                 <span class="bx bxs-zap"></span> | ||||
|                                 Search & Execute actions | ||||
|                             </button> | ||||
|                              | ||||
|                             <button type="button" class="btn btn-sm save-to-note-button"> | ||||
|                                 <span class="bx bx-save"></span> | ||||
|                                 Save to note | ||||
|                             </button> | ||||
|                         </div> | ||||
|                     </td> | ||||
|                 </tr> | ||||
| @@ -258,6 +266,19 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget { | ||||
|  | ||||
|         this.$searchAndExecuteButton = this.$widget.find('.search-and-execute-button'); | ||||
|         this.$searchAndExecuteButton.on('click', () => this.searchAndExecute()); | ||||
|  | ||||
|         this.$saveToNoteButton = this.$widget.find('.save-to-note-button'); | ||||
|         this.$saveToNoteButton.on('click', async () => { | ||||
|             const {notePath} = await server.post("save-search-note", {searchNoteId: this.noteId}); | ||||
|  | ||||
|             await ws.waitForMaxKnownEntityChangeId(); | ||||
|  | ||||
|             await appContext.tabManager.getActiveContext().setNote(notePath); | ||||
|  | ||||
|             console.log("notePath", notePath); | ||||
|  | ||||
|             toastService.showMessage("Search note has been saved into " + await treeService.getNotePathTitle(notePath)); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     async refreshResultsCommand() { | ||||
| @@ -278,6 +299,8 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$component.show(); | ||||
|  | ||||
|         this.$saveToNoteButton.toggle(!note.getAllNotePaths().find(notePathArr => !notePathArr.includes("hidden"))); | ||||
|  | ||||
|         this.$searchOptions.empty(); | ||||
|  | ||||
|         for (const OptionClass of OPTION_CLASSES) { | ||||
|   | ||||
| @@ -12,9 +12,16 @@ const utils = require('../../services/utils'); | ||||
| const path = require('path'); | ||||
| const Attribute = require('../../becca/entities/attribute.js'); | ||||
| const htmlSanitizer = require('../../services/html_sanitizer'); | ||||
| const {formatAttrForSearch} = require("../../services/attribute_formatter.js"); | ||||
|  | ||||
| function findClippingNote(todayNote, pageUrl) { | ||||
|     const notes = todayNote.getDescendantNotesWithLabel('pageUrl', pageUrl); | ||||
|     const notes = todayNote.searchNoteInSubtree( | ||||
|         formatAttrForSearch({ | ||||
|             type: 'label', | ||||
|             name: "pageUrl", | ||||
|             value: pageUrl | ||||
|         }, true) | ||||
|     ); | ||||
|  | ||||
|     for (const note of notes) { | ||||
|         if (note.getOwnedLabelValue('clipType') === 'clippings') { | ||||
|   | ||||
| @@ -13,11 +13,11 @@ function getInboxNote(req) { | ||||
|  | ||||
|     let inbox; | ||||
|  | ||||
|     if (hoistedNote) { | ||||
|         ([inbox] = hoistedNote.getDescendantNotesWithLabel('hoistedInbox')); | ||||
|     if (!hoistedNote.isRoot()) { | ||||
|         inbox = hoistedNote.searchNoteInSubtree('#hoistedInbox'); | ||||
|  | ||||
|         if (!inbox) { | ||||
|             ([inbox] = hoistedNote.getDescendantNotesWithLabel('inbox')); | ||||
|             inbox = hoistedNote.searchNoteInSubtree('#inbox'); | ||||
|         } | ||||
|  | ||||
|         if (!inbox) { | ||||
| @@ -114,39 +114,35 @@ function getSearchRoot() { | ||||
|     return searchRoot; | ||||
| } | ||||
|  | ||||
| function saveSearchNote(req) { | ||||
|     const searchNote = becca.getNote(req.body.searchNoteId); | ||||
|  | ||||
|     const hoistedNote = getHoistedNote(); | ||||
|     let searchHome; | ||||
|  | ||||
|     if (!hoistedNote.isRoot()) { | ||||
|         searchHome = hoistedNote.searchNoteInSubtree('#hoistedSearchHome') | ||||
|             || hoistedNote.searchNoteInSubtree('#searchHome') | ||||
|             || hoistedNote; | ||||
|     } | ||||
|     else { | ||||
|         const today = dateUtils.localNowDate(); | ||||
|  | ||||
|         searchHome = hoistedNote.searchNoteInSubtree('#searchHome') | ||||
|             || dateNoteService.getDateNote(today); | ||||
|     } | ||||
|  | ||||
|     return searchNote.cloneTo(searchHome.noteId); | ||||
| } | ||||
|  | ||||
| function createSearchNote(req) { | ||||
|     const params = req.body; | ||||
|     const searchString = params.searchString || ""; | ||||
|     let ancestorNoteId = params.ancestorNoteId; | ||||
|  | ||||
|     const hoistedNote = getHoistedNote(); | ||||
|  | ||||
|     let searchHome = getSearchRoot(); | ||||
|  | ||||
|     // if (hoistedNote) { | ||||
|     //     ([searchHome] = hoistedNote.getDescendantNotesWithLabel('hoistedSearchHome')); | ||||
|     // | ||||
|     //     if (!searchHome) { | ||||
|     //         ([searchHome] = hoistedNote.getDescendantNotesWithLabel('searchHome')); | ||||
|     //     } | ||||
|     // | ||||
|     //     if (!searchHome) { | ||||
|     //         searchHome = hoistedNote; | ||||
|     //     } | ||||
|     // | ||||
|     //     if (!ancestorNoteId) { | ||||
|     //         ancestorNoteId = hoistedNote.noteId; | ||||
|     //     } | ||||
|     // } | ||||
|     // else { | ||||
|     //     const today = dateUtils.localNowDate(); | ||||
|     // | ||||
|     //     searchHome = attributeService.getNoteWithLabel('searchHome') | ||||
|     //               || dateNoteService.getDateNote(today); | ||||
|     // } | ||||
|     const ancestorNoteId = params.ancestorNoteId || hoistedNote.noteId; | ||||
|  | ||||
|     const {note} = noteService.createNewNote({ | ||||
|         parentNoteId: searchHome.noteId, | ||||
|         parentNoteId: getSearchRoot().noteId, | ||||
|         title: 'Search: ' + searchString, | ||||
|         content: "", | ||||
|         type: 'search', | ||||
| @@ -163,9 +159,7 @@ function createSearchNote(req) { | ||||
| } | ||||
|  | ||||
| function getHoistedNote() { | ||||
|     return cls.getHoistedNoteId() && cls.getHoistedNoteId() !== 'root' | ||||
|         ? becca.getNote(cls.getHoistedNoteId()) | ||||
|         : null; | ||||
|     return becca.getNote(cls.getHoistedNoteId()); | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
| @@ -175,5 +169,6 @@ module.exports = { | ||||
|     getYearNote, | ||||
|     getDateNotesForMonth, | ||||
|     createSqlConsole, | ||||
|     createSearchNote | ||||
|     createSearchNote, | ||||
|     saveSearchNote | ||||
| }; | ||||
|   | ||||
| @@ -92,7 +92,7 @@ function update(name, value) { | ||||
| } | ||||
|  | ||||
| function getUserThemes() { | ||||
|     const notes = searchService.findNotes("#appTheme"); | ||||
|     const notes = searchService.searchNotes("#appTheme"); | ||||
|     const ret = []; | ||||
|  | ||||
|     for (const note of notes) { | ||||
|   | ||||
| @@ -212,6 +212,7 @@ function register(app) { | ||||
|     apiRoute(GET, '/api/date-notes/notes-for-month/:month', dateNotesRoute.getDateNotesForMonth); | ||||
|     apiRoute(POST, '/api/sql-console', dateNotesRoute.createSqlConsole); | ||||
|     apiRoute(POST, '/api/search-note', dateNotesRoute.createSearchNote); | ||||
|     apiRoute(POST, '/api/save-search-note', dateNotesRoute.saveSearchNote); | ||||
|  | ||||
|     route(GET, '/api/images/:noteId/:filename', [auth.checkApiAuthOrElectron], imageRoute.returnImage); | ||||
|     route(POST, '/api/images', [auth.checkApiAuthOrElectron, uploadMiddleware, csrfMiddleware], imageRoute.uploadImage, apiResultHandler); | ||||
|   | ||||
| @@ -60,7 +60,7 @@ const BUILTIN_ATTRIBUTES = [ | ||||
| ]; | ||||
|  | ||||
| function getNotesWithLabel(name, value) { | ||||
|     return searchService.findNotes(formatAttrForSearch({type: 'label', name, value}, true)); | ||||
|     return searchService.searchNotes(formatAttrForSearch({type: 'label', name, value}, true)); | ||||
| } | ||||
|  | ||||
| function getNoteIdsWithLabels(names) { | ||||
| @@ -75,6 +75,7 @@ function getNoteIdsWithLabels(names) { | ||||
|     return Array.from(noteIds); | ||||
| } | ||||
|  | ||||
| // TODO: should be in search service | ||||
| function getNoteWithLabel(name, value) { | ||||
|     const notes = getNotesWithLabel(name, value); | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ const Branch = require('../becca/entities/branch.js'); | ||||
| const TaskContext = require("./task_context.js"); | ||||
| const utils = require('./utils'); | ||||
| const becca = require("../becca/becca.js"); | ||||
| const beccaService = require("../becca/becca_service"); | ||||
|  | ||||
| function cloneNoteToParent(noteId, parentBranchId, prefix) { | ||||
|     const parentBranch = becca.getBranch(parentBranchId); | ||||
| @@ -32,7 +33,11 @@ function cloneNoteToParent(noteId, parentBranchId, prefix) { | ||||
|     parentBranch.isExpanded = true; // the new target should be expanded so it immediately shows up to the user | ||||
|     parentBranch.save(); | ||||
|  | ||||
|     return { success: true, branchId: branch.branchId }; | ||||
|     return { | ||||
|         success: true, | ||||
|         branchId: branch.branchId, | ||||
|         notePath: beccaService.getNotePath(parentBranch.noteId).path + "/" + noteId | ||||
|     }; | ||||
| } | ||||
|  | ||||
| function ensureNoteIsPresentInParent(noteId, parentNoteId, prefix) { | ||||
|   | ||||
| @@ -136,7 +136,7 @@ function parseQueryToExpression(query, searchContext) { | ||||
|  * @param {string} query | ||||
|  * @return {Note[]} | ||||
|  */ | ||||
| function findNotes(query) { | ||||
| function searchNotes(query) { | ||||
|     const searchResults = findResultsWithQuery(query, new SearchContext()); | ||||
|  | ||||
|     return searchResults.map(sr => becca.notes[sr.noteId]); | ||||
| @@ -263,5 +263,5 @@ module.exports = { | ||||
|     searchTrimmedNotes, | ||||
|     searchNotesForAutocomplete, | ||||
|     findResultsWithQuery, | ||||
|     findNotes | ||||
|     searchNotes | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user