From 712ff8265e23858b62eeaa9b3f2d48e7fd577b7d Mon Sep 17 00:00:00 2001 From: Aditya Sharma <65771169+adityash1@users.noreply.github.com> Date: Mon, 2 Jan 2023 23:30:10 +0530 Subject: [PATCH] feat: add `search title only` filter for search options (#4587) * feat: search title only filter * fix: page reload will keep settings * fix: working with additional filters * style changes --- app/scenes/Search/Search.tsx | 32 ++++++++++++++++++++-- app/stores/DocumentsStore.ts | 23 +++++++++++++++- shared/i18n/locales/en_US/translation.json | 1 + 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/app/scenes/Search/Search.tsx b/app/scenes/Search/Search.tsx index 1fd205c74..1542d42a6 100644 --- a/app/scenes/Search/Search.tsx +++ b/app/scenes/Search/Search.tsx @@ -21,6 +21,7 @@ import Flex from "~/components/Flex"; import LoadingIndicator from "~/components/LoadingIndicator"; import RegisterKeyDown from "~/components/RegisterKeyDown"; import Scene from "~/components/Scene"; +import Switch from "~/components/Switch"; import Text from "~/components/Text"; import withStores from "~/components/withStores"; import Logger from "~/utils/Logger"; @@ -159,6 +160,7 @@ class Search extends React.Component { userId?: string | undefined; dateFilter?: TDateFilter; includeArchived?: boolean | undefined; + titleFilter?: boolean | undefined; }) => { this.props.history.replace({ pathname: this.props.location.pathname, @@ -171,6 +173,10 @@ class Search extends React.Component { }); }; + handleTitleFilterChange = (ev: React.ChangeEvent) => { + this.handleFilterChange({ titleFilter: ev.target.checked }); + }; + get includeArchived() { return this.params.get("includeArchived") === "true"; } @@ -190,12 +196,17 @@ class Search extends React.Component { return id ? (id as TDateFilter) : undefined; } + get titleFilter() { + return this.params.get("titleFilter") === "true"; + } + get isFiltered() { return ( this.dateFilter || this.userId || this.collectionId || - this.includeArchived + this.includeArchived || + this.titleFilter ); } @@ -230,6 +241,7 @@ class Search extends React.Component { includeDrafts: true, collectionId: this.collectionId, userId: this.userId, + titleFilter: this.titleFilter, }; // we just requested this thing – no need to try again @@ -243,7 +255,9 @@ class Search extends React.Component { this.lastParams = params; try { - const results = await this.props.documents.search(this.query, params); + const results = this.titleFilter + ? await this.props.documents.searchTitles(this.query, params) + : await this.props.documents.search(this.query, params); // Add to the searches store so this search can immediately appear in // the recent searches list without a flash of load @@ -348,6 +362,13 @@ class Search extends React.Component { }) } /> + ) : ( @@ -437,4 +458,11 @@ const Filters = styled(Flex)` } `; +const SearchTitleOnlyFilter = styled(Switch)` + margin-left: 8px; + margin-top: 2px; + font-size: 14px; + font-weight: 500; +`; + export default withTranslation()(withStores(withRouter(Search))); diff --git a/app/stores/DocumentsStore.ts b/app/stores/DocumentsStore.ts index 67c658b86..bba003750 100644 --- a/app/stores/DocumentsStore.ts +++ b/app/stores/DocumentsStore.ts @@ -385,14 +385,35 @@ export default class DocumentsStore extends BaseStore { }; @action - searchTitles = async (query: string) => { + searchTitles = async (query: string, options?: SearchParams) => { + const compactedOptions = omitBy(options, (o) => !o); const res = await client.post("/documents.search_titles", { + ...compactedOptions, query, }); invariant(res?.data, "Search response should be available"); + // add the documents and associated policies to the store res.data.forEach(this.add); this.addPolicies(res.policies); + + // store a reference to the document model in the search cache instead + // of the original result from the API. + const results: SearchResult[] = compact( + res.data.map((result: SearchResult) => { + const document = this.data.get(result.id); + if (!document) { + return null; + } + return { + document, + }; + }) + ); + const existing = this.searchCache.get(query) || []; + // splice modifies any existing results, taking into account pagination + existing.splice(0, existing.length, ...results); + this.searchCache.set(query, existing); return res.data; }; diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index 471b973bd..5abc7d896 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -622,6 +622,7 @@ "Any author": "Any author", "Author": "Author", "We were unable to find the page you’re looking for.": "We were unable to find the page you’re looking for.", + "Search titles only": "Search titles only", "No documents found for your search filters.": "No documents found for your search filters.", "Search Results": "Search Results", "Allowed domains": "Allowed domains",