diff --git a/src/components/SelectionList/Search/ActionCell.tsx b/src/components/SelectionList/Search/ActionCell.tsx
index c7e7f587769c..2608e4e2de8c 100644
--- a/src/components/SelectionList/Search/ActionCell.tsx
+++ b/src/components/SelectionList/Search/ActionCell.tsx
@@ -87,16 +87,19 @@ function ActionCell({
);
}
- if (action === CONST.SEARCH.ACTION_TYPES.VIEW || shouldUseViewAction) {
+ if (action === CONST.SEARCH.ACTION_TYPES.VIEW || action === CONST.SEARCH.ACTION_TYPES.REVIEW || shouldUseViewAction) {
return isLargeScreenWidth ? (
) : null;
}
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index 86f7aaaecce9..ab99cdac0fca 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -257,6 +257,12 @@ function getAction(data: OnyxTypes.SearchResults['data'], key: string): SearchTr
const transaction = isTransaction ? data[key] : undefined;
const report = isTransaction ? data[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`] : data[key];
+ // We need to check both options for a falsy value since the transaction might not have an error but the report associated with it might
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+ if (transaction?.hasError || report.hasError) {
+ return CONST.SEARCH.ACTION_TYPES.REVIEW;
+ }
+
if (ReportUtils.isSettled(report)) {
return CONST.SEARCH.ACTION_TYPES.PAID;
}
diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts
index 65e5cfe62c63..8ef5802b80dc 100644
--- a/src/libs/actions/Search.ts
+++ b/src/libs/actions/Search.ts
@@ -273,52 +273,52 @@ function submitMoneyRequestOnSearch(hash: number, reportList: SearchReport[], po
}
function approveMoneyRequestOnSearch(hash: number, reportIDList: string[], transactionIDList?: string[]) {
- const createActionLoadingData = (isLoading: boolean): OnyxUpdate[] => [
+ const createOnyxData = (update: Partial | Partial): OnyxUpdate[] => [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
value: {
data: transactionIDList
- ? (Object.fromEntries(
- transactionIDList.map((transactionID) => [`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {isActionLoading: isLoading}]),
- ) as Partial)
- : (Object.fromEntries(reportIDList.map((reportID) => [`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {isActionLoading: isLoading}])) as Partial),
+ ? (Object.fromEntries(transactionIDList.map((transactionID) => [`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, update])) as Partial)
+ : (Object.fromEntries(reportIDList.map((reportID) => [`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, update])) as Partial),
},
},
];
- const optimisticData: OnyxUpdate[] = createActionLoadingData(true);
- const finallyData: OnyxUpdate[] = createActionLoadingData(false);
+ const optimisticData: OnyxUpdate[] = createOnyxData({isActionLoading: true});
+ const failureData: OnyxUpdate[] = createOnyxData({hasError: true});
+ const finallyData: OnyxUpdate[] = createOnyxData({isActionLoading: false});
- API.write(WRITE_COMMANDS.APPROVE_MONEY_REQUEST_ON_SEARCH, {hash, reportIDList}, {optimisticData, finallyData});
+ API.write(WRITE_COMMANDS.APPROVE_MONEY_REQUEST_ON_SEARCH, {hash, reportIDList}, {optimisticData, failureData, finallyData});
}
function payMoneyRequestOnSearch(hash: number, paymentData: PaymentData[], transactionIDList?: string[]) {
- const createActionLoadingData = (isLoading: boolean): OnyxUpdate[] => [
+ const createOnyxData = (update: Partial | Partial): OnyxUpdate[] => [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
value: {
data: transactionIDList
- ? (Object.fromEntries(
- transactionIDList.map((transactionID) => [`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {isActionLoading: isLoading}]),
- ) as Partial)
- : (Object.fromEntries(paymentData.map((item) => [`${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, {isActionLoading: isLoading}])) as Partial),
+ ? (Object.fromEntries(transactionIDList.map((transactionID) => [`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, update])) as Partial)
+ : (Object.fromEntries(paymentData.map((item) => [`${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, update])) as Partial),
},
},
];
- const optimisticData: OnyxUpdate[] = createActionLoadingData(true);
- const finallyData: OnyxUpdate[] = createActionLoadingData(false);
+ const optimisticData: OnyxUpdate[] = createOnyxData({isActionLoading: true});
+ const failureData: OnyxUpdate[] = createOnyxData({hasError: true});
+ const finallyData: OnyxUpdate[] = createOnyxData({isActionLoading: false});
// eslint-disable-next-line rulesdir/no-api-side-effects-method
- API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.PAY_MONEY_REQUEST_ON_SEARCH, {hash, paymentData: JSON.stringify(paymentData)}, {optimisticData, finallyData}).then(
- (response) => {
- if (response?.jsonCode !== CONST.JSON_CODE.SUCCESS) {
- return;
- }
- playSound(SOUNDS.SUCCESS);
- },
- );
+ API.makeRequestWithSideEffects(
+ SIDE_EFFECT_REQUEST_COMMANDS.PAY_MONEY_REQUEST_ON_SEARCH,
+ {hash, paymentData: JSON.stringify(paymentData)},
+ {optimisticData, failureData, finallyData},
+ ).then((response) => {
+ if (response?.jsonCode !== CONST.JSON_CODE.SUCCESS) {
+ return;
+ }
+ playSound(SOUNDS.SUCCESS);
+ });
}
function unholdMoneyRequestOnSearch(hash: number, transactionIDList: string[]) {
diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts
index 7cee219d3b04..16d09a687346 100644
--- a/src/types/onyx/SearchResults.ts
+++ b/src/types/onyx/SearchResults.ts
@@ -154,6 +154,9 @@ type SearchReport = {
/** Whether the action is loading */
isActionLoading?: boolean;
+
+ /** Whether the report has violations or errors */
+ hasError?: boolean;
};
/** Model of report action search result */
@@ -359,6 +362,9 @@ type SearchTransaction = {
/** Whether the action is loading */
isActionLoading?: boolean;
+
+ /** Whether the transaction has violations or errors */
+ hasError?: boolean;
};
/** Types of searchable transactions */