Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Pending/Scanning pattern] Update the UI for Pending and Scanning in Single Transaction ReportPreview / MoneyRequestAction #40020

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
395468d
receipt scan ui change wip
BrtqKr Apr 9, 2024
2e1f4ce
scanning receipt wip
BrtqKr Apr 9, 2024
9ee70da
finalize scanning receipt
BrtqKr Apr 10, 2024
8f22291
finalize pending transaction, cleanup wip
BrtqKr Apr 10, 2024
efe88ce
cleanup
BrtqKr Apr 10, 2024
9a664e5
cleanup
BrtqKr Apr 10, 2024
d315efb
cleanup
BrtqKr Apr 10, 2024
4e08e07
cleanup translations
BrtqKr Apr 10, 2024
648e333
fix preview
BrtqKr Apr 10, 2024
f2bcf10
wip
BrtqKr Apr 11, 2024
c3285b8
cleanup
BrtqKr Apr 11, 2024
69be68e
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 11, 2024
e4f927a
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 12, 2024
7b62f36
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 15, 2024
fea7ada
fix typography
BrtqKr Apr 15, 2024
dd4ae04
style fixes
BrtqKr Apr 15, 2024
d547465
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 16, 2024
348490a
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 17, 2024
77ef74a
cleanup
BrtqKr Apr 22, 2024
dea9aaf
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 22, 2024
6c40f88
cleanup
BrtqKr Apr 22, 2024
0290090
cleanup
BrtqKr Apr 22, 2024
003d291
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 25, 2024
0282069
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 29, 2024
c65e106
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr Apr 30, 2024
254f274
remove hover pattern for scans, remove only visible to you
BrtqKr May 7, 2024
47c1989
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr May 7, 2024
e94782e
revert only visible to you for non-scanning
BrtqKr May 8, 2024
f7fe9a3
change logic for retrieving receipt transactions
BrtqKr May 9, 2024
7b44ab5
add pending action condition for credit card transactions
BrtqKr May 9, 2024
9229cc4
Merge remote-tracking branch 'origin/main' into brtqkr/pending-and-sc…
BrtqKr May 9, 2024
56022e2
fix message type
BrtqKr May 9, 2024
b586db8
adjust translations
BrtqKr May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions assets/images/credit-card-hourglass.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion assets/images/receipt-scan.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import Concierge from '@assets/images/concierge.svg';
import Connect from '@assets/images/connect.svg';
import ConnectionComplete from '@assets/images/connection-complete.svg';
import Copy from '@assets/images/copy.svg';
import CreditCardHourglass from '@assets/images/credit-card-hourglass.svg';
import CreditCard from '@assets/images/creditcard.svg';
import DocumentPlus from '@assets/images/document-plus.svg';
import DocumentSlash from '@assets/images/document-slash.svg';
Expand Down Expand Up @@ -207,6 +208,7 @@ export {
ConnectionComplete,
Copy,
CreditCard,
CreditCardHourglass,
DeletedRoomAvatar,
Document,
DocumentSlash,
Expand Down
28 changes: 23 additions & 5 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as HeaderUtils from '@libs/HeaderUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import variables from '@styles/variables';
import * as IOU from '@userActions/IOU';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand All @@ -18,6 +20,7 @@ import type {Policy, Report, ReportAction, ReportActions, Session, Transaction}
import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage';
import ConfirmModal from './ConfirmModal';
import HeaderWithBackButton from './HeaderWithBackButton';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar';
import ProcessMoneyRequestHoldMenu from './ProcessMoneyRequestHoldMenu';
Expand Down Expand Up @@ -69,6 +72,7 @@ function MoneyRequestHeader({
onBackButtonPress,
}: MoneyRequestHeaderProps) {
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
const [shouldShowHoldMenu, setShouldShowHoldMenu] = useState(false);
Expand Down Expand Up @@ -197,16 +201,30 @@ function MoneyRequestHeader({
/>
{isPending && (
<MoneyRequestHeaderStatusBar
title={translate('iou.pending')}
description={translate('iou.transactionPendingText')}
title={
<Icon
src={Expensicons.CreditCardHourglass}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
fill={theme.icon}
/>
}
description={translate('iou.transactionPendingDescription')}
shouldShowBorderBottom={!isScanning}
/>
)}
{isScanning && (
<MoneyRequestHeaderStatusBar
title={translate('iou.receiptStatusTitle')}
description={translate('iou.receiptStatusText')}
shouldShowBorderBottom={!isOnHold}
title={
<Icon
src={Expensicons.ReceiptScan}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
fill={theme.icon}
/>
}
description={translate('iou.receiptScanInProgressDescription')}
shouldShowBorderBottom
/>
)}
{isOnHold && (
Expand Down
21 changes: 13 additions & 8 deletions src/components/MoneyRequestHeaderStatusBar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {ReactNode} from 'react';
import React from 'react';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -6,7 +7,7 @@ import Text from './Text';

type MoneyRequestHeaderStatusBarProps = {
/** Title displayed in badge */
title: string;
title: string | ReactNode;

/** Banner Description */
description: string;
Expand Down Expand Up @@ -35,13 +36,17 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom
styles.headerStatusBarContainer,
]}
>
<View style={[styles.mr3]}>
<Badge
text={title}
badgeStyles={styles.ml0}
error={danger}
/>
</View>
{typeof title === 'string' ? (
grgia marked this conversation as resolved.
Show resolved Hide resolved
<View style={[styles.mr3]}>
<Badge
text={title}
badgeStyles={styles.ml0}
error={danger}
/>
</View>
) : (
<View style={styles.mr2}>{title}</View>
)}
<View style={[styles.flexShrink1]}>
<Text style={[styles.textLabelSupporting]}>{description}</Text>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {GestureResponderEvent} from 'react-native';
import ConfirmedRoute from '@components/ConfirmedRoute';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import {ReceiptScan} from '@components/Icon/Expensicons';
import MoneyRequestSkeletonView from '@components/MoneyRequestSkeletonView';
import MultipleAvatars from '@components/MultipleAvatars';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
Expand All @@ -28,6 +29,7 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import ViolationsUtils from '@libs/Violations/ViolationsUtils';
import variables from '@styles/variables';
import * as PaymentMethods from '@userActions/PaymentMethods';
import * as Report from '@userActions/Report';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -82,6 +84,7 @@ function MoneyRequestPreviewContent({
const requestMerchant = truncate(merchant, {length: CONST.REQUEST_PREVIEW.MAX_LENGTH});
const hasReceipt = TransactionUtils.hasReceipt(transaction);
const isScanning = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction);
const isPending = TransactionUtils.isPending(transaction);
const isOnHold = TransactionUtils.isOnHold(transaction);
const isSettlementOrApprovalPartial = Boolean(iouReport?.pendingFields?.partial);
const isPartialHold = isSettlementOrApprovalPartial && isOnHold;
Expand Down Expand Up @@ -142,14 +145,6 @@ function MoneyRequestPreviewContent({
message = translate('iou.split');
}

if (isCardTransaction) {
message = translate('iou.card');
if (TransactionUtils.isPending(transaction)) {
message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`;
return message;
}
}

if (isSettled && !iouReport?.isCancelledIOU && !isPartialHold) {
message += ` ${CONST.DOT_SEPARATOR} ${getSettledMessage()}`;
return message;
Expand Down Expand Up @@ -181,8 +176,6 @@ function MoneyRequestPreviewContent({
message += ` • ${translate('violations.reviewRequired')}`;
} else if (ReportUtils.isPaidGroupPolicyExpenseReport(iouReport) && ReportUtils.isReportApproved(iouReport) && !ReportUtils.isSettled(iouReport?.reportID) && !isPartialHold) {
message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.approved')}`;
} else if (iouReport?.isWaitingOnBankAccount) {
message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`;
} else if (iouReport?.isCancelledIOU) {
message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.canceled')}`;
} else if (!(isSettled && !isSettlementOrApprovalPartial) && isOnHold) {
Expand Down Expand Up @@ -319,6 +312,28 @@ function MoneyRequestPreviewContent({
</Text>
)}
</View>
{isScanning && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mt2]}>
<Icon
src={ReceiptScan}
height={variables.iconSizeExtraSmall}
width={variables.iconSizeExtraSmall}
fill={theme.textSupporting}
/>
<Text style={[styles.textMicroSupporting, styles.ml1, styles.amountSplitPadding]}>{translate('iou.receiptScanInProgress')}</Text>
</View>
)}
{isPending && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mt2]}>
<Icon
src={Expensicons.CreditCardHourglass}
height={variables.iconSizeExtraSmall}
width={variables.iconSizeExtraSmall}
fill={theme.textSupporting}
/>
<Text style={[styles.textMicroSupporting, styles.ml1, styles.amountSplitPadding]}>{translate('iou.transactionPending')}</Text>
</View>
)}
</View>
</View>
</View>
Expand Down
7 changes: 1 addition & 6 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,6 @@ function MoneyRequestView({
if (formattedOriginalAmount) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.original')} ${formattedOriginalAmount}`;
}
if (TransactionUtils.isPending(transaction)) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`;
}
if (isCancelled) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.canceled')}`;
}
Expand All @@ -236,9 +233,7 @@ function MoneyRequestView({
} else if (isCancelled) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.canceled')}`;
} else if (isSettled) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.settledExpensify')}`;
} else if (report.isWaitingOnBankAccount) {
amountDescription += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`;
amountDescription += ` • ${translate('iou.settledExpensify')}`;
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import * as ReportActionUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import variables from '@styles/variables';
import * as IOU from '@userActions/IOU';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
Expand Down Expand Up @@ -134,6 +135,7 @@ function ReportPreview({

const hasReceipts = transactionsWithReceipts.length > 0;
const isScanning = hasReceipts && areAllRequestsBeingSmartScanned;

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const hasErrors = hasMissingSmartscanFields || (canUseViolations && ReportUtils.hasViolations(iouReportID, transactionViolations)) || ReportUtils.hasActionsWithErrors(iouReportID);
const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3);
Expand Down Expand Up @@ -224,6 +226,8 @@ function ReportPreview({
const shouldShowSingleRequestMerchantOrDescription =
numberOfRequests === 1 && (!!formattedMerchant || !!formattedDescription) && !(hasOnlyTransactionsWithPendingRoutes && !totalDisplaySpend);
const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchantOrDescription || numberOfRequests > 1);
const shouldShowScanningSubtitle = numberOfScanningReceipts === 1 && numberOfRequests === 1;
const shouldShowPendingSubtitle = numberOfPendingRequests === 1 && numberOfRequests === 1;

const {supportText} = useMemo(() => {
if (formattedMerchant) {
Expand Down Expand Up @@ -310,6 +314,28 @@ function ReportPreview({
</View>
</View>
)}
{shouldShowScanningSubtitle && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mt2]}>
<Icon
src={Expensicons.ReceiptScan}
height={variables.iconSizeExtraSmall}
width={variables.iconSizeExtraSmall}
fill={theme.icon}
/>
<Text style={[styles.textMicroSupporting, styles.ml1, styles.amountSplitPadding]}>{translate('iou.receiptScanInProgress')}</Text>
</View>
)}
{shouldShowPendingSubtitle && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mt2]}>
<Icon
src={Expensicons.CreditCardHourglass}
height={variables.iconSizeExtraSmall}
width={variables.iconSizeExtraSmall}
fill={theme.icon}
/>
<Text style={[styles.textMicroSupporting, styles.ml1, styles.amountSplitPadding]}>{translate('iou.transactionPending')}</Text>
</View>
)}
</View>
</View>
{shouldShowSettlementButton && (
Expand Down
7 changes: 5 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,17 +645,19 @@ export default {
canceled: 'Canceled',
posted: 'Posted',
deleteReceipt: 'Delete receipt',
receiptScanning: 'Receipt scanning...',
receiptScanInProgress: 'Receipt scan in progress.',
receiptScanInProgressDescription: 'Receipt scan in progress. Check back later or enter the details now.',
receiptIssuesFound: (count: number) => `${count === 1 ? 'Issue' : 'Issues'} found`,
fieldPending: 'Pending...',
defaultRate: 'Default rate',
receiptScanning: 'Scan in progress…',
receiptMissingDetails: 'Receipt missing details',
missingAmount: 'Missing amount',
missingMerchant: 'Missing merchant',
receiptStatusTitle: 'Scanning…',
receiptStatusText: "Only you can see this receipt when it's scanning. Check back later or enter the details now.",
receiptScanningFailed: 'Receipt scanning failed. Enter the details manually.',
transactionPendingText: 'It takes a few days from the date the card was used for the transaction to post.',
transactionPendingDescription: 'Transaction pending. It can take a few days from the date the card was used for the transaction to post.',
expenseCount: ({count, scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) =>
`${count} ${Str.pluralize('expense', 'expenses', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}${
pendingReceipts > 0 ? `, ${pendingReceipts} pending` : ''
Expand Down Expand Up @@ -757,6 +759,7 @@ export default {
set: 'set',
changed: 'changed',
removed: 'removed',
transactionPending: 'Transaction pending.',
chooseARate: ({unit}: ReimbursementRateParams) => `Select a workspace reimbursement rate per ${unit}`,
},
notificationPreferencesPage: {
Expand Down
Loading
Loading