import TypeWidget from "./type_widgets/type_widget.js"; import noteAutocompleteService from "../services/note_autocomplete.js"; import SpacedUpdate from "../services/spaced_update.js"; import server from "../services/server.js"; import toastService from "../services/toast.js"; import NoteListRenderer from "../services/note_list_renderer.js"; import TabAwareWidget from "./tab_aware_widget.js"; import treeCache from "../services/tree_cache.js"; const TPL = `
Search string:
Limit search to subtree:
`; export default class SearchDefinitionWidget extends TabAwareWidget { static getType() { return "search"; } renderTitle(note) { return { show: note.type === 'search', activate: true, $title: 'Search' }; } doRender() { this.$widget = $(TPL); this.contentSized(); this.$searchString = this.$widget.find(".search-string"); this.$searchString.on('input', () => this.spacedUpdate.scheduleUpdate()); this.$component = this.$widget.find('.search-definition-widget'); this.spacedUpdate = new SpacedUpdate(() => this.updateSearch(), 2000); this.$limitSearchToSubtree = this.$widget.find('.limit-search-to-subtree'); noteAutocompleteService.initNoteAutocomplete(this.$limitSearchToSubtree); this.$limitSearchToSubtree.on('autocomplete:closed', e => { this.spacedUpdate.scheduleUpdate(); }); this.$searchWithinNoteContent = this.$widget.find('.search-within-note-content'); this.$searchWithinNoteContent.on('change', () => { this.spacedUpdate.scheduleUpdate(); }); } async updateSearch() { const searchString = this.$searchString.val(); const subTreeNoteId = this.$limitSearchToSubtree.getSelectedNoteId(); const includeNoteContent = this.$searchWithinNoteContent.is(":checked"); await server.put(`notes/${this.noteId}/attributes`, [ { type: 'label', name: 'searchString', value: searchString }, { type: 'label', name: 'includeNoteContent', value: includeNoteContent ? 'true' : 'false' }, subTreeNoteId ? { type: 'label', name: 'subTreeNoteId', value: subTreeNoteId } : undefined, ].filter(it => !!it)); if (this.note.title.startsWith('Search: ')) { await server.put(`notes/${this.noteId}/change-title`, { title: 'Search: ' + (searchString.length < 30 ? searchString : `${searchString.substr(0, 30)}…`) }); } await this.refreshResults(); } async refreshResults() { await treeCache.reloadNotes([this.noteId]); } async refreshWithNote(note) { this.$component.show(); this.$searchString.val(this.note.getLabelValue('searchString')); this.$searchWithinNoteContent.prop('checked', this.note.getLabelValue('includeNoteContent') === 'true'); 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 } focusOnSearchDefinitionEvent() { this.$searchString.focus(); } getContent() { return JSON.stringify({ searchString: this.$searchString.val() }); } }