From 7d79b60710e0d01b7b3ebc4399068c9acf4d73c4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 May 2025 16:22:03 +0200 Subject: [PATCH 01/10] Rename and add new one --- src/CONST.ts | 3 ++- src/components/MoneyReportHeader.tsx | 19 ++++++++++++++++--- src/hooks/useSelectedTransactionsActions.ts | 4 ++-- tests/unit/ReportSecondaryActionUtilsTest.ts | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 58714a58c377..a9f1920a26ef 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1200,7 +1200,8 @@ const CONST = { EXPORT_TO_ACCOUNTING: 'exportToAccounting', MARK_AS_EXPORTED: 'markAsExported', HOLD: 'hold', - DOWNLOAD: 'download', + DOWNLOAD_CSV: 'downloadCSV', + DOWNLOAD_PDF: 'downloadPDF', CHANGE_WORKSPACE: 'changeWorkspace', VIEW_DETAILS: 'viewDetails', DELETE: 'delete', diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 06ef767b5af2..32118df0cbd0 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -529,9 +529,22 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea navigateToDetailsPage(moneyRequestReport, Navigation.getReportRHPActiveRoute()); }, }, - [CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD]: { - value: CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD, - text: translate('common.download'), + [CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_CSV]: { + value: CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_CSV, + text: translate('common.downloadAsCSV'), + icon: Expensicons.Download, + onSelected: () => { + if (!moneyRequestReport) { + return; + } + exportReportToCSV({reportID: moneyRequestReport.reportID, transactionIDList: transactionIDs}, () => { + setDownloadErrorModalVisible(true); + }); + }, + }, + [CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_PDF]: { + value: CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_PDF, + text: translate('common.downloadAsPDF'), icon: Expensicons.Download, onSelected: () => { if (!moneyRequestReport) { diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index efddae7b387e..0c409f8642a2 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -122,8 +122,8 @@ function useSelectedTransactionsActions({ } options.push({ - value: CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD, - text: translate('common.download'), + value: CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_CSV, + text: translate('common.downloadAsCSV'), icon: Expensicons.Download, onSelected: () => { if (!report) { diff --git a/tests/unit/ReportSecondaryActionUtilsTest.ts b/tests/unit/ReportSecondaryActionUtilsTest.ts index b8769c119eda..51dc0eef4ea2 100644 --- a/tests/unit/ReportSecondaryActionUtilsTest.ts +++ b/tests/unit/ReportSecondaryActionUtilsTest.ts @@ -46,7 +46,7 @@ describe('getSecondaryAction', () => { const report = {} as unknown as Report; const policy = {} as unknown as Policy; - const result = [CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD, CONST.REPORT.SECONDARY_ACTIONS.VIEW_DETAILS]; + const result = [CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_CSV, CONST.REPORT.SECONDARY_ACTIONS.VIEW_DETAILS]; expect(getSecondaryReportActions(report, [], {}, policy)).toEqual(result); }); From e86e65f4e5b143be472f46de2bf11bc8d31d1711 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 14 May 2025 11:13:48 +0200 Subject: [PATCH 02/10] helper functions --- src/components/MoneyReportHeader.tsx | 8 +++++++- src/libs/ReportSecondaryActionUtils.ts | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 32118df0cbd0..fa5032320910 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -15,7 +15,7 @@ import useSelectedTransactionsActions from '@hooks/useSelectedTransactionsAction import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; -import {exportReportToCSV, exportToIntegration, markAsManuallyExported} from '@libs/actions/Report'; +import {exportReportToCSV, exportReportToPDF, exportToIntegration, markAsManuallyExported} from '@libs/actions/Report'; import {convertToDisplayString} from '@libs/CurrencyUtils'; import {getThreadReportIDsForTransactions} from '@libs/MoneyRequestReportUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -162,6 +162,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const [isUnapproveModalVisible, setIsUnapproveModalVisible] = useState(false); const [isReopenWarningModalVisible, setIsReopenWarningModalVisible] = useState(false); + const [isPDFModalVisible, setIsPDFModalVisible] = useState(false); const [exportModalStatus, setExportModalStatus] = useState(null); @@ -513,6 +514,11 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const {canUseRetractNewDot} = usePermissions(); + const beginPDFExport = useCallback(() => { + setIsPDFModalVisible(true); + exportReportToPDF({reportID: report.reportID}); + }, [report]); + const secondaryActions = useMemo(() => { if (!moneyRequestReport) { return []; diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts index 78bb2e4d455d..f79a29d0b1ad 100644 --- a/src/libs/ReportSecondaryActionUtils.ts +++ b/src/libs/ReportSecondaryActionUtils.ts @@ -413,7 +413,9 @@ function getSecondaryReportActions( options.push(CONST.REPORT.SECONDARY_ACTIONS.HOLD); } - options.push(CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD); + options.push(CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_CSV); + + options.push(CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_PDF); if (isChangeWorkspaceAction(report, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.CHANGE_WORKSPACE); From 422972669e72f68a18187265a0d9ba7380d12208 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 14 May 2025 15:00:22 +0200 Subject: [PATCH 03/10] move modal around --- src/components/MoneyReportHeader.tsx | 77 +++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index fa5032320910..3a1eb3da3094 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1,6 +1,6 @@ import {useRoute} from '@react-navigation/native'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; -import {View} from 'react-native'; +import {ActivityIndicator, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; @@ -15,7 +15,13 @@ import useSelectedTransactionsActions from '@hooks/useSelectedTransactionsAction import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; -import {exportReportToCSV, exportReportToPDF, exportToIntegration, markAsManuallyExported} from '@libs/actions/Report'; +import { + downloadReportPDF, + exportReportToCSV, + exportReportToPDF, + exportToIntegration, + markAsManuallyExported +} from '@libs/actions/Report'; import {convertToDisplayString} from '@libs/CurrencyUtils'; import {getThreadReportIDsForTransactions} from '@libs/MoneyRequestReportUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -103,6 +109,8 @@ import type {ActionHandledType} from './ProcessMoneyReportHoldMenu'; import ProcessMoneyReportHoldMenu from './ProcessMoneyReportHoldMenu'; import AnimatedSettlementButton from './SettlementButton/AnimatedSettlementButton'; import Text from './Text'; +import Header from "@components/Header"; +import Modal from "@components/Modal"; type MoneyReportHeaderProps = { /** The report currently being looked at */ @@ -136,6 +144,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const [nextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${moneyRequestReport?.reportID}`, {canBeMissing: true}); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`, {canBeMissing: true}); + const [reportPDFFilename] = useOnyx(`${ONYXKEYS.COLLECTION.NVP_EXPENSIFY_REPORT_PDF_FILENAME}${moneyRequestReport?.reportID}`, {canBeMissing: true}) ?? null; const [session] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: false}); const requestParentReportAction = useMemo(() => { if (!reportActions || !transactionThreadReport?.parentReportActionID) { @@ -190,6 +199,17 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea () => Object.fromEntries(Object.entries(allViolations ?? {}).filter(([key]) => transactionIDs.includes(key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '')))), [allViolations, transactionIDs], ); + + const messagePDF = useMemo(() => { + if (!reportPDFFilename) { + return translate('reportDetailsPage.waitForPDF'); + } + if (reportPDFFilename === CONST.REPORT_DETAILS_MENU_ITEM.ERROR) { + return translate('reportDetailsPage.errorPDF'); + } + return translate('reportDetailsPage.generatedPDF'); + }, [reportPDFFilename, translate]); + // Check if there is pending rter violation in all transactionViolations with given transactionIDs. const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDs, violations); // Check if user should see broken connection violation warning. @@ -514,10 +534,10 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const {canUseRetractNewDot} = usePermissions(); - const beginPDFExport = useCallback(() => { + const beginPDFExport = (reportID :string)=> { setIsPDFModalVisible(true); - exportReportToPDF({reportID: report.reportID}); - }, [report]); + exportReportToPDF({reportID}); + }; const secondaryActions = useMemo(() => { if (!moneyRequestReport) { @@ -556,9 +576,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea if (!moneyRequestReport) { return; } - exportReportToCSV({reportID: moneyRequestReport.reportID, transactionIDList: transactionIDs}, () => { - setDownloadErrorModalVisible(true); - }); + beginPDFExport(moneyRequestReport.reportID); }, }, [CONST.REPORT.SECONDARY_ACTIONS.SUBMIT]: { @@ -960,6 +978,49 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea isVisible={isDownloadErrorModalVisible} onClose={() => setIsDownloadErrorModalVisible(false)} /> + setIsPDFModalVisible(false)} + isVisible={isPDFModalVisible} + type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.CONFIRM} + innerContainerStyle={styles.pv0} + shouldUseNewModal + > + + + +
+ + + {messagePDF} + {!reportPDFFilename && ( + + )} + + + {!!reportPDFFilename && reportPDFFilename !== 'error' && ( +