Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ function ReportPreviewHeader() {
[translate, numberOfRequests],
);

// A cancelled payment is a report level event and it isn't surfaced by the status badge, so we show it next to the expense count.
const supportingText = iouReport?.isCancelledIOU ? `${translate('iou.canceled')} ${CONST.DOT_SEPARATOR} ${expenseCount}` : expenseCount;

const reportStateNum = iouReport?.stateNum ?? action?.childStateNum;
const reportStatusNum = iouReport?.statusNum ?? action?.childStatusNum;

Expand All @@ -84,6 +81,11 @@ function ReportPreviewHeader() {

const shouldShowReportStatus = !!reportStatus && !!expenseCount;

// The badge can't express a cancelled payment, so it sits next to the expense count - unless the badge already reads "Approved",
// which is the state cancelling returns an approving workspace to.
const isApprovedReport = reportStateNum === CONST.REPORT.STATE_NUM.APPROVED && reportStatusNum === CONST.REPORT.STATUS_NUM.APPROVED;
const supportingText = iouReport?.isCancelledIOU && !isApprovedReport ? `${translate('iou.canceled')} ${CONST.DOT_SEPARATOR} ${expenseCount}` : expenseCount;

const reportStatusColorStyle = useMemo(() => getReportStatusColorStyle(theme, reportStateNum, reportStatusNum), [reportStateNum, reportStatusNum, theme]);

const reportStatusTooltip = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import MultiAccountAvatar from '@components/Avatar/connected/MultiAccountAvatar'
import Button from '@components/ButtonComposed';
import Icon from '@components/Icon';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {ReportPreviewDataContext} from '@components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContext';
import ReportActionItemImages from '@components/ReportActionItem/ReportActionItemImages';
import UserInfoCellsWithArrow from '@components/Search/SearchList/ListItem/UserInfoCellsWithArrow';
import Text from '@components/Text';
Expand Down Expand Up @@ -46,7 +45,7 @@ import {cardByIdSelector} from '@src/selectors/Card';
import {getStableReportSelector} from '@src/selectors/Report';

import truncate from 'lodash/truncate';
import React, {useContext, useMemo} from 'react';
import React, {useMemo} from 'react';
import {View} from 'react-native';
import Animated from 'react-native-reanimated';

Expand Down Expand Up @@ -135,11 +134,6 @@ function TransactionPreviewContent({

const {shouldShowRBR, shouldShowMerchant, shouldShowSplitShare, shouldShowCategory, shouldShowSkeleton, shouldShowDescription} = conditionals;

// Raw useContext (not the useReportPreviewData slice hook, which throws when absent): a missing provider means this is a
// standalone preview with no report header to carry the status, so the preview has to report a cancelled payment itself.
const isInsideReportPreview = !!useContext(ReportPreviewDataContext);
const shouldShowCanceledStatus = !isInsideReportPreview;

const isIOUActionType = isMoneyRequestAction(action);
const canEdit = isIOUActionType && canEditMoneyRequest(action, transaction, isChatReportArchived, report, policy, reportActions);
const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(report?.policyID)}`;
Expand Down Expand Up @@ -169,13 +163,12 @@ function TransactionPreviewContent({
dateFnsLocale,
...transactionPreviewCommonArguments,
shouldShowRBR,
shouldShowCanceledStatus,
violationMessage,
reportActions,
originalTransaction,
convertToDisplayString,
}),
[transactionPreviewCommonArguments, shouldShowRBR, shouldShowCanceledStatus, violationMessage, reportActions, originalTransaction, convertToDisplayString, dateFnsLocale],
[transactionPreviewCommonArguments, shouldShowRBR, violationMessage, reportActions, originalTransaction, convertToDisplayString, dateFnsLocale],
);
const getTranslatedText = (item: TranslationPathOrText) => (item.translationPath ? translate(item.translationPath) : (item.text ?? ''));

Expand Down
16 changes: 4 additions & 12 deletions src/libs/TransactionPreviewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ function getTransactionPreviewTextAndTranslationPaths({
transactionDetails,
isBillSplit,
shouldShowRBR,
shouldShowCanceledStatus,
violationMessage,
reportActions,
originalTransaction,
Expand All @@ -225,8 +224,6 @@ function getTransactionPreviewTextAndTranslationPaths({
transactionDetails: Partial<TransactionDetails>;
isBillSplit: boolean;
shouldShowRBR: boolean;
/** Whether a cancelled payment has to be reported on this line, because the enclosing surface doesn't show it anywhere else */
shouldShowCanceledStatus: boolean;
violationMessage?: string;
reportActions?: OnyxTypes.ReportActions;
originalTransaction?: OnyxEntry<OnyxTypes.Transaction>;
Expand Down Expand Up @@ -329,18 +326,15 @@ function getTransactionPreviewTextAndTranslationPaths({
previewDateText = {text: date};
}

// Paid, Approved, Review required and the hold message are intentionally omitted here because the report status badge and the
// RBR row already show them, so repeating them on this line is noise. Canceled is the exception: it can't be derived from
// stateNum/statusNum, so surfaces without their own report status badge have to report it here.
// Paid, Approved, Review required, Canceled and the hold message are omitted here: the status badge, the preview header and the
// RBR row already show them.
const previewStatusText: TranslationPathOrText[] = [];

if (isPending(transaction)) {
previewStatusText.push({translationPath: 'iou.pending'});
}

if (shouldShowCanceledStatus && iouReport?.isCancelledIOU) {
previewStatusText.push({translationPath: 'iou.canceled'});
} else if (hasPendingRTERViolation(violations)) {
if (hasPendingRTERViolation(violations)) {
previewStatusText.push({translationPath: 'iou.pendingMatch'});
}
Comment thread
Krishna2323 marked this conversation as resolved.

Expand Down Expand Up @@ -394,7 +388,7 @@ function createTransactionPreviewConditionals({
currentUserAccountID: number;
reportActions?: OnyxTypes.ReportActions;
}) {
const {amount: requestAmount, comment: requestComment, merchant, tag, category} = transactionDetails;
const {amount: requestAmount, comment: requestComment, merchant, category} = transactionDetails;

const requestMerchant = truncate(merchant, {length: CONST.REQUEST_PREVIEW.MAX_LENGTH});
const description = truncate(StringUtils.lineBreaksToSpaces(requestComment), {length: CONST.REQUEST_PREVIEW.MAX_LENGTH});
Expand All @@ -416,7 +410,6 @@ function createTransactionPreviewConditionals({
const isFullyApproved = isApproved && !isSettlementOrApprovalPartial;

const shouldShowSkeleton = isEmptyObject(transaction) && !isMessageDeleted(action) && !isDeletedAction(action) && action?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
const shouldShowTag = !!tag && isReportAPolicyExpenseChat;

const categoryForDisplay = isCategoryMissing(category) ? '' : category;

Expand Down Expand Up @@ -450,7 +443,6 @@ function createTransactionPreviewConditionals({

return {
shouldShowSkeleton,
shouldShowTag,
shouldShowRBR,
shouldShowCategory,
shouldShowKeepButton,
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/MoneyRequestReportPreview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ const getTransactionDisplayAmountAndMetadataText = (transaction: Transaction) =>
const created = getFormattedCreated(transaction);
const date = DateUtils.formatWithUTCTimeZone(created, DateUtils.doesDateBelongToAPastYear(created) ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, undefined);
const isTransactionMadeWithCard = isManagedCardTransaction(transaction);
// The date leads the supporting line, which can also carry the category and the report status.
const transactionSupportingText = new RegExp(`^${date}`);
// These transactions have no category and no status, so the date is the whole supporting line. Asserted exactly, so an
// unexpected category or status can't slip through.
const transactionSupportingText = date;
const transactionTypeText = isTransactionMadeWithCard ? TestHelper.translateLocal('iou.card') : TestHelper.translateLocal('iou.cash');
const transactionDisplayAmount = TestHelper.convertToDisplayString(-transaction.amount, transaction.currency);
return {transactionSupportingText, transactionTypeText, transactionDisplayAmount};
Expand Down
17 changes: 2 additions & 15 deletions tests/unit/TransactionPreviewUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const basicProps = {
transactionDetails: {},
isBillSplit: false,
shouldShowRBR: false,
shouldShowCanceledStatus: false,
isReportAPolicyExpenseChat: false,
areThereDuplicates: false,
currentUserEmail: '',
Expand Down Expand Up @@ -256,18 +255,12 @@ describe('TransactionPreviewUtils', () => {
expect(result.displayAmountText.text).toEqual(convertAmountToDisplayString(modifiedAmount, currency));
});

it('does not show the canceled status inside a report preview, because the preview header already shows it', () => {
const functionArgs = {...basicProps, iouReport: {...basicProps.iouReport, isCancelledIOU: true}, originalTransaction: undefined, shouldShowCanceledStatus: false};
it('does not show the canceled status, because it is reported at the report level instead', () => {
const functionArgs = {...basicProps, iouReport: {...basicProps.iouReport, isCancelledIOU: true}, originalTransaction: undefined};
const result = getTransactionPreviewTextAndTranslationPaths(functionArgs);
expect(result.previewStatusText).toEqual([]);
});

it('shows the canceled status in a standalone preview, because nothing else on that surface reports it', () => {
const functionArgs = {...basicProps, iouReport: {...basicProps.iouReport, isCancelledIOU: true}, originalTransaction: undefined, shouldShowCanceledStatus: true};
const result = getTransactionPreviewTextAndTranslationPaths(functionArgs);
expect(result.previewStatusText).toContainEqual({translationPath: 'iou.canceled'});
});

it('does not show the approved status when the report is approved, because it is redundant with the report status badge', () => {
const functionArgs = {
...basicProps,
Expand Down Expand Up @@ -538,12 +531,6 @@ describe('TransactionPreviewUtils', () => {
expect(result.shouldShowDescription).toBeFalsy();
});

it("should show tag if it's a policy expense chat and tag is present", () => {
const functionArgs = {...basicProps, isReportAPolicyExpenseChat: true, transactionDetails: {tag: 'Transport'}};
const result = createTransactionPreviewConditionals(functionArgs);
expect(result.shouldShowTag).toBeTruthy();
});

it('should correctly show violation message if there are multiple violations', () => {
const functionArgs = {
...basicProps,
Expand Down
Loading