From 9a7b66f675a277c7ea414dd17da34ccbf66dc630 Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Tue, 14 Oct 2025 00:52:37 +0500 Subject: [PATCH 1/6] remove deleted WS's expenses from Submit search page --- src/components/Search/index.tsx | 12 ++++++++++-- src/libs/SearchUIUtils.ts | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index dc9978646a2f..7ecb800aab7b 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -408,6 +408,8 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS const shouldShowLoadingMoreItems = !shouldShowLoadingState && searchResults?.search?.isLoading && searchResults?.search?.offset > 0; const prevIsSearchResultEmpty = usePrevious(isSearchResultsEmpty); + const [allReportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS); + const [data, dataLength] = useMemo(() => { if (searchResults === undefined || !isDataLoaded) { return [[], 0]; @@ -420,9 +422,15 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS return [[], 0]; } - const data1 = getSections(type, searchResults.data, accountID, formatPhoneNumber, groupBy, exportReportActions, searchKey, archivedReportsIdSet, queryJSON); + // Merging live REPORT_NAME_VALUE_PAIRS into search data to get latest archived status + const mergedSearchData = { + ...searchResults.data, + ...allReportNameValuePairs, + }; + + const data1 = getSections(type, mergedSearchData, accountID, formatPhoneNumber, groupBy, exportReportActions, searchKey, archivedReportsIdSet, queryJSON); return [data1, data1.length]; - }, [searchKey, exportReportActions, groupBy, isDataLoaded, searchResults, type, archivedReportsIdSet, formatPhoneNumber, accountID, queryJSON]); + }, [searchKey, exportReportActions, groupBy, isDataLoaded, searchResults, type, archivedReportsIdSet, formatPhoneNumber, accountID, queryJSON, allReportNameValuePairs]); useEffect(() => { /** We only want to display the skeleton for the status filters the first time we load them for a specific data type */ diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 8322c67b6fb7..9f0c69946daa 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1369,6 +1369,7 @@ function getReportSections( currentAccountID: number | undefined, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], reportActions: Record = {}, + queryJSON?: SearchQueryJSON, ): TransactionGroupListItemType[] { const shouldShowMerchant = getShouldShowMerchant(data); @@ -1378,7 +1379,11 @@ function getReportSections( // Get violations - optimize by using a Map for faster lookups const allViolations = getViolations(data); - const queryJSON = getCurrentSearchQueryJSON(); + // Check if the current search is filtering by the Submit action + const isSubmitActionFilter = !!queryJSON?.flatFilters + ?.find((filterGroup) => filterGroup.key === CONST.SEARCH.SYNTAX_FILTER_KEYS.ACTION) + ?.filters?.some((filter) => filter.value === CONST.SEARCH.ACTION_FILTERS.SUBMIT); + const reportIDToTransactions: Record = {}; const {reportKeys, transactionKeys} = Object.keys(data).reduce( @@ -1418,6 +1423,15 @@ function getReportSections( } } + // Hiding reports from archived/deleted workspaces in Submit search + if (shouldShow && isSubmitActionFilter) { + const reportNVP = data[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportItem.reportID}`]; + const chatReportNVP = data[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportItem.chatReportID}`]; + if (isArchivedReport(reportNVP) || isArchivedReport(chatReportNVP)) { + shouldShow = false; + } + } + if (shouldShow) { const reportPendingAction = reportItem?.pendingAction ?? reportItem?.pendingFields?.preview; const shouldShowBlankTo = !reportItem || isOpenExpenseReport(reportItem); @@ -1631,7 +1645,7 @@ function getSections( // eslint-disable-next-line default-case switch (groupBy) { case CONST.SEARCH.GROUP_BY.REPORTS: - return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions); + return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions, queryJSON); case CONST.SEARCH.GROUP_BY.FROM: return getMemberSections(data, queryJSON); case CONST.SEARCH.GROUP_BY.CARD: From 79f95dd6ad52f9ad0450d4cbcb8545b1e4e57b0f Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Tue, 14 Oct 2025 01:41:10 +0500 Subject: [PATCH 2/6] fix: allow missing report name value pairs in Search component --- src/components/Search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 7ecb800aab7b..d937465892ad 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -408,7 +408,7 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS const shouldShowLoadingMoreItems = !shouldShowLoadingState && searchResults?.search?.isLoading && searchResults?.search?.offset > 0; const prevIsSearchResultEmpty = usePrevious(isSearchResultsEmpty); - const [allReportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS); + const [allReportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, {canBeMissing: true}); const [data, dataLength] = useMemo(() => { if (searchResults === undefined || !isDataLoaded) { From f4ab10980ca6034a79a11299a2350bf125d4289d Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Sat, 18 Oct 2025 21:04:16 +0500 Subject: [PATCH 3/6] Update getReportSections call in SearchUIUtils to include queryJSON parameter --- src/libs/SearchUIUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 754418662fc3..242e2bfab905 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1638,7 +1638,7 @@ function getSections( } if (type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT) { - return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions); + return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions, queryJSON); } if (groupBy) { From ad0a4a56f27267ea26d1aaaf18c9b022dd4d4d33 Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Sat, 18 Oct 2025 21:06:02 +0500 Subject: [PATCH 4/6] prettier fix --- src/components/Search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 7792dab579b2..b60146df295f 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -391,7 +391,7 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS return [[], 0]; } - // Merging live REPORT_NAME_VALUE_PAIRS into search data to get latest archived status + // Merging live REPORT_NAME_VALUE_PAIRS into search data to get latest archived status const mergedSearchData = { ...searchResults.data, ...allReportNameValuePairs, From f0082396e16d241ebba35639e0c84feb2ea5e0c1 Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Sun, 19 Oct 2025 02:29:42 +0500 Subject: [PATCH 5/6] comment enhancement --- src/components/Search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index b60146df295f..3aa4cafb0633 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -391,7 +391,7 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS return [[], 0]; } - // Merging live REPORT_NAME_VALUE_PAIRS into search data to get latest archived status + // Merging live REPORT_NAME_VALUE_PAIRS into search data to get latest archived status for both online and offline const mergedSearchData = { ...searchResults.data, ...allReportNameValuePairs, From 81966cc0cfe056a638c3bb04aa17344212fb4234 Mon Sep 17 00:00:00 2001 From: Mukhriddin Shakhriyorov Date: Wed, 22 Oct 2025 00:04:14 +0500 Subject: [PATCH 6/6] add eslint-disable comments for deprecated translateLocal function --- src/libs/SearchUIUtils.ts | 53 ++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 980af30d0d12..77aea0cd2f44 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -68,6 +68,7 @@ import {getCardFeedsForDisplay} from './CardFeedUtils'; import {convertToDisplayString, getCurrencySymbol} from './CurrencyUtils'; import DateUtils from './DateUtils'; import interceptAnonymousUser from './interceptAnonymousUser'; +// eslint-disable-next-line @typescript-eslint/no-deprecated import {translateLocal} from './Localize'; import Navigation from './Navigation/Navigation'; import Parser from './Parser'; @@ -169,42 +170,59 @@ function isValidExpenseStatus(status: unknown): status is ValueOf> { return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.unreported'), value: CONST.SEARCH.STATUS.EXPENSE.UNREPORTED}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.draft'), value: CONST.SEARCH.STATUS.EXPENSE.DRAFTS}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.outstanding'), value: CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.approved'), value: CONST.SEARCH.STATUS.EXPENSE.APPROVED}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.settledExpensify'), value: CONST.SEARCH.STATUS.EXPENSE.PAID}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.done'), value: CONST.SEARCH.STATUS.EXPENSE.DONE}, ]; } function getExpenseReportedStatusOptions(): Array> { return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.draft'), value: CONST.SEARCH.STATUS.EXPENSE.DRAFTS}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.outstanding'), value: CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.approved'), value: CONST.SEARCH.STATUS.EXPENSE.APPROVED}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.settledExpensify'), value: CONST.SEARCH.STATUS.EXPENSE.PAID}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.done'), value: CONST.SEARCH.STATUS.EXPENSE.DONE}, ]; } function getInvoiceStatusOptions(): Array> { return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.outstanding'), value: CONST.SEARCH.STATUS.INVOICE.OUTSTANDING}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('iou.settledExpensify'), value: CONST.SEARCH.STATUS.INVOICE.PAID}, ]; } function getTripStatusOptions(): Array> { return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('search.filters.current'), value: CONST.SEARCH.STATUS.TRIP.CURRENT}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('search.filters.past'), value: CONST.SEARCH.STATUS.TRIP.PAST}, ]; } function getTaskStatusOptions(): Array> { return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.outstanding'), value: CONST.SEARCH.STATUS.TASK.OUTSTANDING}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('search.filters.completed'), value: CONST.SEARCH.STATUS.TASK.COMPLETED}, ]; } @@ -906,12 +924,13 @@ function getIOUReportName(data: OnyxTypes.SearchResults['data'], reportItem: Sea const payerName = payerPersonalDetails?.displayName ?? payerPersonalDetails?.login ?? getDisplayNameOrDefault(getPersonalDetailsForAccountID(reportItem.managerID)); const formattedAmount = convertToDisplayString(reportItem.total ?? 0, reportItem.currency ?? CONST.CURRENCY.USD); if (reportItem.action === CONST.SEARCH.ACTION_TYPES.PAID) { + // eslint-disable-next-line @typescript-eslint/no-deprecated return translateLocal('iou.payerPaidAmount', { payer: payerName, amount: formattedAmount, }); } - + // eslint-disable-next-line @typescript-eslint/no-deprecated return translateLocal('iou.payerOwesAmount', { payer: payerName, amount: formattedAmount, @@ -1369,7 +1388,6 @@ function getReportSections( currentAccountID: number | undefined, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], reportActions: Record = {}, - queryJSON?: SearchQueryJSON, ): TransactionGroupListItemType[] { const shouldShowMerchant = getShouldShowMerchant(data); @@ -1379,11 +1397,7 @@ function getReportSections( // Get violations - optimize by using a Map for faster lookups const allViolations = getViolations(data); - // Check if the current search is filtering by the Submit action - const isSubmitActionFilter = !!queryJSON?.flatFilters - ?.find((filterGroup) => filterGroup.key === CONST.SEARCH.SYNTAX_FILTER_KEYS.ACTION) - ?.filters?.some((filter) => filter.value === CONST.SEARCH.ACTION_FILTERS.SUBMIT); - + const queryJSON = getCurrentSearchQueryJSON(); const reportIDToTransactions: Record = {}; const {reportKeys, transactionKeys} = Object.keys(data).reduce( @@ -1423,15 +1437,6 @@ function getReportSections( } } - // Hiding reports from archived/deleted workspaces in Submit search - if (shouldShow && isSubmitActionFilter) { - const reportNVP = data[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportItem.reportID}`]; - const chatReportNVP = data[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportItem.chatReportID}`]; - if (isArchivedReport(reportNVP) || isArchivedReport(chatReportNVP)) { - shouldShow = false; - } - } - if (shouldShow) { const reportPendingAction = reportItem?.pendingAction ?? reportItem?.pendingFields?.preview; const shouldShowBlankTo = !reportItem || isOpenExpenseReport(reportItem); @@ -1645,7 +1650,7 @@ function getSections( // eslint-disable-next-line default-case switch (groupBy) { case CONST.SEARCH.GROUP_BY.REPORTS: - return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions, queryJSON); + return getReportSections(data, currentSearch, currentAccountID, formatPhoneNumber, reportActions); case CONST.SEARCH.GROUP_BY.FROM: return getMemberSections(data, queryJSON); case CONST.SEARCH.GROUP_BY.CARD: @@ -1857,6 +1862,7 @@ function getExpenseTypeTranslationKey(expenseType: ValueOf void, isMobileMenu?: boolean, closeMenu?: () => void) { return [ { + // eslint-disable-next-line @typescript-eslint/no-deprecated text: translateLocal('common.rename'), onSelected: () => { if (isMobileMenu && closeMenu) { @@ -1870,6 +1876,7 @@ function getOverflowMenu(itemName: string, hash: number, inputQuery: string, sho shouldCallAfterModalHide: true, }, { + // eslint-disable-next-line @typescript-eslint/no-deprecated text: translateLocal('common.delete'), onSelected: () => { if (isMobileMenu && closeMenu) { @@ -2145,14 +2152,20 @@ function getHasOptions(type: SearchDataTypes) { switch (type) { case CONST.SEARCH.DATA_TYPES.EXPENSE: return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.receipt'), value: CONST.SEARCH.HAS_VALUES.RECEIPT}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.attachment'), value: CONST.SEARCH.HAS_VALUES.ATTACHMENT}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.tag'), value: CONST.SEARCH.HAS_VALUES.TAG}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.category'), value: CONST.SEARCH.HAS_VALUES.CATEGORY}, ]; case CONST.SEARCH.DATA_TYPES.CHAT: return [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.link'), value: CONST.SEARCH.HAS_VALUES.LINK}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.attachment'), value: CONST.SEARCH.HAS_VALUES.ATTACHMENT}, ]; default: @@ -2162,10 +2175,15 @@ function getHasOptions(type: SearchDataTypes) { function getTypeOptions(policies: OnyxCollection, currentUserLogin?: string) { const typeOptions: Array> = [ + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.expense'), value: CONST.SEARCH.DATA_TYPES.EXPENSE}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.chat'), value: CONST.SEARCH.DATA_TYPES.CHAT}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.invoice'), value: CONST.SEARCH.DATA_TYPES.INVOICE}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.trip'), value: CONST.SEARCH.DATA_TYPES.TRIP}, + // eslint-disable-next-line @typescript-eslint/no-deprecated {text: translateLocal('common.task'), value: CONST.SEARCH.DATA_TYPES.TASK}, ]; const shouldHideInvoiceOption = !canSendInvoice(policies, currentUserLogin) && !hasInvoiceReports(); @@ -2175,6 +2193,7 @@ function getTypeOptions(policies: OnyxCollection, currentUserL } function getGroupByOptions() { + // eslint-disable-next-line @typescript-eslint/no-deprecated return Object.values(CONST.SEARCH.GROUP_BY).map>((value) => ({text: translateLocal(`search.filters.groupBy.${value}`), value})); }