From 89a81f1b658db16ed1695668bb9d5e79d188f80a Mon Sep 17 00:00:00 2001 From: ijmalik Date: Mon, 15 Sep 2025 13:33:39 +0500 Subject: [PATCH 1/3] Resolved - Concierge Bug: Concierge changes appear in the LHN as Expensify --- src/libs/OptionsListUtils/index.ts | 28 ++++++++++++++++++++++++++++ src/libs/SidebarUtils.ts | 14 +++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index c414362ff934..2d1baa4e542f 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -415,6 +415,10 @@ function getLastActorDisplayName(lastActorDetails: Partial | nu return ''; } + if (lastActorDetails.accountID === CONST.ACCOUNT_ID.CONCIERGE) { + return CONST.CONCIERGE_DISPLAY_NAME; + } + return lastActorDetails.accountID !== currentUserAccountID ? // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing lastActorDetails.firstName || formatPhoneNumber(getDisplayNameOrDefault(lastActorDetails)) @@ -543,6 +547,29 @@ function hasHiddenDisplayNames(accountIDs: number[]) { return getPersonalDetailsByIDs({accountIDs, currentUserAccountID: 0}).some((personalDetail) => !getDisplayNameOrDefault(personalDetail, undefined, false)); } +function getLastActorDisplayNameFromLastVisibleActions(report: OnyxEntry, lastActorDetails: Partial | null): string { + const reportID = report?.reportID; + const lastReportAction = reportID ? lastVisibleReportActions[reportID] : undefined; + + if (lastReportAction) { + const lastActorAccountID = lastReportAction.actorAccountID; + let actorDetails: Partial | null = lastActorAccountID ? (allPersonalDetails?.[lastActorAccountID] ?? null) : null; + + if (!actorDetails && lastReportAction.person?.at(0)?.text) { + actorDetails = { + displayName: lastReportAction.person?.at(0)?.text, + accountID: lastActorAccountID, + }; + } + + if (actorDetails) { + return getLastActorDisplayName(actorDetails); + } + } + + return getLastActorDisplayName(lastActorDetails); +} + /** * Get the last message text from the report directly or from other sources for special cases. */ @@ -2606,6 +2633,7 @@ export { getIOUReportIDOfLastAction, getIsUserSubmittedExpenseOrScannedReceipt, getLastActorDisplayName, + getLastActorDisplayNameFromLastVisibleActions, getLastMessageTextForReport, getManagerMcTestParticipant, getMemberInviteOptions, diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 78d13361dca5..f6d7f94392e7 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -16,7 +16,13 @@ import type Report from '@src/types/onyx/Report'; import type ReportAction from '@src/types/onyx/ReportAction'; import {hasValidDraftComment} from './DraftCommentUtils'; import {translateLocal} from './Localize'; -import {getLastActorDisplayName, getLastMessageTextForReport, getPersonalDetailsForAccountIDs, shouldShowLastActorDisplayName} from './OptionsListUtils'; +import { + getLastActorDisplayName, + getLastActorDisplayNameFromLastVisibleActions, + getLastMessageTextForReport, + getPersonalDetailsForAccountIDs, + shouldShowLastActorDisplayName, +} from './OptionsListUtils'; import Parser from './Parser'; import Performance from './Performance'; import {getCleanedTagName, getPolicy} from './PolicyUtils'; @@ -842,7 +848,8 @@ function getOptionData({ } else if (isCardIssuedAction(lastAction)) { result.alternateText = getCardIssuedMessage({reportAction: lastAction, expensifyCard: card}); } else if (lastAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && lastActorDisplayName && lastMessageTextFromReport) { - result.alternateText = formatReportLastMessageText(Parser.htmlToText(`${lastActorDisplayName}: ${lastMessageText}`)); + const displayName = (lastMessageTextFromReport.length > 0 && getLastActorDisplayNameFromLastVisibleActions(report, lastActorDetails)) || lastActorDisplayName; + result.alternateText = formatReportLastMessageText(Parser.htmlToText(`${displayName}: ${lastMessageText}`)); } else if (lastAction && isOldDotReportAction(lastAction)) { result.alternateText = getMessageOfOldDotReportAction(lastAction); } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_DESCRIPTION) { @@ -900,7 +907,8 @@ function getOptionData({ ); } if (shouldShowLastActorDisplayName(report, lastActorDetails, lastAction) && !isReportArchived) { - result.alternateText = `${lastActorDisplayName}: ${formatReportLastMessageText(Parser.htmlToText(lastMessageText))}`; + const displayName = (lastMessageTextFromReport.length > 0 && getLastActorDisplayNameFromLastVisibleActions(report, lastActorDetails)) || lastActorDisplayName; + result.alternateText = `${displayName}: ${formatReportLastMessageText(Parser.htmlToText(lastMessageText))}`; } else { result.alternateText = formatReportLastMessageText(Parser.htmlToText(lastMessageText)); } From f9992346613712f0cd93e968aa4fa84ec2d46aa8 Mon Sep 17 00:00:00 2001 From: ijmalik Date: Mon, 15 Sep 2025 13:34:33 +0500 Subject: [PATCH 2/3] Test correction - Added missing current user session --- tests/unit/SidebarUtilsTest.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/SidebarUtilsTest.ts b/tests/unit/SidebarUtilsTest.ts index 47169beb0d97..65e4e56bb7fe 100644 --- a/tests/unit/SidebarUtilsTest.ts +++ b/tests/unit/SidebarUtilsTest.ts @@ -1311,12 +1311,22 @@ describe('SidebarUtils', () => { shouldShow: true, pendingAction: null, }; + + const session = { + authToken: 'sensitive-auth-token', + encryptedAuthToken: 'sensitive-encrypted-token', + email: 'user@example.com', + accountID: 2, + }; + const reportActions: ReportActions = {[lastAction.reportActionID]: lastAction}; + await Onyx.set(ONYXKEYS.SESSION, session); await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, reportActions); await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}12345`, { name: "Three's Workspace", }); + const result = SidebarUtils.getOptionData({ report, reportAttributes: undefined, From 490d44c09cb67bb43eae00cbe6bc7b4fd4dc4d43 Mon Sep 17 00:00:00 2001 From: ijmalik Date: Thu, 2 Oct 2025 21:30:58 +0500 Subject: [PATCH 3/3] Fix test failures and refactor to match getOptionData implementation --- src/libs/OptionsListUtils/index.ts | 10 +++++++++- tests/unit/SidebarUtilsTest.ts | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 0e38e8a121a4..ad92d81b8b24 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -99,6 +99,7 @@ import { getReimbursementDeQueuedOrCanceledActionMessage, getReimbursementQueuedActionMessage, getRejectedReportMessage, + getReportActionActorAccountID, getReportLastMessage, getReportName, getReportNotificationPreference, @@ -555,7 +556,8 @@ function getLastActorDisplayNameFromLastVisibleActions(report: OnyxEntry const lastReportAction = reportID ? lastVisibleReportActions[reportID] : undefined; if (lastReportAction) { - const lastActorAccountID = lastReportAction.actorAccountID; + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const lastActorAccountID = getReportActionActorAccountID(lastReportAction, undefined, undefined) || report?.lastActorAccountID; let actorDetails: Partial | null = lastActorAccountID ? (allPersonalDetails?.[lastActorAccountID] ?? null) : null; if (!actorDetails && lastReportAction.person?.at(0)?.text) { @@ -565,6 +567,12 @@ function getLastActorDisplayNameFromLastVisibleActions(report: OnyxEntry }; } + // Assign the actor account ID from the last action when it’s a REPORT_PREVIEW action. + // to ensures that actorDetails.accountID is correctly set in case it's empty string + if (lastReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && actorDetails) { + actorDetails.accountID = lastReportAction.actorAccountID; + } + if (actorDetails) { return getLastActorDisplayName(actorDetails); } diff --git a/tests/unit/SidebarUtilsTest.ts b/tests/unit/SidebarUtilsTest.ts index b9ccddf7e358..633265f0499a 100644 --- a/tests/unit/SidebarUtilsTest.ts +++ b/tests/unit/SidebarUtilsTest.ts @@ -1588,8 +1588,21 @@ describe('SidebarUtils', () => { whisperedToAccountIDs: [], }; const reportActions: ReportActions = {[lastAction.reportActionID]: lastAction}; + const PERSONAL_DETAILS = { + '1': { + accountID: 1, + login: 'email1@test.com', + firstName: 'One', + }, + '2': { + accountID: 2, + login: 'email2@test.com', + firstName: 'Two', + }, + }; await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, report); await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, reportActions); + await Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, PERSONAL_DETAILS); const result = SidebarUtils.getOptionData({ report, reportAttributes: undefined,