diff --git a/Mobile-Expensify b/Mobile-Expensify index 608b11947017..e5fad37eb1c0 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit 608b11947017cfd06cf1eb848b7ddb9e3a08f98a +Subproject commit e5fad37eb1c05be78cea85b6e83a27c96b3df64b diff --git a/android/app/build.gradle b/android/app/build.gradle index ce0dc8ff8ade..e528dd22ad63 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -111,8 +111,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009039002 - versionName "9.3.90-2" + versionCode 1009039003 + versionName "9.3.90-3" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 574e701d0278..a366a84002ef 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -44,7 +44,7 @@ CFBundleVersion - 9.3.90.2 + 9.3.90.3 FullStory OrgId diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 188035d898d2..e92b1c20c264 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.3.90 CFBundleVersion - 9.3.90.2 + 9.3.90.3 NSExtension NSExtensionPointIdentifier diff --git a/ios/ShareViewController/Info.plist b/ios/ShareViewController/Info.plist index cdc9da4fbdba..a26a47a549ef 100644 --- a/ios/ShareViewController/Info.plist +++ b/ios/ShareViewController/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.3.90 CFBundleVersion - 9.3.90.2 + 9.3.90.3 NSExtension NSExtensionAttributes diff --git a/package-lock.json b/package-lock.json index ad722c98f8d1..d17dbf53c846 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.3.90-2", + "version": "9.3.90-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.3.90-2", + "version": "9.3.90-3", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index cf2b94cf592c..6238dfab7513 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.3.90-2", + "version": "9.3.90-3", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", diff --git a/src/hooks/useSearchBulkActions.ts b/src/hooks/useSearchBulkActions.ts index cee3278748e2..63d9bd56f439 100644 --- a/src/hooks/useSearchBulkActions.ts +++ b/src/hooks/useSearchBulkActions.ts @@ -10,7 +10,7 @@ import type {PaymentMethodType} from '@components/KYCWall/types'; import {ModalActions} from '@components/Modal/Global/ModalContext'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import {useSearchQueryContext, useSearchResultsContext, useSearchSelectionActions, useSearchSelectionContext} from '@components/Search/SearchContext'; -import type {BulkPaySelectionData, PaymentData, SearchColumnType, SearchQueryJSON} from '@components/Search/types'; +import type {BulkPaySelectionData, PaymentData, SearchQueryJSON} from '@components/Search/types'; import {unholdRequest} from '@libs/actions/IOU/Hold'; import {setupMergeTransactionDataAndNavigate} from '@libs/actions/MergeTransaction'; import {deleteAppReport, exportReportToPDF, markAsManuallyExported, moveIOUReportToPolicy, moveIOUReportToPolicyAndInviteSubmitter} from '@libs/actions/Report'; @@ -51,8 +51,8 @@ import { isIOUReport as isIOUReportUtil, isSelfDM, } from '@libs/ReportUtils'; -import {isDefaultExpensesQuery, serializeQueryJSONForBackend} from '@libs/SearchQueryUtils'; -import {getColumnsToShow, getSearchColumnTranslationKey, getValidGroupBy, navigateToSearchRHP, shouldShowDeleteOption} from '@libs/SearchUIUtils'; +import {serializeQueryJSONForBackend} from '@libs/SearchQueryUtils'; +import {navigateToSearchRHP, shouldShowDeleteOption} from '@libs/SearchUIUtils'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import { getOriginalTransactionWithSplitInfo, @@ -73,7 +73,6 @@ import {canIOUBePaid} from '@userActions/IOU/ReportWorkflow'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import {columnsSelector} from '@src/selectors/AdvancedSearchFiltersForm'; import type {BillingGraceEndPeriod, Policy, Report, ReportNameValuePairs, SearchResults, Transaction, TransactionViolations} from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import useAllPolicyExpenseChatReportActions from './useAllPolicyExpenseChatReportActions'; @@ -276,7 +275,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { const [integrationsExportTemplates] = useOnyx(ONYXKEYS.NVP_INTEGRATION_SERVER_EXPORT_TEMPLATES); const [csvExportLayouts] = useOnyx(ONYXKEYS.NVP_CSV_EXPORT_LAYOUTS); const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION); - const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {selector: columnsSelector}); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END); const [amountOwed] = useOnyx(ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED); @@ -538,116 +536,74 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { return result; }, [policies]); - const exportSearchData = searchResults?.data; - const exportSearchType = searchResults?.search.type ?? queryJSON?.type; - - const getCSVExportParameters = useCallback( - (isBasicExport: boolean) => { - const columnsToExport = getColumnsToShow({ - currentAccountID: accountID, - data: exportSearchData ?? {}, - visibleColumns, - type: exportSearchType, - groupBy: getValidGroupBy(queryJSON?.groupBy), - shouldUseStrictDefaultExpenseColumns: currentSearchKey === CONST.SEARCH.SEARCH_KEYS.EXPENSES && !!queryJSON && isDefaultExpensesQuery(queryJSON), - }); - - const exportColumnLabels: Partial> = {}; - for (const column of columnsToExport) { - exportColumnLabels[column] = translate(getSearchColumnTranslationKey(column)); - } - - const jsonQuery = queryJSON ? serializeQueryJSONForBackend({...queryJSON, columns: columnsToExport as SearchQueryJSON['columns']}) : (JSON.stringify(queryJSON) ?? ''); - - return { - jsonQuery, - isBasicExport, - exportColumnLabels: JSON.stringify(exportColumnLabels), - }; - }, - [accountID, currentSearchKey, exportSearchData, exportSearchType, queryJSON, translate, visibleColumns], - ); + const handleBasicExport = useCallback(async () => { + if (isOffline) { + setIsOfflineModalVisible(true); + return; + } - const handleCSVExport = useCallback( - async (isBasicExport: boolean) => { - if (isOffline) { - setIsOfflineModalVisible(true); - return; - } + if (status === null || status === undefined) { + return; + } - if (status === null || status === undefined) { + if (areAllMatchingItemsSelected) { + const result = await showConfirmModal({ + title: translate('search.exportSearchResults.title'), + prompt: translate('search.exportSearchResults.description'), + confirmText: translate('search.exportSearchResults.title'), + cancelText: translate('common.cancel'), + }); + if (result.action !== ModalActions.CONFIRM) { return; } - - if (areAllMatchingItemsSelected) { - const result = await showConfirmModal({ - title: translate('search.exportSearchResults.title'), - prompt: translate('search.exportSearchResults.description'), - confirmText: translate('search.exportSearchResults.title'), - cancelText: translate('common.cancel'), - }); - if (result.action !== ModalActions.CONFIRM) { - return; - } - if (selectedTransactionsKeys.length === 0 || status == null || !hash) { - return; - } - const reportIDList = selectedReports?.map((report) => report?.reportID).filter((reportID) => reportID !== undefined) ?? []; - const exportParameters = getCSVExportParameters(isBasicExport); - queueExportSearchItemsToCSV({ - query: status, - jsonQuery: exportParameters.jsonQuery, - reportIDList, - transactionIDList: selectedTransactionsKeys, - isBasicExport: exportParameters.isBasicExport, - exportColumnLabels: exportParameters.exportColumnLabels, - }); - selectAllMatchingItems(false); - clearSelectedTransactions(); + if (selectedTransactionsKeys.length === 0 || status == null || !hash) { return; } + const reportIDList = selectedReports?.map((report) => report?.reportID).filter((reportID) => reportID !== undefined) ?? []; + queueExportSearchItemsToCSV({ + query: status, + jsonQuery: queryJSON ? serializeQueryJSONForBackend(queryJSON) : JSON.stringify(queryJSON), + reportIDList, + transactionIDList: selectedTransactionsKeys, + }); + selectAllMatchingItems(false); + clearSelectedTransactions(); + return; + } - let didFail = false; - const exportParameters = getCSVExportParameters(isBasicExport); - await exportSearchItemsToCSV( - { - query: status, - jsonQuery: exportParameters.jsonQuery, - reportIDList: selectedReports.length > 0 ? selectedReportIDs : selectedTransactionReportIDs, - transactionIDList: selectedTransactionsKeys, - isBasicExport: exportParameters.isBasicExport, - exportColumnLabels: exportParameters.exportColumnLabels, - }, - () => { - didFail = true; - setEmptyReportsCount(0); - setIsDownloadErrorModalVisible(true); - }, - translate, - ); - if (!didFail) { - clearSelectedTransactions(undefined, true); - } - }, - [ - isOffline, - status, - areAllMatchingItemsSelected, - selectedReports, - selectedReportIDs, - selectedTransactionReportIDs, - selectedTransactionsKeys, + let didFail = false; + await exportSearchItemsToCSV( + { + query: status, + jsonQuery: queryJSON ? serializeQueryJSONForBackend(queryJSON) : JSON.stringify(queryJSON), + reportIDList: selectedReports.length > 0 ? selectedReportIDs : selectedTransactionReportIDs, + transactionIDList: selectedTransactionsKeys, + }, + () => { + didFail = true; + setEmptyReportsCount(0); + setIsDownloadErrorModalVisible(true); + }, translate, - clearSelectedTransactions, - showConfirmModal, - hash, - selectAllMatchingItems, - getCSVExportParameters, - ], - ); - - const handleBasicExport = useCallback(() => handleCSVExport(true), [handleCSVExport]); - const handleExportCurrentView = useCallback(() => handleCSVExport(false), [handleCSVExport]); + ); + if (!didFail) { + clearSelectedTransactions(undefined, true); + } + }, [ + isOffline, + status, + areAllMatchingItemsSelected, + queryJSON, + selectedReports, + selectedReportIDs, + selectedTransactionReportIDs, + selectedTransactionsKeys, + translate, + clearSelectedTransactions, + showConfirmModal, + hash, + selectAllMatchingItems, + ]); const handleApproveWithDEWCheck = useCallback(async () => { if (isOffline) { @@ -1087,7 +1043,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { const areFullReportsSelected = selectedTransactionReportIDs.length === selectedReportIDs.length && selectedTransactionReportIDs.every((id) => selectedReportIDs.includes(id)); const typeInvoice = queryJSON?.type === CONST.REPORT.TYPE.INVOICE; const typeExpense = queryJSON?.type === CONST.REPORT.TYPE.EXPENSE; - const isGroupedSearch = !!getValidGroupBy(queryJSON?.groupBy); const isAllOneTransactionReport = Object.values(selectedTransactions).every((transaction) => transaction.isFromOneTransactionReport); const includeReportLevelExport = ((isExpenseReportType || typeInvoice) && areFullReportsSelected) || (typeExpense && !isExpenseReportType && isAllOneTransactionReport); @@ -1216,18 +1171,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { shouldCallAfterModalHide: true, }); - if (!isGroupedSearch) { - exportOptions.push({ - text: translate('export.currentView'), - icon: expensifyIcons.Table, - onSelected: () => { - handleExportCurrentView(); - }, - shouldCloseModalOnSelect: true, - shouldCallAfterModalHide: true, - }); - } - if (!allSelectedAreDeleted) { for (const template of exportTemplates) { const isStandardTemplate = diff --git a/src/languages/de.ts b/src/languages/de.ts index 57b6dfb756eb..5c3b27792320 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -9366,7 +9366,6 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`, expenseLevelExport: 'Alle Daten – Ausgabenebene', exportInProgress: 'Export wird ausgeführt', conciergeWillSend: 'Concierge wird dir die Datei in Kürze senden.', - currentView: 'Aktuelle Ansicht exportieren', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/en.ts b/src/languages/en.ts index b1496794bd58..ca69f75ee4ee 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -9391,7 +9391,6 @@ const translations = { }, export: { basicExport: 'Basic export', - currentView: 'Export current view', reportLevelExport: 'All Data - report level', expenseLevelExport: 'All Data - expense level', exportInProgress: 'Export in progress', diff --git a/src/languages/es.ts b/src/languages/es.ts index f94ab5bdd7e5..d8b4c1701381 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -9519,7 +9519,6 @@ ${amount} para ${merchant} - ${date}`, }, export: { basicExport: 'Exportar básico', - currentView: 'Exportar vista actual', reportLevelExport: 'Todos los datos - a nivel de informe', expenseLevelExport: 'Todos los datos - a nivel de gasto', exportInProgress: 'Exportación en curso', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index ffe8fe432ab7..4ae6f16fb893 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -9397,7 +9397,6 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`, expenseLevelExport: 'Toutes les données - niveau dépense', exportInProgress: 'Export en cours', conciergeWillSend: 'Concierge vous enverra le fichier sous peu.', - currentView: 'Exporter la vue actuelle', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/it.ts b/src/languages/it.ts index 14a51b1a27a3..155f6ef5dc0e 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -9353,7 +9353,6 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`, expenseLevelExport: 'Tutti i dati - livello spesa', exportInProgress: 'Esportazione in corso', conciergeWillSend: 'Concierge ti invierà il file a breve.', - currentView: 'Esporta vista corrente', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 979a87f17b04..0cbba09f9af6 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -9235,7 +9235,6 @@ ${reportName} expenseLevelExport: 'すべてのデータ - 経費レベル', exportInProgress: 'エクスポート処理中', conciergeWillSend: 'Conciergeがまもなくファイルを送信します。', - currentView: '現在の表示をエクスポート', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 8540c1d87bdb..db6cd2ef5c28 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -9322,7 +9322,6 @@ Hier is een *proefbon* om je te laten zien hoe het werkt:`, expenseLevelExport: 'Alle gegevens - uitgaveniveau', exportInProgress: 'Export bezig', conciergeWillSend: 'Concierge stuurt je het bestand zo meteen.', - currentView: 'Huidige weergave exporteren', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index bdbaf80e8efa..ee57dd01e6b7 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -9303,7 +9303,6 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`, expenseLevelExport: 'Wszystkie dane – poziom wydatku', exportInProgress: 'Trwa eksport', conciergeWillSend: 'Concierge wkrótce wyśle Ci plik.', - currentView: 'Eksportuj bieżący widok', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index cdfe462ac026..fb26b4bc7ace 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -9312,7 +9312,6 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`, expenseLevelExport: 'Todos os dados - nível de despesa', exportInProgress: 'Exportação em andamento', conciergeWillSend: 'O Concierge enviará o arquivo para você em breve.', - currentView: 'Exportar visualização atual', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 95a993c47bf1..4612d15ab1a8 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -9064,7 +9064,6 @@ ${reportName} expenseLevelExport: '所有数据 - 报销级别', exportInProgress: '导出进行中', conciergeWillSend: 'Concierge 将很快把文件发送给你。', - currentView: '导出当前视图', }, exportDownload: { preparingTitle: 'Preparing download...', diff --git a/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts b/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts index 0d321bf01e48..35e06a4cb713 100644 --- a/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts +++ b/src/libs/API/parameters/ExportSearchItemsToCSVParams.ts @@ -5,8 +5,6 @@ type ExportSearchItemsToCSVParams = { jsonQuery: SearchQueryString; reportIDList: string[]; transactionIDList: string[]; - isBasicExport: boolean; - exportColumnLabels: string; }; export default ExportSearchItemsToCSVParams; diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 7a8406ad0908..1b9154a41013 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -4167,8 +4167,6 @@ function getSearchColumnTranslationKey(column: SearchColumnType): TranslationPat return 'iou.totalPerAttendee'; case CONST.SEARCH.TABLE_COLUMNS.RECEIPT: return 'common.receipt'; - case CONST.SEARCH.TABLE_COLUMNS.TYPE: - return 'common.type'; case CONST.SEARCH.TABLE_COLUMNS.TAG: return 'common.tag'; case CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT: @@ -4179,12 +4177,6 @@ function getSearchColumnTranslationKey(column: SearchColumnType): TranslationPat return 'common.billable'; case CONST.SEARCH.TABLE_COLUMNS.ACTION: return 'common.action'; - case CONST.SEARCH.TABLE_COLUMNS.IN: - return 'common.sharedIn'; - case CONST.SEARCH.TABLE_COLUMNS.ASSIGNEE: - return 'common.assignee'; - case CONST.SEARCH.TABLE_COLUMNS.COMMENTS: - return 'common.comments'; case CONST.SEARCH.TABLE_COLUMNS.TITLE: return 'common.title'; case CONST.SEARCH.TABLE_COLUMNS.STATUS: diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 91dd969888cd..8ff5aaa72b75 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -1142,11 +1142,9 @@ function rejectMoneyRequestsOnSearch( return urlToNavigateBack; } -function exportSearchItemsToCSV( - {query, jsonQuery, reportIDList, transactionIDList, isBasicExport, exportColumnLabels}: ExportSearchItemsToCSVParams, - onDownloadFailed: () => void, - translate: LocalizedTranslate, -) { +type Params = Record; + +function exportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList}: ExportSearchItemsToCSVParams, onDownloadFailed: () => void, translate: LocalizedTranslate) { const reportIDSet = new Set(); const transactionIDSet = new Set(transactionIDList); for (const reportID of reportIDList) { @@ -1177,9 +1175,7 @@ function exportSearchItemsToCSV( jsonQuery, reportIDList: Array.from(reportIDSet), transactionIDList, - isBasicExport, - exportColumnLabels, - }); + }) as Params; const formData = new FormData(); for (const [key, value] of Object.entries(finalParameters)) { @@ -1193,14 +1189,12 @@ function exportSearchItemsToCSV( return fileDownload(translate, getCommandURL({command: WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } -function queueExportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList, isBasicExport, exportColumnLabels}: ExportSearchItemsToCSVParams) { - const finalParameters = enhanceParameters(WRITE_COMMANDS.QUEUE_EXPORT_SEARCH_ITEMS_TO_CSV, { +function queueExportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList}: ExportSearchItemsToCSVParams) { + const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV, { query, jsonQuery, reportIDList, transactionIDList, - isBasicExport, - exportColumnLabels, }) as ExportSearchItemsToCSVParams; API.write(WRITE_COMMANDS.QUEUE_EXPORT_SEARCH_ITEMS_TO_CSV, finalParameters);