mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 04:51:31 +08:00 
			
		
		
		
	implemented "search in subtree"
This commit is contained in:
		
							parent
							
								
									b0e5ab7533
								
							
						
					
					
						commit
						90d33f56c3
					
				
							
								
								
									
										54
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										54
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.45.5", |   "version": "0.45.6", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
| @ -2044,9 +2044,9 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "commonmark": { |     "commonmark": { | ||||||
|       "version": "0.29.2", |       "version": "0.29.3", | ||||||
|       "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.2.tgz", |       "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.3.tgz", | ||||||
|       "integrity": "sha512-spe43MvEIaPpHss1T7z4yQaFQfLGmMu+yvCwv6xqhELIwkG/ZGgDpxOPzKxnuYzYT2c+aziCCc8m2rBVLA7jUA==", |       "integrity": "sha512-fvt/NdOFKaL2gyhltSy6BC4LxbbxbnPxBMl923ittqO/JBM0wQHaoYZliE4tp26cRxX/ZZtRsJlZzQrVdUkXAA==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "entities": "~2.0", |         "entities": "~2.0", | ||||||
|         "mdurl": "~1.0.1", |         "mdurl": "~1.0.1", | ||||||
| @ -2358,9 +2358,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "dayjs": { |     "dayjs": { | ||||||
|       "version": "1.9.6", |       "version": "1.9.7", | ||||||
|       "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.6.tgz", |       "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.7.tgz", | ||||||
|       "integrity": "sha512-HngNLtPEBWRo8EFVmHFmSXAjtCX8rGNqeXQI0Gh7wCTSqwaKgPIDqu9m07wABVopNwzvOeCb+2711vQhDlcIXw==" |       "integrity": "sha512-IC877KBdMhBrCfBfJXHQlo0G8keZ0Opy7YIIq5QKtUbCuHMzim8S4PyiVK4YmihI3iOF9lhfUBW4AQWHTR5WHA==" | ||||||
|     }, |     }, | ||||||
|     "debug": { |     "debug": { | ||||||
|       "version": "4.1.1", |       "version": "4.1.1", | ||||||
| @ -2910,9 +2910,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "electron-osx-sign": { |     "electron-osx-sign": { | ||||||
|       "version": "0.4.17", |       "version": "0.5.0", | ||||||
|       "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.17.tgz", |       "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz", | ||||||
|       "integrity": "sha512-wUJPmZJQCs1zgdlQgeIpRcvrf7M5/COQaOV68Va1J/SgmWx5KL2otgg+fAae7luw6qz9R8Gvu/Qpe9tAOu/3xQ==", |       "integrity": "sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "bluebird": "^3.5.0", |         "bluebird": "^3.5.0", | ||||||
| @ -2944,16 +2944,16 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "electron-packager": { |     "electron-packager": { | ||||||
|       "version": "15.1.0", |       "version": "15.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.1.0.tgz", |       "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.2.0.tgz", | ||||||
|       "integrity": "sha512-THNm4bz1DfvR9f0g51+NjuAYELflM8+1vhQ/iv/G8vyZNKzSMuFd5doobngQKq3rRsLdPNZVnGqDdgS884d7Og==", |       "integrity": "sha512-BaklTBRQy1JTijR3hi8XxHf/uo76rHbDCNM/eQHSblzE9C0NoNfOe86nPxB7y1u2jwlqoEJ4zFiHpTFioKGGRA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@electron/get": "^1.6.0", |         "@electron/get": "^1.6.0", | ||||||
|         "asar": "^3.0.0", |         "asar": "^3.0.0", | ||||||
|         "debug": "^4.0.1", |         "debug": "^4.0.1", | ||||||
|         "electron-notarize": "^1.0.0", |         "electron-notarize": "^1.0.0", | ||||||
|         "electron-osx-sign": "^0.4.11", |         "electron-osx-sign": "^0.5.0", | ||||||
|         "extract-zip": "^2.0.0", |         "extract-zip": "^2.0.0", | ||||||
|         "filenamify": "^4.1.0", |         "filenamify": "^4.1.0", | ||||||
|         "fs-extra": "^9.0.0", |         "fs-extra": "^9.0.0", | ||||||
| @ -2965,7 +2965,7 @@ | |||||||
|         "rcedit": "^2.0.0", |         "rcedit": "^2.0.0", | ||||||
|         "resolve": "^1.1.6", |         "resolve": "^1.1.6", | ||||||
|         "semver": "^7.1.3", |         "semver": "^7.1.3", | ||||||
|         "yargs-parser": "^19.0.1" |         "yargs-parser": "^20.0.0" | ||||||
|       }, |       }, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "asar": { |         "asar": { | ||||||
| @ -3001,12 +3001,6 @@ | |||||||
|           "requires": { |           "requires": { | ||||||
|             "pump": "^3.0.0" |             "pump": "^3.0.0" | ||||||
|           } |           } | ||||||
|         }, |  | ||||||
|         "yargs-parser": { |  | ||||||
|           "version": "19.0.1", |  | ||||||
|           "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-19.0.1.tgz", |  | ||||||
|           "integrity": "sha512-2UuJKZmPN9S9/0s3FSCG3aNUSyC/qz56oJsMZG0NV2B44QxTXaNySp4xXW10CizmUs0DXgPY0y114dOGLvtYHg==", |  | ||||||
|           "dev": true |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
| @ -3674,9 +3668,9 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "filenamify": { |     "filenamify": { | ||||||
|       "version": "4.1.0", |       "version": "4.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", |       "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.2.0.tgz", | ||||||
|       "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", |       "integrity": "sha512-pkgE+4p7N1n7QieOopmn3TqJaefjdWXwEkj2XLZJLKfOgcQKkn11ahvGNgTD8mLggexLiDFQxeTs14xVU22XPA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "filename-reserved-regex": "^2.0.0", |         "filename-reserved-regex": "^2.0.0", | ||||||
| @ -3854,9 +3848,9 @@ | |||||||
|       }, |       }, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "debug": { |         "debug": { | ||||||
|           "version": "3.2.6", |           "version": "3.2.7", | ||||||
|           "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", |           "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", | ||||||
|           "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", |           "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", | ||||||
|           "dev": true, |           "dev": true, | ||||||
|           "requires": { |           "requires": { | ||||||
|             "ms": "^2.1.1" |             "ms": "^2.1.1" | ||||||
| @ -7951,9 +7945,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ws": { |     "ws": { | ||||||
|       "version": "7.4.0", |       "version": "7.4.1", | ||||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", |       "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", | ||||||
|       "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" |       "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" | ||||||
|     }, |     }, | ||||||
|     "xdg-basedir": { |     "xdg-basedir": { | ||||||
|       "version": "4.0.0", |       "version": "4.0.0", | ||||||
|  | |||||||
| @ -29,10 +29,10 @@ | |||||||
|     "better-sqlite3": "7.1.1", |     "better-sqlite3": "7.1.1", | ||||||
|     "body-parser": "1.19.0", |     "body-parser": "1.19.0", | ||||||
|     "cls-hooked": "4.2.2", |     "cls-hooked": "4.2.2", | ||||||
|     "commonmark": "0.29.2", |     "commonmark": "0.29.3", | ||||||
|     "cookie-parser": "1.4.5", |     "cookie-parser": "1.4.5", | ||||||
|     "csurf": "1.11.0", |     "csurf": "1.11.0", | ||||||
|     "dayjs": "1.9.6", |     "dayjs": "1.9.7", | ||||||
|     "ejs": "3.1.5", |     "ejs": "3.1.5", | ||||||
|     "electron-debug": "3.1.0", |     "electron-debug": "3.1.0", | ||||||
|     "electron-dl": "3.0.2", |     "electron-dl": "3.0.2", | ||||||
| @ -71,7 +71,7 @@ | |||||||
|     "turndown": "7.0.0", |     "turndown": "7.0.0", | ||||||
|     "turndown-plugin-gfm": "1.0.2", |     "turndown-plugin-gfm": "1.0.2", | ||||||
|     "unescape": "1.0.1", |     "unescape": "1.0.1", | ||||||
|     "ws": "7.4.0", |     "ws": "7.4.1", | ||||||
|     "yauzl": "2.10.0", |     "yauzl": "2.10.0", | ||||||
|     "yazl": "2.5.1" |     "yazl": "2.5.1" | ||||||
|   }, |   }, | ||||||
| @ -79,7 +79,7 @@ | |||||||
|     "cross-env": "7.0.3", |     "cross-env": "7.0.3", | ||||||
|     "electron": "9.3.5", |     "electron": "9.3.5", | ||||||
|     "electron-builder": "22.9.1", |     "electron-builder": "22.9.1", | ||||||
|     "electron-packager": "15.1.0", |     "electron-packager": "15.2.0", | ||||||
|     "electron-rebuild": "2.3.4", |     "electron-rebuild": "2.3.4", | ||||||
|     "esm": "3.2.25", |     "esm": "3.2.25", | ||||||
|     "jasmine": "3.6.3", |     "jasmine": "3.6.3", | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
|  | import ws from "./ws.js"; | ||||||
| 
 | 
 | ||||||
| /** @return {NoteShort} */ | /** @return {NoteShort} */ | ||||||
| async function getInboxNote() { | async function getInboxNote() { | ||||||
| @ -42,10 +43,20 @@ async function createSqlConsole() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** @return {NoteShort} */ | /** @return {NoteShort} */ | ||||||
| async function createSearchNote() { | async function createSearchNote(subTreeNoteId = null) { | ||||||
|     const note = await server.post('search-note'); |     const note = await server.post('search-note'); | ||||||
| 
 | 
 | ||||||
|     return await treeCache.getNote(note.noteId); |     if (subTreeNoteId) { | ||||||
|  |         await server.put(`notes/${note.noteId}/attributes`, [ | ||||||
|  |             { type: 'label', name: 'subTreeNoteId', value: subTreeNoteId } | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  | 
 | ||||||
|  |     const noteShort = await treeCache.getNote(note.noteId); | ||||||
|  | 
 | ||||||
|  |     return noteShort; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import Component from "../widgets/component.js"; | import Component from "../widgets/component.js"; | ||||||
| import appContext from "./app_context.js"; | import appContext from "./app_context.js"; | ||||||
| import dateNoteService from "../services/date_notes.js"; | import dateNoteService from "../services/date_notes.js"; | ||||||
| import noteCreateService from "../services/note_create.js"; | import treeService from "../services/tree.js"; | ||||||
| 
 | 
 | ||||||
| export default class DialogCommandExecutor extends Component { | export default class DialogCommandExecutor extends Component { | ||||||
|     jumpToNoteCommand() { |     jumpToNoteCommand() { | ||||||
| @ -75,6 +75,16 @@ export default class DialogCommandExecutor extends Component { | |||||||
|         appContext.triggerCommand('focusOnSearchDefinition', {tabId: tabContext.tabId}); |         appContext.triggerCommand('focusOnSearchDefinition', {tabId: tabContext.tabId}); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     async searchInSubtreeCommand({notePath}) { | ||||||
|  |         const noteId = treeService.getNoteIdFromNotePath(notePath); | ||||||
|  | 
 | ||||||
|  |         const searchNote = await dateNoteService.createSearchNote(noteId); | ||||||
|  | 
 | ||||||
|  |         const tabContext = await appContext.tabManager.openTabWithNote(searchNote.noteId, true); | ||||||
|  | 
 | ||||||
|  |         appContext.triggerCommand('focusOnSearchDefinition', {tabId: tabContext.tabId}); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     showBackendLogCommand() { |     showBackendLogCommand() { | ||||||
|         import("../dialogs/backend_log.js").then(d => d.showDialog()); |         import("../dialogs/backend_log.js").then(d => d.showDialog()); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -176,21 +176,6 @@ export default class Entrypoints extends Component { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async searchForResultsCommand({searchText}) { |  | ||||||
|         const response = await server.get('search/' + encodeURIComponent(searchText) + '?includeNoteContent=true&excludeArchived=true&fuzzyAttributeSearch=false'); |  | ||||||
| 
 |  | ||||||
|         if (!response.success) { |  | ||||||
|             toastService.showError("Search failed: " + response.message, 10000); |  | ||||||
|             // even in this case we'll show the results
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.triggerEvent('searchResults', {results: response.results}); |  | ||||||
| 
 |  | ||||||
|         // have at least some feedback which is good especially in situations
 |  | ||||||
|         // when the result list does not change with a query
 |  | ||||||
|         toastService.showMessage("Search finished successfully."); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async switchToDesktopVersionCommand() { |     async switchToDesktopVersionCommand() { | ||||||
|         utils.setCookie('trilium-device', 'desktop'); |         utils.setCookie('trilium-device', 'desktop'); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -129,6 +129,8 @@ class TreeContextMenu { | |||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|  |             console.log("Triggering", command, notePath); | ||||||
|  | 
 | ||||||
|             this.treeWidget.triggerCommand(command, {node: this.node, notePath: notePath}); |             this.treeWidget.triggerCommand(command, {node: this.node, notePath: notePath}); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1220,7 +1220,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         for (const action of actions) { |         for (const action of actions) { | ||||||
|             for (const shortcut of action.effectiveShortcuts) { |             for (const shortcut of action.effectiveShortcuts) { | ||||||
|                 hotKeyMap[utils.normalizeShortcut(shortcut)] = node => { |                 hotKeyMap[utils.normalizeShortcut(shortcut)] = node => { | ||||||
|                     this.triggerCommand(action.actionName, {node}); |                     const notePath = treeService.getNotePath(node); | ||||||
|  | 
 | ||||||
|  |                     this.triggerCommand(action.actionName, {node, notePath}); | ||||||
| 
 | 
 | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -96,13 +96,13 @@ export default class SearchDefinitionWidget extends TabAwareWidget { | |||||||
| 
 | 
 | ||||||
|     async updateSearch() { |     async updateSearch() { | ||||||
|         const searchString = this.$searchString.val(); |         const searchString = this.$searchString.val(); | ||||||
|         const subNoteId = this.$limitSearchToSubtree.getSelectedNoteId(); |         const subTreeNoteId = this.$limitSearchToSubtree.getSelectedNoteId(); | ||||||
|         const includeNoteContent = this.$searchWithinNoteContent.is(":checked"); |         const includeNoteContent = this.$searchWithinNoteContent.is(":checked"); | ||||||
| 
 | 
 | ||||||
|         await server.put(`notes/${this.noteId}/attributes`, [ |         await server.put(`notes/${this.noteId}/attributes`, [ | ||||||
|             { type: 'label', name: 'searchString', value: searchString }, |             { type: 'label', name: 'searchString', value: searchString }, | ||||||
|             { type: 'label', name: 'includeNoteContent', value: includeNoteContent ? 'true' : 'false' }, |             { type: 'label', name: 'includeNoteContent', value: includeNoteContent ? 'true' : 'false' }, | ||||||
|             subNoteId ? { type: 'label', name: 'subTreeNoteId', value: subNoteId } : undefined, |             subTreeNoteId ? { type: 'label', name: 'subTreeNoteId', value: subTreeNoteId } : undefined, | ||||||
|         ].filter(it => !!it)); |         ].filter(it => !!it)); | ||||||
| 
 | 
 | ||||||
|         if (this.note.title.startsWith('Search: ')) { |         if (this.note.title.startsWith('Search: ')) { | ||||||
| @ -122,7 +122,13 @@ export default class SearchDefinitionWidget extends TabAwareWidget { | |||||||
|         this.$component.show(); |         this.$component.show(); | ||||||
|         this.$searchString.val(this.note.getLabelValue('searchString')); |         this.$searchString.val(this.note.getLabelValue('searchString')); | ||||||
|         this.$searchWithinNoteContent.prop('checked', this.note.getLabelValue('includeNoteContent') === 'true'); |         this.$searchWithinNoteContent.prop('checked', this.note.getLabelValue('includeNoteContent') === 'true'); | ||||||
|         this.$limitSearchToSubtree.val(this.note.getLabelValue('subTreeNoteId')); | 
 | ||||||
|  |         const subTreeNoteId = this.note.getLabelValue('subTreeNoteId'); | ||||||
|  |         const subTreeNote = subTreeNoteId ? await treeCache.getNote(subTreeNoteId, true) : null; | ||||||
|  | 
 | ||||||
|  |         this.$limitSearchToSubtree | ||||||
|  |             .val(subTreeNote ? subTreeNote.title : "") | ||||||
|  |             .setSelectedNotePath(subTreeNoteId); | ||||||
| 
 | 
 | ||||||
|         this.refreshResults(); // important specifically when this search note was not yet refreshed
 |         this.refreshResults(); // important specifically when this search note was not yet refreshed
 | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -6,30 +6,6 @@ const log = require('../../services/log'); | |||||||
| const scriptService = require('../../services/script'); | const scriptService = require('../../services/script'); | ||||||
| const searchService = require('../../services/search/services/search'); | const searchService = require('../../services/search/services/search'); | ||||||
| 
 | 
 | ||||||
| function searchNotes(req) { |  | ||||||
|     const searchContext = new SearchContext({ |  | ||||||
|         includeNoteContent: req.query.includeNoteContent === 'true', |  | ||||||
|         excludeArchived: req.query.excludeArchived === 'true', |  | ||||||
|         fuzzyAttributeSearch: req.query.fuzzyAttributeSearch === 'true' |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     const {count, results} = searchService.searchTrimmedNotes(req.params.searchString, searchContext); |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|         return { |  | ||||||
|             success: !searchContext.hasError(), |  | ||||||
|             message: searchContext.getError(), |  | ||||||
|             count, |  | ||||||
|             results |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     catch { |  | ||||||
|         return { |  | ||||||
|             success: false |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async function searchFromNote(req) { | async function searchFromNote(req) { | ||||||
|     const note = repository.getNote(req.params.noteId); |     const note = repository.getNote(req.params.noteId); | ||||||
| 
 | 
 | ||||||
| @ -58,6 +34,7 @@ async function searchFromNote(req) { | |||||||
|         else if (searchString) { |         else if (searchString) { | ||||||
|             const searchContext = new SearchContext({ |             const searchContext = new SearchContext({ | ||||||
|                 includeNoteContent: note.getLabelValue('includeNoteContent') === 'true', |                 includeNoteContent: note.getLabelValue('includeNoteContent') === 'true', | ||||||
|  |                 subTreeNoteId: note.getLabelValue('subTreeNoteId'), | ||||||
|                 excludeArchived: true, |                 excludeArchived: true, | ||||||
|                 fuzzyAttributeSearch: false |                 fuzzyAttributeSearch: false | ||||||
|             }); |             }); | ||||||
| @ -197,7 +174,6 @@ function formatValue(val) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     searchNotes, |  | ||||||
|     searchFromNote, |     searchFromNote, | ||||||
|     getRelatedNotes |     getRelatedNotes | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -254,7 +254,6 @@ function register(app) { | |||||||
|     route(POST, '/api/sender/image', [auth.checkToken, uploadMiddleware], senderRoute.uploadImage, apiResultHandler); |     route(POST, '/api/sender/image', [auth.checkToken, uploadMiddleware], senderRoute.uploadImage, apiResultHandler); | ||||||
|     route(POST, '/api/sender/note', [auth.checkToken], senderRoute.saveNote, apiResultHandler); |     route(POST, '/api/sender/note', [auth.checkToken], senderRoute.saveNote, apiResultHandler); | ||||||
| 
 | 
 | ||||||
|     apiRoute(GET, '/api/search/:searchString', searchRoute.searchNotes); |  | ||||||
|     apiRoute(GET, '/api/search-note/:noteId', searchRoute.searchFromNote); |     apiRoute(GET, '/api/search-note/:noteId', searchRoute.searchFromNote); | ||||||
|     apiRoute(POST, '/api/search-related', searchRoute.getRelatedNotes); |     apiRoute(POST, '/api/search-related', searchRoute.getRelatedNotes); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								src/services/search/expressions/sub_tree.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/services/search/expressions/sub_tree.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const Expression = require('./expression'); | ||||||
|  | const NoteSet = require('../note_set'); | ||||||
|  | const log = require('../../log'); | ||||||
|  | const noteCache = require('../../note_cache/note_cache'); | ||||||
|  | 
 | ||||||
|  | class SubTreeExp extends Expression { | ||||||
|  |     constructor(subTreeNoteId) { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.subTreeNoteId = subTreeNoteId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     execute(inputNoteSet, searchContext) { | ||||||
|  |         const subTreeNote = noteCache.notes[this.subTreeNoteId]; | ||||||
|  | 
 | ||||||
|  |         if (!subTreeNote) { | ||||||
|  |             log.error(`Subtree note '${this.subTreeNoteId}' was not not found.`); | ||||||
|  | 
 | ||||||
|  |             return new NoteSet([]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return new NoteSet(subTreeNote.subtreeNotes).intersection(inputNoteSet); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = SubTreeExp; | ||||||
| @ -3,6 +3,7 @@ | |||||||
| class SearchContext { | class SearchContext { | ||||||
|     constructor(params = {}) { |     constructor(params = {}) { | ||||||
|         this.includeNoteContent = !!params.includeNoteContent; |         this.includeNoteContent = !!params.includeNoteContent; | ||||||
|  |         this.subTreeNoteId = params.subTreeNoteId; | ||||||
|         this.excludeArchived = !!params.excludeArchived; |         this.excludeArchived = !!params.excludeArchived; | ||||||
|         this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch; |         this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch; | ||||||
|         this.highlightedTokens = []; |         this.highlightedTokens = []; | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ const NoteCacheFulltextExp = require('../expressions/note_cache_flat_text.js'); | |||||||
| const NoteContentProtectedFulltextExp = require('../expressions/note_content_protected_fulltext.js'); | const NoteContentProtectedFulltextExp = require('../expressions/note_content_protected_fulltext.js'); | ||||||
| const NoteContentUnprotectedFulltextExp = require('../expressions/note_content_unprotected_fulltext.js'); | const NoteContentUnprotectedFulltextExp = require('../expressions/note_content_unprotected_fulltext.js'); | ||||||
| const OrderByAndLimitExp = require('../expressions/order_by_and_limit.js'); | const OrderByAndLimitExp = require('../expressions/order_by_and_limit.js'); | ||||||
|  | const SubTreeExp = require("../expressions/sub_tree.js"); | ||||||
| const buildComparator = require('./build_comparator.js'); | const buildComparator = require('./build_comparator.js'); | ||||||
| const ValueExtractor = require('../value_extractor.js'); | const ValueExtractor = require('../value_extractor.js'); | ||||||
| 
 | 
 | ||||||
| @ -409,6 +410,7 @@ function getExpression(tokens, searchContext, level = 0) { | |||||||
| function parse({fulltextTokens, expressionTokens, searchContext}) { | function parse({fulltextTokens, expressionTokens, searchContext}) { | ||||||
|     return AndExp.of([ |     return AndExp.of([ | ||||||
|         searchContext.excludeArchived ? new PropertyComparisonExp("isarchived", buildComparator("=", "false")) : null, |         searchContext.excludeArchived ? new PropertyComparisonExp("isarchived", buildComparator("=", "false")) : null, | ||||||
|  |         searchContext.subTreeNoteId ? new SubTreeExp(searchContext.subTreeNoteId) : null, | ||||||
|         getFulltext(fulltextTokens, searchContext), |         getFulltext(fulltextTokens, searchContext), | ||||||
|         getExpression(expressionTokens, searchContext) |         getExpression(expressionTokens, searchContext) | ||||||
|     ]); |     ]); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam