Skip to content
Merged
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
24 changes: 17 additions & 7 deletions src/components/TransactionItemRow/TransactionItemRowRBR.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,39 @@ type TransactionItemRowRBRProps = {

/** Styles for the RBR messages container */
containerStyles?: ViewStyle[];

/** Error message for missing required fields in the transaction */
missingFieldError?: string;
};

/** This component is lighter version of TransactionItemRowRBRWithOnyx that doesn't use onyx but uses transactionViolations data computed from search,
* thus it doesn't include violations taken from reportActions like its counterpart does. */
function TransactionItemRowRBR({transactionViolations, containerStyles}: TransactionItemRowRBRProps) {
function TransactionItemRowRBR({transactionViolations, containerStyles, missingFieldError}: TransactionItemRowRBRProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const theme = useTheme();
if (!transactionViolations) {

if (!transactionViolations && !missingFieldError) {
return null;
}

const RBRMessages = [
...(missingFieldError ? [`${missingFieldError}.`] : []),
// Some violations end with a period already so lets make sure the connected messages have only single period between them
// and end with a single dot.
...transactionViolations.map((violation) => {
const message = ViolationsUtils.getViolationTranslation(violation, translate);
return message.endsWith('.') || transactionViolations.length === 1 ? message : `${message}.`;
}),
...(transactionViolations
? transactionViolations.map((violation) => {
const message = ViolationsUtils.getViolationTranslation(violation, translate);
return message.endsWith('.') ? message : `${message}.`;
})
: []),
].join(' ');
return (
RBRMessages.length > 0 && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, containerStyles]}>
<View
style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, containerStyles]}
testID="TransactionItemRowRBR"
>
<Icon
src={DotIndicator}
fill={theme.danger}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type TransactionItemRowRBRProps = {

/** Styles for the RBR messages container */
containerStyles?: ViewStyle[];

/** Error message for missing required fields in the transaction */
missingFieldError?: string;
};

/**
Expand Down Expand Up @@ -64,7 +67,7 @@ const extractErrorMessages = (errors: Errors | ReceiptErrors, errorActions: Repo
return Array.from(uniqueMessages);
};

function TransactionItemRowRBRWithOnyx({transaction, containerStyles}: TransactionItemRowRBRProps) {
function TransactionItemRowRBRWithOnyx({transaction, containerStyles, missingFieldError}: TransactionItemRowRBRProps) {
const styles = useThemeStyles();
const transactionViolations = useTransactionViolations(transaction?.transactionID);
const {translate} = useLocalize();
Expand All @@ -83,16 +86,20 @@ function TransactionItemRowRBRWithOnyx({transaction, containerStyles}: Transacti
transaction?.errors,
transactionThreadActions?.filter((e) => !!e.errors),
),
...(missingFieldError ? [`${missingFieldError}.`] : []),
// Some violations end with a period already so lets make sure the connected messages have only single period between them
// and end with a single dot.
...transactionViolations.map((violation) => {
const message = ViolationsUtils.getViolationTranslation(violation, translate);
return message.endsWith('.') || transactionViolations.length === 1 ? message : `${message}.`;
return message.endsWith('.') ? message : `${message}.`;
}),
].join(' ');
return (
RBRMessages.length > 0 && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, containerStyles]}>
<View
style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, containerStyles]}
testID="TransactionItemRowRBRWithOnyx"
>
<Icon
src={DotIndicator}
fill={theme.danger}
Expand Down
31 changes: 29 additions & 2 deletions src/components/TransactionItemRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import {
getMerchant,
getCreated as getTransactionCreated,
getTransactionPendingAction,
hasMissingSmartscanFields,
hasReceipt,
isAmountMissing,
isMerchantMissing,
isReceiptBeingScanned,
isTransactionPendingDelete,
} from '@libs/TransactionUtils';
Expand Down Expand Up @@ -165,6 +168,23 @@ function TransactionItemRow({
}, [hovered, isParentHovered, isSelected, styles.activeComponentBG, styles.hoveredComponentBG]);

const merchantOrDescriptionName = useMemo(() => getMerchantNameWithFallback(transactionItem, translate, shouldUseNarrowLayout), [shouldUseNarrowLayout, transactionItem, translate]);
const missingFieldError = useMemo(() => {
const hasFieldErrors = hasMissingSmartscanFields(transactionItem);
if (hasFieldErrors) {
const amountMissing = isAmountMissing(transactionItem);
const merchantMissing = isMerchantMissing(transactionItem);
let error = '';

if (amountMissing && merchantMissing) {
error = translate('violations.reviewRequired');
} else if (amountMissing) {
error = translate('iou.missingAmount');
} else if (merchantMissing) {
error = translate('iou.missingMerchant');
}
return error;
}
}, [transactionItem, translate]);

useEffect(() => {
if (!transactionItem.shouldBeHighlighted || !scrollToNewTransaction) {
Expand Down Expand Up @@ -395,6 +415,7 @@ function TransactionItemRow({
<TransactionItemRowRBRWithOnyx
transaction={transactionItem}
containerStyles={[styles.mt2, styles.minHeight4]}
missingFieldError={missingFieldError}
/>
</View>
<ChatBubbleCell
Expand Down Expand Up @@ -422,9 +443,15 @@ function TransactionItemRow({
</View>
{}
{isInReportTableView ? (
<TransactionItemRowRBRWithOnyx transaction={transactionItem} />
<TransactionItemRowRBRWithOnyx
transaction={transactionItem}
missingFieldError={missingFieldError}
/>
) : (
<TransactionItemRowRBR transactionViolations={transactionItem.violations} /> // We are rendering this component only if we are not in the report table view for performance reasons
<TransactionItemRowRBR
transactionViolations={transactionItem.violations}
missingFieldError={missingFieldError}
/> // We are rendering this component only if we are not in the report table view for performance reasons
)}
</View>
</Animated.View>
Expand Down
Loading