From 0c1358c033472bc00aa26244d89c8a774d54ba3c Mon Sep 17 00:00:00 2001 From: Christopher Loverich <1010084+cloverich@users.noreply.github.com> Date: Sun, 14 Jan 2024 16:14:18 -0800 Subject: [PATCH] filter invalid in: tokens - if in: token references a journal that does not exist, drop it from the UI to clarify its not being included in the search - clean up some comments / typos --- src/preload/client/documents.ts | 2 +- src/views/documents/SearchStore.test.ts | 10 +++++++++ src/views/documents/SearchStore.ts | 23 +++++++++++++++++--- src/views/documents/TagSearchStore.ts | 8 +++---- src/views/documents/index.tsx | 8 +++---- src/views/documents/search/parsers/before.ts | 9 ++------ 6 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 src/views/documents/SearchStore.test.ts diff --git a/src/preload/client/documents.ts b/src/preload/client/documents.ts index 6a6e27a..4d6c6ec 100644 --- a/src/preload/client/documents.ts +++ b/src/preload/client/documents.ts @@ -125,7 +125,7 @@ export class DocumentsClient { if (q?.titles?.length) { for (const title of q.titles) { // note: andWhereILike throws a SQL syntax error in SQLite. - // It seems case insensitie without it? + // It seems case insensitive without it? query = query.andWhereLike('title', `%${title}%`); } } diff --git a/src/views/documents/SearchStore.test.ts b/src/views/documents/SearchStore.test.ts new file mode 100644 index 0000000..e10f69d --- /dev/null +++ b/src/views/documents/SearchStore.test.ts @@ -0,0 +1,10 @@ +import { suite, test } from "mocha"; + + +suite("SearchStore", function () { + + // TODO: Test _tokens, computed getter, setter works + // TODO: Test add / remove token work through it + // TODO: Test it filters out invalid in: journal tokens + test("setTokens") +}); \ No newline at end of file diff --git a/src/views/documents/SearchStore.ts b/src/views/documents/SearchStore.ts index b76939f..775e2da 100644 --- a/src/views/documents/SearchStore.ts +++ b/src/views/documents/SearchStore.ts @@ -1,5 +1,5 @@ import { IClient } from "../../hooks/useClient"; -import { observable, IObservableArray, reaction, computed } from "mobx"; +import { observable, IObservableArray, reaction, computed, action } from "mobx"; import { JournalsStore } from "../../hooks/stores/journals"; import { SearchToken } from "./search/tokens"; import { TagSearchStore } from "./TagSearchStore"; @@ -19,7 +19,7 @@ export class SearchV2Store { private tagSeachStore: TagSearchStore; private setTokensUrl: any; // todo: This is react-router-dom's setUrl; type it - @observable tokens: IObservableArray = observable([]); + @observable private _tokens: IObservableArray = observable([]); constructor(private client: IClient, journals: JournalsStore, setTokensUrl: any) { this.journals = journals; @@ -27,11 +27,28 @@ export class SearchV2Store { this.setTokensUrl = setTokensUrl; // Re-run the search query anytime the tokens change. - reaction(() => this.tokens.slice(), this.search, { + reaction(() => this._tokens.slice(), this.search, { fireImmediately: false, }); } + @action + setTokens = (tokens: SearchToken[]) => { + // Filter out invalid in: journal tokens + // Additional validation can go here as well + tokens = tokens.filter((t) => { + if (t.type !== "in") return true; + const journal = this.journals.idForName(t.value as string); + return !!journal; + }); + + this.tokens.replace(tokens); + } + + @computed get tokens(): IObservableArray { + return this._tokens; + } + // todo: this might be better as a @computed get private tokensToQuery = () => { const journals = this.tokens diff --git a/src/views/documents/TagSearchStore.ts b/src/views/documents/TagSearchStore.ts index b116ad6..19ec0a6 100644 --- a/src/views/documents/TagSearchStore.ts +++ b/src/views/documents/TagSearchStore.ts @@ -8,8 +8,7 @@ import { TitleTokenParser } from "./search/parsers/title"; import { TextTokenParser } from "./search/parsers/text"; import { BeforeTokenParser } from './search/parsers/before'; -// NOTE: This won't allow searching where value has colon in it -// Feel free to improe this +// TODO: This won't allow searching where value has colon in it const tokenRegex = /^(.*):(.*)/; interface TokenParser { @@ -36,6 +35,7 @@ const parsers: Record> = { */ export interface ITokensStore { tokens: IObservableArray; + setTokens: (tokens: SearchToken[]) => void; } /** @@ -106,7 +106,7 @@ export class TagSearchStore { const [parser, parsedToken] = results; const tokens = parser.add(this.store.tokens, parsedToken); - this.store.tokens = observable(tokens); + this.store.setTokens(tokens); }; @action @@ -116,6 +116,6 @@ export class TagSearchStore { const [parser, parsedToken] = results; const tokens = parser.remove(this.store.tokens.slice(), parsedToken); - this.store.tokens = observable(tokens); + this.store.setTokens(tokens); }; } diff --git a/src/views/documents/index.tsx b/src/views/documents/index.tsx index 27d4f4a..8f6f2cb 100644 --- a/src/views/documents/index.tsx +++ b/src/views/documents/index.tsx @@ -29,14 +29,12 @@ function DocumentsContainer() { console.log('Documents.index.useEffect') const tokens = params.getAll('search'); - // Ok, this does not trigger initial search reaction because there are no + // does not trigger initial search reaction because there are no // tokens and the change is based on length, and there fireImmediately is false - // This whole thing is dumb. + // Make this more elegant. if (tokens.length) { - console.log('Documents.index passing tokens to searchStore', tokens) searchStore.addTokens(tokens); } else { - console.log('Documents.index calling search directly') searchStore.search(); } }, []) @@ -51,7 +49,7 @@ function DocumentsContainer() { } // todo: Improve error handling - // case: can re-attempt search when searchStore has error (works) + // test case: can re-attempt search when searchStore has error (works) if (searchStore.error) { return ( diff --git a/src/views/documents/search/parsers/before.ts b/src/views/documents/search/parsers/before.ts index c26fe96..dc8dab2 100644 --- a/src/views/documents/search/parsers/before.ts +++ b/src/views/documents/search/parsers/before.ts @@ -13,12 +13,7 @@ export class BeforeTokenParser { }; add = (tokens: SearchToken[], token: BeforeToken) => { - // TODO: I dont remember what these comments were about // replace existing after token - // this.remove(tokens, token); - // TRY: What if URL syncing does "has" before "add"? - - const existing = tokens.find(t => t.type === 'before'); if (existing) { if (existing.value !== token.value) { @@ -43,8 +38,8 @@ export class BeforeTokenParser { remove = (tokens: SearchToken[], token: BeforeToken) => { return tokens.filter((t) => { - // since we can have only one after token; keep - // everything that isn't an after token + // since we can have only one before token; keep + // everything that isn't an before token return t.type !== "before"; }); };