diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 779573b172a3..04b3974b99ab 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -630,6 +630,8 @@ function getLastMessageTextForReport({ lastMessageTextFromReport = getDeletedParentActionMessageForChatReport(lastReportAction); } else if (isPendingRemove(lastReportAction) && report?.reportID && isThreadParentMessage(lastReportAction, report.reportID)) { lastMessageTextFromReport = translateLocal('parentReportAction.hiddenMessage'); + } else if (isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) { + lastMessageTextFromReport = translateLocal('iou.paidElsewhere'); } else if (isReportMessageAttachment({text: report?.lastMessageText ?? '', html: report?.lastMessageHtml, type: ''})) { lastMessageTextFromReport = `[${translateLocal('common.attachment')}]`; } else if (isModifiedExpenseAction(lastReportAction)) { diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 5760335fb8a3..790f876e5a12 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -612,11 +612,19 @@ function extractLinksFromMessageHtml(reportAction: OnyxEntry): str */ function findPreviousAction(reportActions: ReportAction[], actionIndex: number): OnyxEntry { for (let i = actionIndex + 1; i < reportActions.length; i++) { + const action = reportActions.at(i); + // Find the next non-pending deletion report action, as the pending delete action means that it is not displayed in the UI, but still is in the report actions list. // If we are offline, all actions are pending but shown in the UI, so we take the previous action, even if it is a delete. - if (isNetworkOffline || reportActions.at(i)?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { - return reportActions.at(i); + if (!isNetworkOffline && action?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { + continue; + } + + if (action?.shouldShow === false) { + continue; } + + return action; } return undefined; @@ -629,11 +637,19 @@ function findPreviousAction(reportActions: ReportAction[], actionIndex: number): */ function findNextAction(reportActions: ReportAction[], actionIndex: number): OnyxEntry { for (let i = actionIndex - 1; i >= 0; i--) { + const action = reportActions.at(i); + // Find the next non-pending deletion report action, as the pending delete action means that it is not displayed in the UI, but still is in the report actions list. // If we are offline, all actions are pending but shown in the UI, so we take the previous action, even if it is a delete. - if (isNetworkOffline || reportActions.at(i)?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { - return reportActions.at(i); + if (!isNetworkOffline && action?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { + continue; } + + if (action?.shouldShow === false) { + continue; + } + + return action; } return undefined; @@ -875,12 +891,6 @@ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: return false; } - // Ignore markedAsReimbursed action here since we're already display message that explains the expense was paid - // elsewhere in the IOU reportAction - if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED) { - return false; - } - if (isWhisperActionTargetedToOthers(reportAction)) { return false; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4e913b129e01..1f6abf0ace30 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5413,6 +5413,10 @@ function getReportName( return getPolicyChangeLogDefaultTitleEnforcedMessage(parentReportAction); } + if (isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) { + return translateLocal('iou.paidElsewhere'); + } + if (isActionOfType(parentReportAction, CONST.REPORT.ACTIONS.TYPE.CHANGE_POLICY)) { return getPolicyChangeMessage(parentReportAction); } diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 8e4057fe406b..41a4417bc8b1 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -590,6 +590,8 @@ const ContextMenuActions: ContextMenuAction[] = [ Clipboard.setString(getPolicyChangeLogDefaultTitleEnforcedMessage(reportAction)); } else if (isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.UNREPORTED_TRANSACTION)) { setClipboardMessage(getUnreportedTransactionMessage()); + } else if (isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) { + Clipboard.setString(translateLocal('iou.paidElsewhere')); } else if (isReimbursementQueuedAction(reportAction)) { Clipboard.setString(getReimbursementQueuedActionMessage({reportAction, reportOrID: reportID, shouldUseShortDisplayName: false})); } else if (isActionableMentionWhisper(reportAction)) { diff --git a/src/pages/home/report/PureReportActionItem.tsx b/src/pages/home/report/PureReportActionItem.tsx index f1e20920f310..cf3199eca0b5 100644 --- a/src/pages/home/report/PureReportActionItem.tsx +++ b/src/pages/home/report/PureReportActionItem.tsx @@ -1166,6 +1166,10 @@ function PureReportActionItem({ } else { children = ; } + } else if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED)) { + const isFromNewDot = getOriginalMessage(action)?.isNewDot ?? false; + + children = isFromNewDot ? emptyHTML : ; } else if (isUnapprovedAction(action)) { children = ; } else if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.FORWARDED)) { diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 60fc313817c5..2ea64c86fd05 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -756,6 +756,18 @@ type OriginalMessageDismissedViolation = { violationName: string; }; +/** Model of `marked reimbursed` report action */ +type OriginalMessageMarkedReimbursed = { + /** Whether this action was created from NewDot */ + isNewDot?: boolean; + + /** When was the action last modified */ + lastModified?: string; + + /** Type of payment method */ + type?: string; +}; + /** Model of `trip room preview` report action */ type OriginalMessageTripRoomPreview = { /** ID of the report to be previewed */ @@ -988,7 +1000,7 @@ type OriginalMessageMap = { [CONST.REPORT.ACTIONS.TYPE.MANAGER_ATTACH_RECEIPT]: never; [CONST.REPORT.ACTIONS.TYPE.MANAGER_DETACH_RECEIPT]: never; [CONST.REPORT.ACTIONS.TYPE.MARK_REIMBURSED_FROM_INTEGRATION]: never; - [CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED]: never; + [CONST.REPORT.ACTIONS.TYPE.MARKED_REIMBURSED]: OriginalMessageMarkedReimbursed; [CONST.REPORT.ACTIONS.TYPE.MERGED_WITH_CASH_TRANSACTION]: never; [CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE]: OriginalMessageModifiedExpense; [CONST.REPORT.ACTIONS.TYPE.MOVED]: OriginalMessageMoved;