From 65989829d10b9fa7b6dce71085f788f8027dac05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 26 Aug 2024 14:05:58 +0200 Subject: [PATCH 001/101] WIP --- src/ROUTES.ts | 4 ++-- src/components/Search/index.tsx | 12 +++++++++--- src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/libs/API/types.ts | 2 ++ src/libs/Navigation/types.ts | 1 + src/libs/actions/Search.ts | 13 +++++++++++++ src/pages/Search/AdvancedSearchFilters.tsx | 18 ++++++++++++++++++ src/pages/Search/SearchPage.tsx | 3 ++- 9 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 47a2ad76209e..93e34a934c21 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -35,8 +35,8 @@ const ROUTES = { SEARCH_CENTRAL_PANE: { route: 'search', - getRoute: ({query, isCustomQuery = false, policyIDs}: {query: SearchQueryString; isCustomQuery?: boolean; policyIDs?: string}) => - `search?q=${query}&isCustomQuery=${isCustomQuery}${policyIDs ? `&policyIDs=${policyIDs}` : ''}` as const, + getRoute: ({query, isCustomQuery = false, isSavedSearch = false, policyIDs}: {query: SearchQueryString; isCustomQuery?: boolean; isSavedSearch?: boolean; policyIDs?: string}) => + `search?q=${query}&isCustomQuery=${isCustomQuery}${isSavedSearch ? `&isSavedSearch=${isSavedSearch}` : ''}${policyIDs ? `&policyIDs=${policyIDs}` : ''}` as const, }, SEARCH_ADVANCED_FILTERS: 'search/filters', SEARCH_ADVANCED_FILTERS_DATE: 'search/filters/date', diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index df5398bffffa..de1d03bd4372 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -36,6 +36,7 @@ import type {SearchColumnType, SearchQueryJSON, SearchStatus, SelectedTransactio type SearchProps = { queryJSON: SearchQueryJSON; isCustomQuery: boolean; + isSavedSearch: boolean; policyIDs?: string; }; @@ -73,7 +74,7 @@ function prepareTransactionsList(item: TransactionListItemType, selectedTransact return {...selectedTransactions, [item.keyForList]: {isSelected: true, canDelete: item.canDelete, canHold: item.canHold, canUnhold: item.canUnhold, action: item.action}}; } -function Search({queryJSON, policyIDs, isCustomQuery}: SearchProps) { +function Search({queryJSON, policyIDs, isCustomQuery, isSavedSearch}: SearchProps) { const {isOffline} = useNetwork(); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -117,9 +118,14 @@ function Search({queryJSON, policyIDs, isCustomQuery}: SearchProps) { return; } - SearchActions.search({queryJSON, offset, policyIDs}); + if (isSavedSearch === 'true') { + SearchActions.saveSearch({queryJSON, policyIDs}); + } else { + SearchActions.search({queryJSON, offset, policyIDs}); + } + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, [isOffline, offset, queryJSON]); + }, [isOffline, offset, queryJSON, isSavedSearch]); const handleOnCancelConfirmModal = () => { setDeleteExpensesConfirmModalVisible(false); diff --git a/src/languages/en.ts b/src/languages/en.ts index 632da6f9c3ae..a7fd9e76444b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3746,6 +3746,7 @@ export default { buttonText: 'Book a trip', }, }, + saveSearch: 'Save search', groupedExpenses: 'grouped expenses', bulkActions: { delete: 'Delete', diff --git a/src/languages/es.ts b/src/languages/es.ts index 77ba5e5abf45..a0d35c7505ef 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3796,6 +3796,7 @@ export default { buttonText: 'Reserva un viaje', }, }, + saveSearch: 'Guardar búsqueda', groupedExpenses: 'gastos agrupados', bulkActions: { delete: 'Eliminar', diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 5ea2ae44b74d..25b97eb17034 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -336,6 +336,7 @@ const WRITE_COMMANDS = { CREATE_EXPENSIFY_CARD: 'CreateExpensifyCard', CREATE_ADMIN_ISSUED_VIRTUAL_CARD: 'CreateAdminIssuedVirtualCard', TOGGLE_CARD_CONTINUOUS_RECONCILIATION: 'ToggleCardContinuousReconciliation', + SAVE_SEARCH: 'SaveSearch', } as const; type WriteCommand = ValueOf; @@ -677,6 +678,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.CREATE_EXPENSIFY_CARD]: Parameters.CreateExpensifyCardParams; [WRITE_COMMANDS.CREATE_ADMIN_ISSUED_VIRTUAL_CARD]: Omit; [WRITE_COMMANDS.TOGGLE_CARD_CONTINUOUS_RECONCILIATION]: Parameters.ToggleCardContinuousReconciliationParams; + [WRITE_COMMANDS.SAVE_SEARCH]: Parameters.SearchParams; }; const READ_COMMANDS = { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ceb62f1dac1c..c183619d7873 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -69,6 +69,7 @@ type CentralPaneScreensParamList = { [SCREENS.SEARCH.CENTRAL_PANE]: { q: SearchQueryString; isCustomQuery: boolean; + isSavedSearch: boolean; policyIDs?: string; }; [SCREENS.SETTINGS.SAVE_THE_WORLD]: undefined; diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index b51955c9cc59..833079486a98 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -49,6 +49,18 @@ function getOnyxLoadingData(hash: number): {optimisticData: OnyxUpdate[]; finall return {optimisticData, finallyData}; } +function saveSearch({queryJSON, offset, policyIDs}: {queryJSON: SearchQueryJSON; offset?: number; policyIDs?: string}) { + const {optimisticData, finallyData} = getOnyxLoadingData(queryJSON.hash); + const queryWithOffset = { + ...queryJSON, + offset, + }; + const jsonQuery = JSON.stringify(queryWithOffset); + + API.write(WRITE_COMMANDS.SAVE_SEARCH, {hash: queryJSON.hash, jsonQuery, policyIDs}, {optimisticData, finallyData}); +} + + function search({queryJSON, offset, policyIDs}: {queryJSON: SearchQueryJSON; offset?: number; policyIDs?: string}) { const {optimisticData, finallyData} = getOnyxLoadingData(queryJSON.hash); @@ -133,6 +145,7 @@ function clearAdvancedFilters() { } export { + saveSearch, search, createTransactionThread, deleteMoneyRequestOnSearch, diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index 4b859e37785e..d4b3bb7d3f7d 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -23,6 +23,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {SearchAdvancedFiltersForm} from '@src/types/form'; import type {CardList, PersonalDetailsList} from '@src/types/onyx'; +import Button from '@components/Button'; function getFilterCardDisplayTitle(filters: Partial, cards: CardList) { const filterValue = filters[CONST.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID]; @@ -213,6 +214,17 @@ function AdvancedSearchFilters() { [searchAdvancedFilters, translate, cardList, taxRates, personalDetails], ); + const onSaveSearch = () => { + SearchActions.clearAdvancedFilters(); + Navigation.navigate( + ROUTES.SEARCH_CENTRAL_PANE.getRoute({ + query: SearchUtils.buildQueryStringFromFilters(searchAdvancedFilters), + isCustomQuery: true, + isSavedSearch: true, + }), + ); + } + const onFormSubmit = () => { const query = SearchUtils.buildQueryStringFromFilters(searchAdvancedFilters); SearchActions.clearAdvancedFilters(); @@ -245,6 +257,12 @@ function AdvancedSearchFilters() { })} +