hidden notes should not appear in the global search unless hoisted into it, #3516

This commit is contained in:
zadam 2023-01-13 10:09:41 +01:00
parent e7b3c3239b
commit 88bc7402a2
9 changed files with 64 additions and 6 deletions

View File

@ -1107,6 +1107,13 @@ class Note extends AbstractEntity {
return notePaths; return notePaths;
} }
/**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/
isHiddenCompletely() {
return !this.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'));
}
/** /**
* @param ancestorNoteId * @param ancestorNoteId
* @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths * @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths

View File

@ -364,6 +364,13 @@ class NoteShort {
return notePaths; return notePaths;
} }
/**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/
isHiddenCompletely() {
return !this.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'));
}
__filterAttrs(attributes, type, name) { __filterAttrs(attributes, type, name) {
this.__validateTypeName(type, name); this.__validateTypeName(type, name);

View File

@ -230,6 +230,10 @@ function init() {
$.fn.getSelectedNoteId = function () { $.fn.getSelectedNoteId = function () {
const notePath = $(this).getSelectedNotePath(); const notePath = $(this).getSelectedNotePath();
if (!notePath) {
return null;
}
const chunks = notePath.split('/'); const chunks = notePath.split('/');
return chunks.length >= 1 ? chunks[chunks.length - 1] : null; return chunks.length >= 1 ? chunks[chunks.length - 1] : null;

View File

@ -76,7 +76,7 @@ export default class CodeButtonsWidget extends NoteContextAwareWidget {
this.$saveToNoteButton.toggle( this.$saveToNoteButton.toggle(
note.mime === 'text/x-sqlite;schema=trilium' note.mime === 'text/x-sqlite;schema=trilium'
&& !note.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden')) && note.isHiddenCompletely()
); );
this.$openTriliumApiDocsButton.toggle(note.mime.startsWith('application/javascript;env=')); this.$openTriliumApiDocsButton.toggle(note.mime.startsWith('application/javascript;env='));

View File

@ -270,7 +270,7 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
async refreshWithNote(note) { async refreshWithNote(note) {
this.$component.show(); this.$component.show();
this.$saveToNoteButton.toggle(!note.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'))); this.$saveToNoteButton.toggle(note.isHiddenCompletely());
this.$searchOptions.empty(); this.$searchOptions.empty();

View File

@ -0,0 +1,23 @@
"use strict";
const Expression = require('./expression');
const NoteSet = require('../note_set');
/**
* Note is hidden when all its note paths start in hidden subtree (i.e. the note is not cloned into visible tree)
*/
class IsHiddenExp extends Expression {
execute(inputNoteSet, executionContext, searchContext) {
const resultNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
if (note.isHiddenCompletely()) {
resultNoteSet.add(note);
}
}
return resultNoteSet;
}
}
module.exports = IsHiddenExp;

View File

@ -6,10 +6,11 @@ class SearchContext {
constructor(params = {}) { constructor(params = {}) {
this.fastSearch = !!params.fastSearch; this.fastSearch = !!params.fastSearch;
this.includeArchivedNotes = !!params.includeArchivedNotes; this.includeArchivedNotes = !!params.includeArchivedNotes;
this.includeHiddenNotes = !!params.includeHiddenNotes;
this.ignoreHoistedNote = !!params.ignoreHoistedNote; this.ignoreHoistedNote = !!params.ignoreHoistedNote;
this.ancestorNoteId = params.ancestorNoteId; this.ancestorNoteId = params.ancestorNoteId;
if (!this.ancestorNoteId && !this.ignoreHoistedNote && !hoistedNoteService.isHoistedInHiddenSubtree()) { if (!this.ancestorNoteId && !this.ignoreHoistedNote) {
// hoisting in hidden subtree should not limit autocomplete // hoisting in hidden subtree should not limit autocomplete
// since we want to link (create relations) to the normal non-hidden notes // since we want to link (create relations) to the normal non-hidden notes
this.ancestorNoteId = hoistedNoteService.getHoistedNoteId(); this.ancestorNoteId = hoistedNoteService.getHoistedNoteId();

View File

@ -18,7 +18,8 @@ const AncestorExp = require("../expressions/ancestor");
const buildComparator = require('./build_comparator'); const buildComparator = require('./build_comparator');
const ValueExtractor = require('../value_extractor'); const ValueExtractor = require('../value_extractor');
const utils = require("../../utils"); const utils = require("../../utils");
const TrueExp = require("../expressions/true.js"); const TrueExp = require("../expressions/true");
const IsHiddenExp = require("../expressions/is_hidden");
function getFulltext(tokens, searchContext) { function getFulltext(tokens, searchContext) {
tokens = tokens.map(t => utils.removeDiacritic(t.token)); tokens = tokens.map(t => utils.removeDiacritic(t.token));
@ -429,7 +430,7 @@ function parse({fulltextTokens, expressionTokens, searchContext}) {
let exp = AndExp.of([ let exp = AndExp.of([
searchContext.includeArchivedNotes ? null : new PropertyComparisonExp(searchContext, "isarchived", "=", "false"), searchContext.includeArchivedNotes ? null : new PropertyComparisonExp(searchContext, "isarchived", "=", "false"),
(searchContext.ancestorNoteId && searchContext.ancestorNoteId !== 'root') ? new AncestorExp(searchContext.ancestorNoteId, searchContext.ancestorDepth) : null, getAncestorExp(searchContext),
getFulltext(fulltextTokens, searchContext), getFulltext(fulltextTokens, searchContext),
expression expression
]); ]);
@ -448,4 +449,14 @@ function parse({fulltextTokens, expressionTokens, searchContext}) {
return exp; return exp;
} }
function getAncestorExp({ancestorNoteId, ancestorDepth, includeHiddenNotes}) {
if (ancestorNoteId && ancestorNoteId !== 'root') {
return new AncestorExp(ancestorNoteId, ancestorDepth);
} else if (!includeHiddenNotes) {
return new NotExp(new IsHiddenExp());
} else {
return null;
}
}
module.exports = parse; module.exports = parse;

View File

@ -11,6 +11,7 @@ const beccaService = require('../../../becca/becca_service');
const utils = require('../../utils'); const utils = require('../../utils');
const log = require('../../log'); const log = require('../../log');
const scriptService = require("../../script"); const scriptService = require("../../script");
const hoistedNoteService = require("../../hoisted_note");
function searchFromNote(note) { function searchFromNote(note) {
let searchResultNoteIds, highlightedTokens; let searchResultNoteIds, highlightedTokens;
@ -271,7 +272,11 @@ function searchNotesForAutocomplete(query) {
const searchContext = new SearchContext({ const searchContext = new SearchContext({
fastSearch: true, fastSearch: true,
includeArchivedNotes: false, includeArchivedNotes: false,
fuzzyAttributeSearch: true includeHiddenNotes: true,
fuzzyAttributeSearch: true,
ancestorNoteId: hoistedNoteService.isHoistedInHiddenSubtree()
? 'root'
: hoistedNoteService.getHoistedNoteId()
}); });
const allSearchResults = findResultsWithQuery(query, searchContext); const allSearchResults = findResultsWithQuery(query, searchContext);