Skip to content

Commit

Permalink
Merge pull request #35497 from tienifr/fix/33549
Browse files Browse the repository at this point in the history
fix: Closing receipt view using device navigation redirects user to expense report
  • Loading branch information
rlinoz authored Mar 8, 2024
2 parents 63dee4e + c2006ab commit 61b4b04
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 35 deletions.
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ const ROUTES = {
getRoute: (contentType: string, backTo?: string) => getUrlWithBackToParam(`referral/${contentType}`, backTo),
},
PROCESS_MONEY_REQUEST_HOLD: 'hold-request-educational',
TRANSACTION_RECEIPT: {
route: 'r/:reportID/transaction/:transactionID/receipt',
getRoute: (reportID: string, transactionID: string) => `r/${reportID}/transaction/${transactionID}/receipt` as const,
},
} as const;

/**
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ const SCREENS = {
GET_ASSISTANCE: 'GetAssistance',
REFERRAL_DETAILS: 'Referral_Details',
KEYBOARD_SHORTCUTS: 'KeyboardShortcuts',
TRANSACTION_RECEIPT: 'TransactionReceipt',
} as const;

type Screen = DeepValueOf<typeof SCREENS>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/AttachmentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ function AttachmentModal({
const deleteAndCloseModal = useCallback(() => {
IOU.detachReceipt(transaction?.transactionID ?? '');
setIsDeleteReceiptConfirmModalVisible(false);
Navigation.dismissModal(report?.reportID);
Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? ''));
}, [transaction, report]);

const isValidFile = useCallback((fileObject: FileObject) => {
Expand Down
1 change: 0 additions & 1 deletion src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ function MoneyRequestView({
filename={receiptURIs?.filename}
transaction={transaction}
enablePreviewModal
canEditReceipt={canEditReceipt}
/>
)}
</View>
Expand Down
43 changes: 10 additions & 33 deletions src/components/ReportActionItem/ReportActionItemImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type {ReactElement} from 'react';
import type {ImageSourcePropType, ViewStyle} from 'react-native';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import AttachmentModal from '@components/AttachmentModal';
import EReceiptThumbnail from '@components/EReceiptThumbnail';
import * as Expensicons from '@components/Icon/Expensicons';
import Image from '@components/Image';
Expand All @@ -14,10 +13,12 @@ import {ShowContextMenuContext} from '@components/ShowContextMenuContext';
import ThumbnailImage from '@components/ThumbnailImage';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import * as TransactionUtils from '@libs/TransactionUtils';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {Transaction} from '@src/types/onyx';

type ReportActionItemImageProps = {
Expand All @@ -36,9 +37,6 @@ type ReportActionItemImageProps = {
/** whether thumbnail is refer the local file or not */
isLocalFile?: boolean;

/** whether the receipt can be replaced */
canEditReceipt?: boolean;

/** Filename of attachment */
filename?: string;

