@@ -846,6 +846,7 @@ type OptionData = {
846846 allReportErrors?: Errors;
847847 brickRoadIndicator?: ValueOf<typeof CONST.BRICK_ROAD_INDICATOR_STATUS> | '' | null;
848848 actionBadge?: ValueOf<typeof CONST.REPORT.ACTION_BADGE>;
849+ actionTargetReportActionID?: string;
849850 tooltipText?: string | null;
850851 alternateTextMaxLines?: number;
851852 boldStyle?: boolean;
@@ -9100,67 +9101,51 @@ function shouldHideReport(
91009101}
91019102
91029103/**
9103- * Should we display a RBR on the LHN on this report due to violations?
9104+ * Returns the reportID of the first child expense report that has violations under the same policy,
9105+ * or undefined if none found. Used to find the REPORT_PREVIEW action to deep-link to.
91049106 */
9105- function shouldDisplayViolationsRBRInLHN (report: OnyxEntry<Report>, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean {
9107+ function getViolatingReportIDForRBRInLHN (report: OnyxEntry<Report>, transactionViolations: OnyxCollection<TransactionViolation[]>): string | null {
91069108 // We only show the RBR in the highest level, which is the expense chat
91079109 if (!report || !isPolicyExpenseChat(report)) {
9108- return false ;
9110+ return null ;
91099111 }
91109112
91119113 // We only show the RBR to the submitter
91129114 if (!isCurrentUserSubmitter(report)) {
9113- return false ;
9115+ return null ;
91149116 }
91159117 if (!report.policyID || !reportsByPolicyID) {
9116- return false ;
9118+ return null ;
91179119 }
91189120
91199121 // If any report has a violation, then it should have a RBR
91209122 const potentialReports = Object.values(reportsByPolicyID[report.policyID] ?? {}) ?? [];
9121- return potentialReports.some((potentialReport) => {
9122- if (!potentialReport) {
9123- return false;
9124- }
9125- const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
9126- const transactions = getReportTransactions(potentialReport.reportID);
9123+ const violatingReport = potentialReports
9124+ // eslint-disable-next-line rulesdir/prefer-locale-compare-from-context
9125+ .sort((a, b) => (a?.created ?? '').localeCompare(b?.created ?? ''))
9126+ .find((potentialReport) => {
9127+ if (!potentialReport) {
9128+ return false;
9129+ }
9130+ const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
9131+ const transactions = getReportTransactions(potentialReport.reportID);
91279132
9128- // Allow both open and processing reports to show RBR for violations
9129- if (!isOpenOrProcessingReport(potentialReport)) {
9130- return false;
9131- }
9133+ // Allow both open and processing reports to show RBR for violations
9134+ if (!isOpenOrProcessingReport(potentialReport)) {
9135+ return false;
9136+ }
91329137
9133- return (
9134- !isInvoiceReport(potentialReport) &&
9135- ViolationsUtils.hasVisibleViolationsForUser(
9136- potentialReport,
9137- transactionViolations,
9138- currentUserEmail ?? '',
9139- currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
9140- policy,
9141- transactions,
9142- ) &&
9143- (hasViolations(
9144- potentialReport.reportID,
9145- transactionViolations,
9146- currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
9147- currentUserEmail ?? '',
9148- true,
9149- transactions,
9150- potentialReport,
9151- policy,
9152- ) ||
9153- hasWarningTypeViolations(
9154- potentialReport.reportID,
9138+ return (
9139+ !isInvoiceReport(potentialReport) &&
9140+ ViolationsUtils.hasVisibleViolationsForUser(
9141+ potentialReport,
91559142 transactionViolations,
9156- currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
91579143 currentUserEmail ?? '',
9158- true,
9159- transactions,
9160- potentialReport,
9144+ currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
91619145 policy,
9162- ) ||
9163- hasNoticeTypeViolations(
9146+ transactions,
9147+ ) &&
9148+ (hasViolations(
91649149 potentialReport.reportID,
91659150 transactionViolations,
91669151 currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
@@ -9169,9 +9154,30 @@ function shouldDisplayViolationsRBRInLHN(report: OnyxEntry<Report>, transactionV
91699154 transactions,
91709155 potentialReport,
91719156 policy,
9172- ))
9173- );
9174- });
9157+ ) ||
9158+ hasWarningTypeViolations(
9159+ potentialReport.reportID,
9160+ transactionViolations,
9161+ currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
9162+ currentUserEmail ?? '',
9163+ true,
9164+ transactions,
9165+ potentialReport,
9166+ policy,
9167+ ) ||
9168+ hasNoticeTypeViolations(
9169+ potentialReport.reportID,
9170+ transactionViolations,
9171+ currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
9172+ currentUserEmail ?? '',
9173+ true,
9174+ transactions,
9175+ potentialReport,
9176+ policy,
9177+ ))
9178+ );
9179+ });
9180+ return violatingReport ? violatingReport.reportID : null;
91759181}
91769182
91779183/**
@@ -9402,7 +9408,7 @@ function hasReportErrorsOtherThanFailedReceipt(
94029408 let doesTransactionThreadReportHasViolations = false;
94039409 if (oneTransactionThreadReportID) {
94049410 const transactionReport = getReport(oneTransactionThreadReportID, allReports);
9405- doesTransactionThreadReportHasViolations = !!transactionReport && shouldDisplayViolationsRBRInLHN (transactionReport, transactionViolations);
9411+ doesTransactionThreadReportHasViolations = !!transactionReport && !!getViolatingReportIDForRBRInLHN (transactionReport, transactionViolations);
94069412 }
94079413 return (
94089414 doesTransactionThreadReportHasViolations ||
@@ -12750,16 +12756,17 @@ function generateReportAttributes({
1275012756 transactionViolations: OnyxCollection<TransactionViolation[]>;
1275112757 isReportArchived: boolean;
1275212758 actionBadge?: ValueOf<typeof CONST.REPORT.ACTION_BADGE>;
12759+ actionTargetReportActionID?: string;
1275312760}) {
1275412761 const reportActionsList = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`];
1275512762 const parentReportActionsList = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`];
12756- const hasViolationsToDisplayInLHN = shouldDisplayViolationsRBRInLHN (report, transactionViolations);
12763+ const hasViolationsToDisplayInLHN = !!getViolatingReportIDForRBRInLHN (report, transactionViolations);
1275712764 const hasAnyTypeOfViolations = hasViolationsToDisplayInLHN;
1275812765 const reportErrors = getAllReportErrors(report, reportActionsList, isReportArchived);
1275912766 const hasErrors = Object.entries(reportErrors ?? {}).length > 0;
1276012767 const oneTransactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActionsList);
1276112768 const parentReportAction = report?.parentReportActionID ? parentReportActionsList?.[report.parentReportActionID] : undefined;
12762- const {reason, actionBadge} = getReasonAndReportActionThatRequiresAttention(report, parentReportAction, isReportArchived) ?? {};
12769+ const {reason, actionBadge, reportAction } = getReasonAndReportActionThatRequiresAttention(report, parentReportAction, isReportArchived) ?? {};
1276312770
1276412771 return {
1276512772 hasViolationsToDisplayInLHN,
@@ -12770,6 +12777,7 @@ function generateReportAttributes({
1277012777 parentReportAction,
1277112778 requiresAttention: !!reason,
1277212779 actionBadge,
12780+ actionTargetReportActionID: reportAction?.reportActionID,
1277312781 };
1277412782}
1277512783
@@ -13282,6 +13290,7 @@ export {
1328213290 getDisplayedReportID,
1328313291 getTransactionsWithReceipts,
1328413292 getUserDetailTooltipText,
13293+ getViolatingReportIDForRBRInLHN,
1328513294 getWhisperDisplayNames,
1328613295 getWorkspaceChats,
1328713296 getWorkspaceIcon,
@@ -13422,7 +13431,6 @@ export {
1342213431 shouldDisableRename,
1342313432 shouldDisableThread,
1342413433 shouldDisplayThreadReplies,
13425- shouldDisplayViolationsRBRInLHN,
1342613434 shouldReportBeInOptionList,
1342713435 shouldReportShowSubscript,
1342813436 shouldShowFlagComment,
0 commit comments