Expand All @@ -52,16 +50,7 @@ type ReportActionItemImageProps = {
* and optional preview modal as well.
*/

function ReportActionItemImage({
thumbnail,
image,
enablePreviewModal = false,
transaction,
canEditReceipt = false,
isLocalFile = false,
filename,
isSingleImage = true,
}: ReportActionItemImageProps) {
function ReportActionItemImage({thumbnail, image, enablePreviewModal = false, transaction, isLocalFile = false, filename, isSingleImage = true}: ReportActionItemImageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const attachmentModalSource = tryResolveUrlFromApiRoot(image ?? '');
Expand Down Expand Up @@ -118,26 +107,14 @@ function ReportActionItemImage({
return (
<ShowContextMenuContext.Consumer>
{({report}) => (
<AttachmentModal
source={attachmentModalSource}
isAuthTokenRequired={!isLocalFile}
report={report}
isReceiptAttachment
canEditReceipt={canEditReceipt}
allowDownload={!isEReceipt}
originalFileName={filename}
<PressableWithoutFocus
style={[styles.w100, styles.h100, styles.noOutline as ViewStyle]}
onPress={() => Navigation.navigate(ROUTES.TRANSACTION_RECEIPT.getRoute(report?.reportID ?? '', transaction?.transactionID ?? ''))}
accessibilityLabel={translate('accessibilityHints.viewAttachment')}
accessibilityRole={CONST.ROLE.BUTTON}
>
{({show}) => (
<PressableWithoutFocus
style={[styles.w100, styles.h100, styles.noOutline as ViewStyle]}
onPress={show}
accessibilityRole={CONST.ROLE.BUTTON}
accessibilityLabel={translate('accessibilityHints.viewAttachment')}
>
{receiptImageComponent}
</PressableWithoutFocus>
)}
</AttachmentModal>
{receiptImageComponent}
</PressableWithoutFocus>
)}
</ShowContextMenuContext.Consumer>
);
Expand Down
11 changes: 11 additions & 0 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const loadConciergePage = () => require('../../../pages/ConciergePage').default
const loadProfileAvatar = () => require('../../../pages/settings/Profile/ProfileAvatar').default as React.ComponentType;
const loadWorkspaceAvatar = () => require('../../../pages/workspace/WorkspaceAvatar').default as React.ComponentType;
const loadReportAvatar = () => require('../../../pages/ReportAvatar').default as React.ComponentType;
const loadReceiptView = () => require('../../../pages/TransactionReceiptPage').default as React.ComponentType;
const loadWorkspaceJoinUser = () => require('@pages/workspace/WorkspaceJoinUserPage').default as React.ComponentType;

let timezone: Timezone | null;
Expand Down Expand Up @@ -363,8 +364,18 @@ function AuthScreens({session, lastOpenedPublicRoomID, isUsingMemoryOnlyKeys = f
headerShown: false,
presentation: 'transparentModal',
}}
listeners={modalScreenListeners}
getComponent={loadWorkspaceJoinUser}
/>
<RootStack.Screen
name={SCREENS.TRANSACTION_RECEIPT}
options={{
headerShown: false,
presentation: 'transparentModal',
}}
getComponent={loadReceiptView}
listeners={modalScreenListeners}
/>
</RootStack.Navigator>
</View>
);
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.PROFILE_AVATAR]: ROUTES.PROFILE_AVATAR.route,
[SCREENS.WORKSPACE_AVATAR]: ROUTES.WORKSPACE_AVATAR.route,
[SCREENS.REPORT_AVATAR]: ROUTES.REPORT_AVATAR.route,
[SCREENS.TRANSACTION_RECEIPT]: ROUTES.TRANSACTION_RECEIPT.route,
[SCREENS.WORKSPACE_JOIN_USER]: ROUTES.WORKSPACE_JOIN_USER.route,

// Sidebar
Expand Down
4 changes: 4 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ type AuthScreensParamList = SharedScreensParamList & {
[NAVIGATORS.RIGHT_MODAL_NAVIGATOR]: NavigatorScreenParams<RightModalNavigatorParamList>;
[NAVIGATORS.FULL_SCREEN_NAVIGATOR]: NavigatorScreenParams<FullScreenNavigatorParamList>;
[SCREENS.DESKTOP_SIGN_IN_REDIRECT]: undefined;
[SCREENS.TRANSACTION_RECEIPT]: {
reportID: string;
transactionID: string;
};
};

type RootStackParamList = PublicScreensParamList & AuthScreensParamList;
Expand Down
79 changes: 79 additions & 0 deletions src/pages/TransactionReceiptPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useEffect} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import AttachmentModal from '@components/AttachmentModal';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
import * as ReceiptUtils from '@libs/ReceiptUtils';
import * as ReportActionUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import * as ReportActions from '@userActions/Report';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {Report, ReportMetadata, Transaction} from '@src/types/onyx';

type TransactionReceiptOnyxProps = {
report: OnyxEntry<Report>;
transaction: OnyxEntry<Transaction>;
reportMetadata: OnyxEntry<ReportMetadata>;
};

type TransactionReceiptProps = TransactionReceiptOnyxProps & StackScreenProps<AuthScreensParamList, typeof SCREENS.TRANSACTION_RECEIPT>;

function TransactionReceipt({transaction, report, reportMetadata = {isLoadingInitialReportActions: true}, route}: TransactionReceiptProps) {
const receiptURIs = ReceiptUtils.getThumbnailAndImageURIs(transaction);

const imageSource = tryResolveUrlFromApiRoot(receiptURIs.image);

const isLocalFile = receiptURIs.isLocalFile;

const parentReportAction = ReportActionUtils.getReportAction(report?.parentReportID ?? '', report?.parentReportActionID ?? '');
const canEditReceipt = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT);
const isEReceipt = transaction && TransactionUtils.hasEReceipt(transaction);

useEffect(() => {
if (report && transaction) {
return;
}
ReportActions.openReport(route.params.reportID);
// I'm disabling the warning, as it expects to use exhaustive deps, even though we want this useEffect to run only on the first render.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<AttachmentModal
source={imageSource}
isAuthTokenRequired={!isLocalFile}
report={report}
isReceiptAttachment
canEditReceipt={canEditReceipt}
allowDownload={!isEReceipt}
originalFileName={receiptURIs?.filename}
defaultOpen
onModalClose={() => {
Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? ''));
}}
isLoading={!transaction && reportMetadata?.isLoadingInitialReportActions}
shouldShowNotFoundPage={(report?.parentReportID ?? '') !== transaction?.reportID}
/>
);
}

TransactionReceipt.displayName = 'TransactionReceipt';

export default withOnyx<TransactionReceiptProps, TransactionReceiptOnyxProps>({
report: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? '0'}`,
},
transaction: {
key: ({route}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${route.params.transactionID ?? '0'}`,
},
reportMetadata: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_METADATA}${route.params.reportID ?? '0'}`,
},
})(TransactionReceipt);

0 comments on commit 61b4b04

Please sign in to comment.