From df1d58658fa567362edd542465031d9cb0fff47c Mon Sep 17 00:00:00 2001 From: Linh Date: Thu, 1 Jan 2026 16:42:28 +0700 Subject: [PATCH 01/24] fix: remove currentUserEmail from Onyx.connect --- src/components/MoneyReportHeader.tsx | 6 ++--- src/libs/actions/Report.ts | 14 +++++----- .../PrivateNotes/PrivateNotesEditPage.tsx | 4 ++- .../report/ReportActionItemMessageEdit.tsx | 27 +++++++++++++++++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index af21e451a9ba7..f1b38d484fc73 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1478,9 +1478,9 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload || !canTriggerAutomaticPDFDownload.current) { return; } - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email); canTriggerAutomaticPDFDownload.current = false; - }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate]); + }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate, email]); const shouldShowBackButton = shouldDisplayBackButton || shouldUseNarrowLayout; @@ -1789,7 +1789,7 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload) { setIsPDFModalVisible(false); } else { - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email); } }} text={hasFinishedPDFDownload ? translate('common.download') : translate('common.cancel')} diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 5a45120de2617..af5ab78e9a180 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -274,6 +274,7 @@ type ReportError = { const addNewMessageWithText = new Set([WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_TEXT_AND_ATTACHMENT]); let conciergeReportID: string | undefined; let currentUserAccountID = -1; +/** @deprecated This value is deprecated. Use the email from useCurrentUserPersonalDetails hook instead. */ let currentUserEmail: string | undefined; Onyx.connect({ @@ -2143,12 +2144,12 @@ function removeLinksFromHtml(html: string, links: string[]): string { * @param originalCommentMarkdown original markdown of the comment before editing. * @param videoAttributeCache cache of video attributes ([videoSource]: videoAttributes) */ -function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, videoAttributeCache?: Record): string { +function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, videoAttributeCache?: Record, userEmail?: string): string { if (newCommentText.length > CONST.MAX_MARKUP_LENGTH) { return newCommentText; } - const userEmailDomain = isEmailPublicDomain(currentUserEmail ?? '') ? '' : Str.extractEmailDomain(currentUserEmail ?? ''); + const userEmailDomain = isEmailPublicDomain(userEmail ?? '') ? '' : Str.extractEmailDomain(userEmail ?? ''); const allPersonalDetailLogins = Object.values(allPersonalDetails ?? {}).map((personalDetail) => personalDetail?.login ?? ''); const htmlForNewComment = getParsedMessageWithShortMentions({ @@ -2173,6 +2174,7 @@ function editReportComment( isOriginalReportArchived: boolean | undefined, isOriginalParentReportArchived: boolean | undefined, videoAttributeCache?: Record, + userEmail?: string, ) { const originalReportID = originalReport?.reportID; if (!originalReportID || !originalReportAction) { @@ -2191,7 +2193,7 @@ function editReportComment( if (originalCommentMarkdown === textForNewComment) { return; } - const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, videoAttributeCache); + const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, videoAttributeCache, userEmail); const reportComment = Parser.htmlToText(htmlForNewComment); @@ -3630,7 +3632,7 @@ function doneCheckingPublicRoom() { function getCurrentUserAccountID(): number { return currentUserAccountID; } - +/** @deprecated This function is deprecated. Use the email from useCurrentUserPersonalDetails hook instead. */ function getCurrentUserEmail(): string | undefined { return currentUserEmail; } @@ -4923,12 +4925,12 @@ function exportReportToPDF({reportID}: ExportReportPDFParams) { API.write(WRITE_COMMANDS.EXPORT_REPORT_TO_PDF, params, {optimisticData, failureData}); } -function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate) { +function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, userEmail?: string) { const baseURL = addTrailingForwardSlash(getOldDotURLFromEnvironment(environment)); const downloadFileName = `${reportName}.pdf`; setDownload(fileName, true); const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${encodeURIComponent(fileName)}&downloadName=${encodeURIComponent(downloadFileName)}&email=${encodeURIComponent( - currentUserEmail ?? '', + userEmail ?? '', )}`; fileDownload(translate, addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); } diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx index e8fdc82312168..504589c2ecca5 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx @@ -12,6 +12,7 @@ import type {AnimatedTextInputRef} from '@components/RNTextInput'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -51,6 +52,7 @@ function PrivateNotesEditPageInternal({route, report, accountID, privateNoteDraf const styles = useThemeStyles(); const {translate} = useLocalize(); const personalDetailsList = usePersonalDetails(); + const {email} = useCurrentUserPersonalDetails(); // We need to edit the note in markdown format, but display it in HTML format const [privateNote, setPrivateNote] = useState(() => privateNoteDraft || Parser.htmlToMarkdown(report?.privateNotes?.[Number(route.params.accountID)]?.note ?? '').trim()); @@ -91,7 +93,7 @@ function PrivateNotesEditPageInternal({route, report, accountID, privateNoteDraf const originalNote = report?.privateNotes?.[Number(route.params.accountID)]?.note ?? ''; let editedNote = ''; if (privateNote.trim() !== originalNote.trim()) { - editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim()); + editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim(), undefined, email); updatePrivateNotes(report.reportID, Number(route.params.accountID), editedNote); } diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 1a3a10679ad38..33a2a5bba41da 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -16,6 +16,7 @@ import * as Expensicons from '@components/Icon/Expensicons'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Tooltip from '@components/Tooltip'; import useAncestors from '@hooks/useAncestors'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useHandleExceedMaxCommentLength from '@hooks/useHandleExceedMaxCommentLength'; import useIsScrollLikelyLayoutTriggered from '@hooks/useIsScrollLikelyLayoutTriggered'; import useKeyboardState from '@hooks/useKeyboardState'; @@ -153,6 +154,7 @@ function ReportActionItemMessageEdit({ const originalParentReportID = getOriginalReportID(originalReportID, action); const isOriginalParentReportArchived = useReportIsArchived(originalParentReportID); const ancestors = useAncestors(originalReport); + const {email} = useCurrentUserPersonalDetails(); useEffect(() => { draftMessageVideoAttributeCache.clear(); @@ -314,9 +316,30 @@ function ReportActionItemMessageEdit({ ReportActionContextMenu.showDeleteModal(originalReportID ?? reportID, action, true, deleteDraft, () => focusEditAfterCancelDelete(textInputRef.current)); return; } - editReportComment(originalReport, action, ancestors, trimmedNewDraft, isOriginalReportArchived, isOriginalParentReportArchived, Object.fromEntries(draftMessageVideoAttributeCache)); + editReportComment( + originalReport, + action, + ancestors, + trimmedNewDraft, + isOriginalReportArchived, + isOriginalParentReportArchived, + Object.fromEntries(draftMessageVideoAttributeCache), + email, + ); deleteDraft(); - }, [reportID, action, ancestors, deleteDraft, draft, originalReportID, isOriginalReportArchived, originalReport, isOriginalParentReportArchived, debouncedValidateCommentMaxLength]); + }, [ + reportID, + action, + ancestors, + deleteDraft, + draft, + originalReportID, + isOriginalReportArchived, + originalReport, + isOriginalParentReportArchived, + debouncedValidateCommentMaxLength, + email, + ]); /** * @param emoji From f0f50d900affcf7b69743d434b81fab651dc0fb2 Mon Sep 17 00:00:00 2001 From: Linh Date: Thu, 1 Jan 2026 18:27:41 +0700 Subject: [PATCH 02/24] chore: remove currentUserEmail from onyx --- .../ReportActionItem/MoneyRequestView.tsx | 2 +- src/components/Search/index.tsx | 8 ++++---- src/hooks/useSelectedTransactionsActions.ts | 5 ++++- src/hooks/useTodos.ts | 2 +- src/libs/PolicyUtils.ts | 6 ++---- src/libs/ReportPreviewActionUtils.ts | 6 +++--- src/libs/ReportPrimaryActionUtils.ts | 6 +++--- src/libs/ReportSecondaryActionUtils.ts | 17 +++++++++++------ src/libs/SearchUIUtils.ts | 2 +- src/libs/actions/Report.ts | 5 ----- src/pages/iou/SplitExpenseEditPage.tsx | 4 +++- src/pages/iou/SplitExpensePage.tsx | 4 ++-- 12 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 2c152e26e04b1..d153a09c0d66c 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -315,7 +315,7 @@ function MoneyRequestView({ const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(transactionThreadReport?.policyID)}`; const [originalTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transaction?.comment?.originalTransactionID)}`, {canBeMissing: true}); const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(transaction, originalTransaction); - const isSplitAvailable = moneyRequestReport && transaction && isSplitAction(moneyRequestReport, [transaction], originalTransaction, policy); + const isSplitAvailable = moneyRequestReport && transaction && isSplitAction(moneyRequestReport, [transaction], originalTransaction, currentUserPersonalDetails.email ?? '', policy); const canEditTaxFields = canEdit && !isDistanceRequest; const canEditAmount = diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 7c7079717c6ed..0f9a2c7c4252f 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -110,7 +110,7 @@ function mapTransactionItemToSelectedEntry( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, @@ -162,7 +162,7 @@ function prepareTransactionsList( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, @@ -509,7 +509,7 @@ function Search({ canHold: canHoldRequest, isHeld: isOnHold(transactionItem), canUnhold: canUnholdRequest, - canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, transactionItem.policy), + canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, email ?? '', transactionItem.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( transactionItem.reportAction, @@ -562,7 +562,7 @@ function Search({ canHold: canHoldRequest, isHeld: isOnHold(transactionItem), canUnhold: canUnholdRequest, - canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, transactionItem.policy), + canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, email ?? '', transactionItem.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( transactionItem.reportAction, diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index a50965e1e33f8..035ac1fd7ec16 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -1,6 +1,7 @@ import {useCallback, useMemo, useState} from 'react'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import {useSearchContext} from '@components/Search/SearchContext'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import {initSplitExpense, unholdRequest} from '@libs/actions/IOU'; import {setupMergeTransactionDataAndNavigate} from '@libs/actions/MergeTransaction'; import {exportReportToCSV} from '@libs/actions/Report'; @@ -76,6 +77,7 @@ function useSelectedTransactionsActions({ const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(selectedTransactionIDs); const isReportArchived = useReportIsArchived(report?.reportID); const {deleteTransactions} = useDeleteTransactions({report, reportActions, policy}); + const {email} = useCurrentUserPersonalDetails(); const selectedTransactionsList = useMemo( () => selectedTransactionIDs.reduce((acc, transactionID) => { @@ -329,7 +331,7 @@ function useSelectedTransactionsActions({ const originalTransaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${firstTransaction?.comment?.originalTransactionID}`]; const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(firstTransaction, originalTransaction); - const canSplitTransaction = selectedTransactionsList.length === 1 && report && !isExpenseSplit && isSplitAction(report, [firstTransaction], originalTransaction, policy); + const canSplitTransaction = selectedTransactionsList.length === 1 && report && !isExpenseSplit && isSplitAction(report, [firstTransaction], originalTransaction, email ?? '', policy); if (canSplitTransaction) { options.push({ @@ -398,6 +400,7 @@ function useSelectedTransactionsActions({ expensifyIcons.Trashcan, localeCompare, isOnSearch, + email, ]); return { diff --git a/src/hooks/useTodos.ts b/src/hooks/useTodos.ts index cc5859a3c6d43..26b354e431483 100644 --- a/src/hooks/useTodos.ts +++ b/src/hooks/useTodos.ts @@ -53,7 +53,7 @@ export default function useTodos() { if (isPrimaryPayAction(report, accountID, email, policy, reportNameValuePair)) { reportsToPay.push(report); } - if (isExportAction(report, policy, reportActions)) { + if (isExportAction(report, email, policy, reportActions)) { reportsToExport.push(report); } } diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 2b831a0f0d88f..07cd8372f72bf 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -34,7 +34,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {getBankAccountFromID} from './actions/BankAccounts'; import {hasSynchronizationErrorMessage, isConnectionUnverified} from './actions/connections'; import {shouldShowQBOReimbursableExportDestinationAccountError} from './actions/connections/QuickbooksOnline'; -import {getCurrentUserEmail} from './actions/Report'; import {getCategoryApproverRule} from './CategoryUtils'; import Navigation from './Navigation/Navigation'; import {isOffline as isOfflineNetworkStore} from './Network/NetworkStore'; @@ -1631,8 +1630,7 @@ const getDescriptionForPolicyDomainCard = (domainName: string): string => { return domainName; }; -function isPreferredExporter(policy: Policy) { - const user = getCurrentUserEmail(); +function isPreferredExporter(policy: Policy, userEmail: string) { const exporters = [ policy.connections?.intacct?.config?.export?.exporter, policy.connections?.netsuite?.options?.config?.exporter, @@ -1641,7 +1639,7 @@ function isPreferredExporter(policy: Policy) { policy.connections?.xero?.config?.export?.exporter, ]; - return exporters.some((exporter) => exporter && exporter === user); + return exporters.some((exporter) => exporter && exporter === userEmail); } /** diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index fdd16876cf9bf..c93b6ca25d758 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -135,9 +135,9 @@ function canPay(report: Report, isReportArchived: boolean, currentUserAccountID: return invoiceReceiverPolicy?.role === CONST.POLICY.ROLE.ADMIN && reimbursableSpend > 0; } -function canExport(report: Report, policy?: Policy) { +function canExport(report: Report, userEmail: string, policy?: Policy) { const isExpense = isExpenseReport(report); - const isExporter = policy ? isPreferredExporter(policy) : false; + const isExporter = policy ? isPreferredExporter(policy, userEmail) : false; const isReimbursed = isSettled(report); const isClosed = isClosedReport(report); const isApproved = isReportApproved({report}); @@ -216,7 +216,7 @@ function getReportPreviewAction({ if (canPay(report, isReportArchived, currentUserAccountID, currentUserEmail, policy, invoiceReceiverPolicy)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.PAY; } - if (canExport(report, policy)) { + if (canExport(report, currentUserEmail, policy)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.EXPORT_TO_ACCOUNTING; } diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index 56f7bc55baa3a..1e02fc4e4bf66 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -205,7 +205,7 @@ function isPrimaryPayAction( return invoiceReceiverPolicy?.role === CONST.POLICY.ROLE.ADMIN && reimbursableSpend > 0; } -function isExportAction(report: Report, policy?: Policy, reportActions?: ReportAction[]) { +function isExportAction(report: Report, currentUserEmail: string, policy?: Policy, reportActions?: ReportAction[]) { if (!policy) { return false; } @@ -219,7 +219,7 @@ function isExportAction(report: Report, policy?: Policy, reportActions?: ReportA const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const isReportExporter = isPreferredExporter(policy); + const isReportExporter = isPreferredExporter(policy, currentUserEmail); if (!isReportExporter && !isAdmin) { return false; } @@ -451,7 +451,7 @@ function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf, reportTransactions: Array>, originalTransaction: OnyxEntry, policy?: OnyxEntry): boolean { +function isSplitAction( + report: OnyxEntry, + reportTransactions: Array>, + originalTransaction: OnyxEntry, + currentUserEmail: string, + policy?: OnyxEntry, +): boolean { if (Number(reportTransactions?.length) !== 1 || !report) { return false; } @@ -119,7 +125,6 @@ function isSplitAction(report: OnyxEntry, reportTransactions: Array) { const lastAccessedReportID = findLastAccessedReport(false, false, undefined, currentReport?.reportID)?.reportID; @@ -6323,7 +6319,6 @@ export { exportToIntegration, flagComment, getCurrentUserAccountID, - getCurrentUserEmail, getMostRecentReportID, getNewerActions, getOlderActions, diff --git a/src/pages/iou/SplitExpenseEditPage.tsx b/src/pages/iou/SplitExpenseEditPage.tsx index 96ed74401c3de..cfd3ecec07755 100644 --- a/src/pages/iou/SplitExpenseEditPage.tsx +++ b/src/pages/iou/SplitExpenseEditPage.tsx @@ -9,6 +9,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import {useSearchContext} from '@components/Search/SearchContext'; import useAllTransactions from '@hooks/useAllTransactions'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; @@ -71,6 +72,7 @@ function SplitExpenseEditPage({route}: SplitExpensePageProps) { const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${currentReport?.policyID}`, {canBeMissing: false}); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${currentReport?.policyID}`, {canBeMissing: false}); + const {email} = useCurrentUserPersonalDetails(); const fetchData = useCallback(() => { if (!policyCategories) { @@ -104,7 +106,7 @@ function SplitExpenseEditPage({route}: SplitExpensePageProps) { const transactionTag = getTag(splitExpenseDraftTransaction); const policyTagLists = useMemo(() => getTagLists(policyTags), [policyTags]); - const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, currentPolicy); + const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, email ?? '', currentPolicy); const isCategoryRequired = !!currentPolicy?.requiresCategory; const reportName = computeReportName(currentReport); diff --git a/src/pages/iou/SplitExpensePage.tsx b/src/pages/iou/SplitExpensePage.tsx index 16014b39df8bf..3b3a60f764ea4 100644 --- a/src/pages/iou/SplitExpensePage.tsx +++ b/src/pages/iou/SplitExpensePage.tsx @@ -82,6 +82,7 @@ function SplitExpensePage({route}: SplitExpensePageProps) { const searchHash = searchContext?.currentSearchHash ?? CONST.DEFAULT_NUMBER_ID; const [currentSearchResults] = useOnyx(`${ONYXKEYS.COLLECTION.SNAPSHOT}${searchHash}`, {canBeMissing: true}); const allTransactions = useAllTransactions(); + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`]; const originalTransaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transaction?.comment?.originalTransactionID)}`]; @@ -97,7 +98,7 @@ function SplitExpensePage({route}: SplitExpensePageProps) { ? policy : currentSearchResults?.data?.[`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(currentReport?.policyID)}`]; - const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, currentPolicy); + const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, currentUserPersonalDetails.email ?? '', currentPolicy); const transactionDetails = useMemo>(() => getTransactionDetails(transaction) ?? {}, [transaction]); const transactionDetailsAmount = transactionDetails?.amount ?? 0; @@ -117,7 +118,6 @@ function SplitExpensePage({route}: SplitExpensePageProps) { const childTransactions = useMemo(() => getChildTransactions(allTransactions, allReports, transactionID), [allReports, allTransactions, transactionID]); const splitFieldDataFromChildTransactions = useMemo(() => childTransactions.map((currentTransaction) => initSplitExpenseItemData(currentTransaction)), [childTransactions]); const splitFieldDataFromOriginalTransaction = useMemo(() => initSplitExpenseItemData(transaction), [transaction]); - const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); const icons = useMemoizedLazyExpensifyIcons(['ArrowsLeftRight', 'Plus'] as const); From b1faaff4e0bcc0538a1dfb6684377c776a06b7a0 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 08:58:46 +0700 Subject: [PATCH 03/24] chore: disable estlint until migration success --- src/libs/actions/Report.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 74c585988f4ca..fca95911b8efb 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -274,7 +274,7 @@ type ReportError = { const addNewMessageWithText = new Set([WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_TEXT_AND_ATTACHMENT]); let conciergeReportID: string | undefined; let currentUserAccountID = -1; -/** @deprecated This value is deprecated. Use the email from useCurrentUserPersonalDetails hook instead. */ +/** @deprecated This value is deprecated and will be removed soon after migration. Use the email from useCurrentUserPersonalDetails hook instead. */ let currentUserEmail: string | undefined; Onyx.connect({ @@ -285,6 +285,7 @@ Onyx.connect({ conciergeReportID = undefined; return; } + // eslint-disable-next-line @typescript-eslint/no-deprecated currentUserEmail = value.email; currentUserAccountID = value.accountID; }, @@ -1077,6 +1078,7 @@ function openReport( const parentReport = transactionParentReportID === optimisticSelfDMReport?.reportID ? optimisticSelfDMReport : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionParentReportID}`]; const submitterAccountID = parentReport?.ownerAccountID ?? currentUserAccountID; + // eslint-disable-next-line @typescript-eslint/no-deprecated const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? currentUserEmail ?? ''; const submitterPersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(submitterEmail); @@ -1204,6 +1206,7 @@ function openReport( const isGroupChat = isGroupChatReportUtils(newReportObject); if (isGroupChat) { parameters.chatType = CONST.REPORT.CHAT_TYPE.GROUP; + // eslint-disable-next-line @typescript-eslint/no-deprecated parameters.groupChatAdminLogins = currentUserEmail; parameters.optimisticAccountIDList = Object.keys(newReportObject?.participants ?? {}).join(','); parameters.reportName = newReportObject?.reportName ?? ''; @@ -1446,6 +1449,7 @@ function createTransactionThreadReport( openReport( optimisticTransactionThreadReportID, undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated currentUserEmail ? [currentUserEmail] : [], optimisticTransactionThread, iouReportAction?.reportActionID, From 611b99805c1088c6c4578f095391ad1d2592e1e4 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 09:08:59 +0700 Subject: [PATCH 04/24] chore: prettier --- src/hooks/useSelectedTransactionsActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index 035ac1fd7ec16..99a7938243d3c 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -1,7 +1,6 @@ import {useCallback, useMemo, useState} from 'react'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import {useSearchContext} from '@components/Search/SearchContext'; -import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import {initSplitExpense, unholdRequest} from '@libs/actions/IOU'; import {setupMergeTransactionDataAndNavigate} from '@libs/actions/MergeTransaction'; import {exportReportToCSV} from '@libs/actions/Report'; @@ -28,6 +27,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, Session, Transaction} from '@src/types/onyx'; import useAllTransactions from './useAllTransactions'; +import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; import useDeleteTransactions from './useDeleteTransactions'; import useDuplicateTransactionsAndViolations from './useDuplicateTransactionsAndViolations'; import {useMemoizedLazyExpensifyIcons} from './useLazyAsset'; From dc8b49fa46860efd01e5ed69590325130e671d74 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 09:13:46 +0700 Subject: [PATCH 05/24] chore: make current user email required --- src/components/MoneyReportHeader.tsx | 4 ++-- src/libs/actions/Report.ts | 12 ++++++------ src/pages/PrivateNotes/PrivateNotesEditPage.tsx | 2 +- .../home/report/ReportActionItemMessageEdit.tsx | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index f1b38d484fc73..fa6edf001166a 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1478,7 +1478,7 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload || !canTriggerAutomaticPDFDownload.current) { return; } - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email ?? ''); canTriggerAutomaticPDFDownload.current = false; }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate, email]); @@ -1789,7 +1789,7 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload) { setIsPDFModalVisible(false); } else { - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email ?? ''); } }} text={hasFinishedPDFDownload ? translate('common.download') : translate('common.cancel')} diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index fca95911b8efb..58b6b7d8a6bde 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2148,12 +2148,12 @@ function removeLinksFromHtml(html: string, links: string[]): string { * @param originalCommentMarkdown original markdown of the comment before editing. * @param videoAttributeCache cache of video attributes ([videoSource]: videoAttributes) */ -function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, videoAttributeCache?: Record, userEmail?: string): string { +function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, userEmail: string, videoAttributeCache?: Record): string { if (newCommentText.length > CONST.MAX_MARKUP_LENGTH) { return newCommentText; } - const userEmailDomain = isEmailPublicDomain(userEmail ?? '') ? '' : Str.extractEmailDomain(userEmail ?? ''); + const userEmailDomain = isEmailPublicDomain(userEmail) ? '' : Str.extractEmailDomain(userEmail); const allPersonalDetailLogins = Object.values(allPersonalDetails ?? {}).map((personalDetail) => personalDetail?.login ?? ''); const htmlForNewComment = getParsedMessageWithShortMentions({ @@ -2177,8 +2177,8 @@ function editReportComment( textForNewComment: string, isOriginalReportArchived: boolean | undefined, isOriginalParentReportArchived: boolean | undefined, + userEmail: string, videoAttributeCache?: Record, - userEmail?: string, ) { const originalReportID = originalReport?.reportID; if (!originalReportID || !originalReportAction) { @@ -2197,7 +2197,7 @@ function editReportComment( if (originalCommentMarkdown === textForNewComment) { return; } - const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, videoAttributeCache, userEmail); + const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, userEmail, videoAttributeCache); const reportComment = Parser.htmlToText(htmlForNewComment); @@ -4925,12 +4925,12 @@ function exportReportToPDF({reportID}: ExportReportPDFParams) { API.write(WRITE_COMMANDS.EXPORT_REPORT_TO_PDF, params, {optimisticData, failureData}); } -function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, userEmail?: string) { +function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, userEmail: string) { const baseURL = addTrailingForwardSlash(getOldDotURLFromEnvironment(environment)); const downloadFileName = `${reportName}.pdf`; setDownload(fileName, true); const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${encodeURIComponent(fileName)}&downloadName=${encodeURIComponent(downloadFileName)}&email=${encodeURIComponent( - userEmail ?? '', + userEmail, )}`; fileDownload(translate, addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); } diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx index 504589c2ecca5..5a7bf2a675b05 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx @@ -93,7 +93,7 @@ function PrivateNotesEditPageInternal({route, report, accountID, privateNoteDraf const originalNote = report?.privateNotes?.[Number(route.params.accountID)]?.note ?? ''; let editedNote = ''; if (privateNote.trim() !== originalNote.trim()) { - editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim(), undefined, email); + editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim(), email ?? '', undefined); updatePrivateNotes(report.reportID, Number(route.params.accountID), editedNote); } diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index 33a2a5bba41da..501dd5d018376 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -323,8 +323,8 @@ function ReportActionItemMessageEdit({ trimmedNewDraft, isOriginalReportArchived, isOriginalParentReportArchived, + email ?? '', Object.fromEntries(draftMessageVideoAttributeCache), - email, ); deleteDraft(); }, [ From 5bcaeee1f3254a6d4637f0361d6963c870b18eef Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 10:24:56 +0700 Subject: [PATCH 06/24] chore: pass email to isSplitAction --- src/pages/iou/SplitExpenseCreateDateRagePage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/iou/SplitExpenseCreateDateRagePage.tsx b/src/pages/iou/SplitExpenseCreateDateRagePage.tsx index 7cb001e41d9ab..eb4fe5658d6d8 100644 --- a/src/pages/iou/SplitExpenseCreateDateRagePage.tsx +++ b/src/pages/iou/SplitExpenseCreateDateRagePage.tsx @@ -9,6 +9,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import {useSearchContext} from '@components/Search/SearchContext'; import useAllTransactions from '@hooks/useAllTransactions'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; @@ -51,13 +52,14 @@ function SplitExpenseCreateDateRagePage({route}: SplitExpenseCreateDateRagePageP const currentPolicy = Object.keys(policy?.employeeList ?? {}).length ? policy : currentSearchResults?.data?.[`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(currentReport?.policyID)}`]; + const {email} = useCurrentUserPersonalDetails(); const updateDate = (value: FormOnyxValues) => { resetSplitExpensesByDateRange(transaction, value[INPUT_IDS.START_DATE], value[INPUT_IDS.END_DATE]); Navigation.goBack(backTo); }; - const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, currentPolicy); + const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, email ?? '', currentPolicy); const validate = (values: FormOnyxValues) => { const errors: FormInputErrors = {}; From 23fdb8ae4b3fc774c2a0094604d0488c162fc876 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 10:27:04 +0700 Subject: [PATCH 07/24] test: add test for short mention in comment edits --- tests/actions/ReportTest.ts | 115 +++++++++++++++++++++++++++++++----- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 7ed8cff409aa3..0bd16591f4fdb 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -539,7 +539,7 @@ describe('actions/Report', () => { return setPromise; }); - it('Should properly update comment with links', () => { + it('Should properly update comment with links', async () => { /* This tests a variety of scenarios when a user edits a comment. * We should generate a link when editing a message unless the link was * already in the comment and the user deleted it on purpose. @@ -547,11 +547,13 @@ describe('actions/Report', () => { global.fetch = TestHelper.getGlobalFetchMock(); + const TEST_USER_LOGIN = 'test@expensify.com'; + // User edits comment to add link // We should generate link let originalCommentMarkdown = 'Original Comment'; let afterEditCommentText = 'Original Comment www.google.com'; - let newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + let newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); let expectedOutput = 'Original Comment www.google.com'; expect(newCommentHTML).toBe(expectedOutput); @@ -559,7 +561,7 @@ describe('actions/Report', () => { // We should not generate link originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com)'; afterEditCommentText = 'Comment www.google.com'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'Comment www.google.com'; expect(newCommentHTML).toBe(expectedOutput); @@ -567,7 +569,7 @@ describe('actions/Report', () => { // We should not generate link originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com)'; afterEditCommentText = 'Comment [www.google.com]'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'Comment [www.google.com]'; expect(newCommentHTML).toBe(expectedOutput); @@ -575,7 +577,7 @@ describe('actions/Report', () => { // We should generate both links originalCommentMarkdown = 'Comment'; afterEditCommentText = 'Comment www.google.com www.facebook.com'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'Comment www.google.com ' + 'www.facebook.com'; @@ -585,7 +587,7 @@ describe('actions/Report', () => { // Should not generate link again for the deleted one originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com) [www.facebook.com](https://www.facebook.com)'; afterEditCommentText = 'Comment www.google.com [www.facebook.com](https://www.facebook.com)'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'Comment www.google.com www.facebook.com'; expect(newCommentHTML).toBe(expectedOutput); @@ -593,7 +595,7 @@ describe('actions/Report', () => { // We should generate link originalCommentMarkdown = 'Comment'; afterEditCommentText = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; expect(newCommentHTML).toBe(expectedOutput); @@ -601,7 +603,7 @@ describe('actions/Report', () => { // We should not generate link originalCommentMarkdown = '[https://www.facebook.com/hashtag/__main/?__eep__=6](https://www.facebook.com/hashtag/__main/?__eep__=6)'; afterEditCommentText = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; expect(newCommentHTML).toBe(expectedOutput); @@ -609,7 +611,7 @@ describe('actions/Report', () => { // We should generate link originalCommentMarkdown = 'Comment'; afterEditCommentText = 'http://example.com/foo/*/bar/*/test.txt'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'http://example.com/foo/*/bar/*/test.txt'; expect(newCommentHTML).toBe(expectedOutput); @@ -617,9 +619,25 @@ describe('actions/Report', () => { // We should not generate link originalCommentMarkdown = '[http://example.com/foo/*/bar/*/test.txt](http://example.com/foo/*/bar/*/test.txt)'; afterEditCommentText = 'http://example.com/foo/*/bar/*/test.txt'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); expectedOutput = 'http://example.com/foo/*/bar/*/test.txt'; expect(newCommentHTML).toBe(expectedOutput); + + // User edits comment to add mention + // We should generate mention-user tag + const privateDomainAccount = { + accountID: 2, + login: 'user@expensify.com', + email: 'user@expensify.com', + }; + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, { + [privateDomainAccount.accountID]: privateDomainAccount, + }); + originalCommentMarkdown = 'Comment'; + afterEditCommentText = 'Comment @user'; + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown, TEST_USER_LOGIN); + expectedOutput = 'Comment @user@expensify.com'; + expect(newCommentHTML).toBe(expectedOutput); }); it('should show a notification for report action updates with shouldNotify', () => { @@ -980,6 +998,7 @@ describe('actions/Report', () => { it('should remove AddComment and UpdateComment without sending any request when DeleteComment is set', async () => { global.fetch = TestHelper.getGlobalFetchMock(); + const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const TEN_MINUTES_AGO = subMinutes(new Date(), 10); @@ -998,7 +1017,7 @@ describe('actions/Report', () => { }; const {result: ancestors, rerender} = renderHook(() => useAncestors(originalReport)); - Report.editReportComment(originalReport, newReportAction, ancestors.current, 'Testing an edited comment', undefined, undefined); + Report.editReportComment(originalReport, newReportAction, ancestors.current, 'Testing an edited comment', undefined, undefined, TEST_USER_LOGIN); await waitForBatchedUpdates(); @@ -1059,6 +1078,7 @@ describe('actions/Report', () => { it('should send DeleteComment request and remove UpdateComment accordingly', async () => { global.fetch = TestHelper.getGlobalFetchMock(); + const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const TEN_MINUTES_AGO = subMinutes(new Date(), 10); @@ -1080,7 +1100,7 @@ describe('actions/Report', () => { }; const {result: ancestors, rerender} = renderHook(() => useAncestors(originalReport)); - Report.editReportComment(originalReport, reportAction, ancestors.current, 'Testing an edited comment', undefined, undefined); + Report.editReportComment(originalReport, reportAction, ancestors.current, 'Testing an edited comment', undefined, undefined, TEST_USER_LOGIN); await waitForBatchedUpdates(); @@ -1627,6 +1647,7 @@ describe('actions/Report', () => { it('should update AddComment text with the UpdateComment text, sending just an AddComment request', async () => { global.fetch = TestHelper.getGlobalFetchMock(); + const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const TEN_MINUTES_AGO = subMinutes(new Date(), 10); @@ -1642,7 +1663,7 @@ describe('actions/Report', () => { const originalReport = { reportID: REPORT_ID, }; - Report.editReportComment(originalReport, reportAction, [], 'Testing an edited comment', undefined, undefined); + Report.editReportComment(originalReport, reportAction, [], 'Testing an edited comment', undefined, undefined, TEST_USER_LOGIN); await waitForBatchedUpdates(); @@ -1664,6 +1685,7 @@ describe('actions/Report', () => { it('it should only send the last sequential UpdateComment request to BE', async () => { global.fetch = TestHelper.getGlobalFetchMock(); const reportID = '123'; + const TEST_USER_LOGIN = 'test@gmail.com'; await Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}); @@ -1680,9 +1702,9 @@ describe('actions/Report', () => { const {result: ancestors} = renderHook(() => useAncestors(originalReport)); - Report.editReportComment(originalReport, action, ancestors.current, 'value1', undefined, undefined); - Report.editReportComment(originalReport, action, ancestors.current, 'value2', undefined, undefined); - Report.editReportComment(originalReport, action, ancestors.current, 'value3', undefined, undefined); + Report.editReportComment(originalReport, action, ancestors.current, 'value1', undefined, undefined, TEST_USER_LOGIN); + Report.editReportComment(originalReport, action, ancestors.current, 'value2', undefined, undefined, TEST_USER_LOGIN); + Report.editReportComment(originalReport, action, ancestors.current, 'value3', undefined, undefined, TEST_USER_LOGIN); const requests = PersistedRequests?.getAll(); @@ -1695,6 +1717,67 @@ describe('actions/Report', () => { TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.UPDATE_COMMENT, 1); }); + it('should convert short mentions to full format when editing comments', async () => { + global.fetch = TestHelper.getGlobalFetchMock(); + + const TEST_USER_LOGIN = 'alice@expensify.com'; + const TEST_USER_ACCOUNT_ID = 1; + const MENTIONED_USER_ACCOUNT_ID = 2; + const MENTIONED_USER_LOGIN = 'bob@expensify.com'; + const REPORT_ID = '1'; + const TEN_MINUTES_AGO = subMinutes(new Date(), 10); + const created = format(addSeconds(TEN_MINUTES_AGO, 10), CONST.DATE.FNS_DB_FORMAT_STRING); + + // Set up personal details with private domain users + await TestHelper.setPersonalDetails(TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, { + [MENTIONED_USER_ACCOUNT_ID]: { + accountID: MENTIONED_USER_ACCOUNT_ID, + login: MENTIONED_USER_LOGIN, + displayName: 'Bob', + }, + }); + + await Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}); + + Report.addComment(REPORT_ID, REPORT_ID, [], 'Initial comment', CONST.DEFAULT_TIME_ZONE); + + // Get the reportActionID to edit and delete the comment + const newComment = PersistedRequests.getAll().at(0); + const reportActionID = newComment?.data?.reportActionID as string | undefined; + const newReportAction = TestHelper.buildTestReportComment(created, TEST_USER_ACCOUNT_ID, reportActionID); + const originalReport = { + reportID: REPORT_ID, + }; + + const {result: ancestors} = renderHook(() => useAncestors(originalReport)); + + // Edit the comment to add a short mention + Report.editReportComment(originalReport, newReportAction, ancestors.current, 'Initial comment with @bob', undefined, undefined, TEST_USER_LOGIN); + + await waitForBatchedUpdates(); + + // Verify the mention was converted in the edited comment + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${REPORT_ID}`, + callback: (reportActions) => { + Onyx.disconnect(connection); + + const reportAction = reportActionID ? reportActions?.[reportActionID] : null; + const message = reportAction?.message; + const editedMessage = Array.isArray(message) && message.length > 0 ? message.at(0)?.html : undefined; + // Verify the mention was converted to full mention with domain + expect(editedMessage).toContain('@bob@expensify.com'); + expect(editedMessage).toBe('Initial comment with @bob@expensify.com'); + resolve(); + }, + }); + }); + await Onyx.set(ONYXKEYS.NETWORK, {isOffline: false}); + await waitForBatchedUpdates(); + }); + it('should clears lastMentionedTime when all mentions to the current user are deleted', async () => { const reportID = '1'; const mentionActionID = '1'; From bafad57ff5109f25cef43b226ba85c1cade9cd45 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 10:54:14 +0700 Subject: [PATCH 08/24] test: add test export to accounting action --- tests/unit/Search/SearchUIUtilsTest.ts | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index bdc414bd4338b..4d7781dda9fca 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -1822,6 +1822,49 @@ describe('SearchUIUtils', () => { const action = SearchUIUtils.getActions(searchResults.data, {}, iouReportKey, CONST.SEARCH.SEARCH_KEYS.EXPENSES, '').at(0); expect(action).toEqual(CONST.SEARCH.ACTION_TYPES.PAY); }); + + test('Should return EXPORT_TO_ACCOUNTING action when report is approved and policy has verified accounting integration', () => { + const exportReportID = 'report_export'; + const localSearchResults = { + ...searchResults.data, + [`policy_${policyID}`]: { + ...searchResults.data[`policy_${policyID}`], + role: CONST.POLICY.ROLE.ADMIN, + exporter: adminEmail, + connections: { + [CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: { + verified: true, + lastSync: { + errorDate: '', + errorMessage: '', + isAuthenticationError: false, + isConnected: true, + isSuccessful: true, + source: 'NEWEXPENSIFY', + successfulDate: '', + }, + }, + } as Connections, + }, + [`report_${exportReportID}`]: { + ...searchResults.data[`report_${reportID2}`], + reportID: exportReportID, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + }, + }; + + const actions = SearchUIUtils.getActions( + localSearchResults, + {}, + `report_${exportReportID}`, + CONST.SEARCH.SEARCH_KEYS.EXPENSES, + adminEmail, + [], + ); + + expect(actions).toContain(CONST.SEARCH.ACTION_TYPES.EXPORT_TO_ACCOUNTING); + }); }); describe('Test getListItem', () => { From f378b047c66be6316f3894d0cc2183d3196a4b17 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 10:54:20 +0700 Subject: [PATCH 09/24] test: add test export to accounting action --- tests/unit/Search/SearchUIUtilsTest.ts | 37 +++++++++++--------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 4d7781dda9fca..843cad3e47772 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -1831,20 +1831,20 @@ describe('SearchUIUtils', () => { ...searchResults.data[`policy_${policyID}`], role: CONST.POLICY.ROLE.ADMIN, exporter: adminEmail, - connections: { - [CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: { - verified: true, - lastSync: { - errorDate: '', - errorMessage: '', - isAuthenticationError: false, - isConnected: true, - isSuccessful: true, - source: 'NEWEXPENSIFY', - successfulDate: '', + connections: { + [CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: { + verified: true, + lastSync: { + errorDate: '', + errorMessage: '', + isAuthenticationError: false, + isConnected: true, + isSuccessful: true, + source: 'NEWEXPENSIFY', + successfulDate: '', + }, }, - }, - } as Connections, + } as Connections, }, [`report_${exportReportID}`]: { ...searchResults.data[`report_${reportID2}`], @@ -1854,15 +1854,8 @@ describe('SearchUIUtils', () => { }, }; - const actions = SearchUIUtils.getActions( - localSearchResults, - {}, - `report_${exportReportID}`, - CONST.SEARCH.SEARCH_KEYS.EXPENSES, - adminEmail, - [], - ); - + const actions = SearchUIUtils.getActions(localSearchResults, {}, `report_${exportReportID}`, CONST.SEARCH.SEARCH_KEYS.EXPENSES, adminEmail, []); + expect(actions).toContain(CONST.SEARCH.ACTION_TYPES.EXPORT_TO_ACCOUNTING); }); }); From 975f680015d189710a3d46cff614b0a5a03ca317 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 12:07:08 +0700 Subject: [PATCH 10/24] chore: update prop --- src/libs/PolicyUtils.ts | 4 ++-- src/libs/ReportPreviewActionUtils.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 07cd8372f72bf..bbd2604945472 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1630,7 +1630,7 @@ const getDescriptionForPolicyDomainCard = (domainName: string): string => { return domainName; }; -function isPreferredExporter(policy: Policy, userEmail: string) { +function isPreferredExporter(policy: Policy, currentUserEmail: string) { const exporters = [ policy.connections?.intacct?.config?.export?.exporter, policy.connections?.netsuite?.options?.config?.exporter, @@ -1639,7 +1639,7 @@ function isPreferredExporter(policy: Policy, userEmail: string) { policy.connections?.xero?.config?.export?.exporter, ]; - return exporters.some((exporter) => exporter && exporter === userEmail); + return exporters.some((exporter) => exporter && exporter === currentUserEmail); } /** diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index c93b6ca25d758..352a245586dc5 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -135,9 +135,9 @@ function canPay(report: Report, isReportArchived: boolean, currentUserAccountID: return invoiceReceiverPolicy?.role === CONST.POLICY.ROLE.ADMIN && reimbursableSpend > 0; } -function canExport(report: Report, userEmail: string, policy?: Policy) { +function canExport(report: Report, currentUserEmail: string, policy?: Policy) { const isExpense = isExpenseReport(report); - const isExporter = policy ? isPreferredExporter(policy, userEmail) : false; + const isExporter = policy ? isPreferredExporter(policy, currentUserEmail) : false; const isReimbursed = isSettled(report); const isClosed = isClosedReport(report); const isApproved = isReportApproved({report}); @@ -190,6 +190,8 @@ function getReportPreviewAction({ isSubmittingAnimationRunning?: boolean; violationsData?: OnyxCollection; }): ValueOf { + console.log('🚀 ~ getReportPreviewAction ~ currentUserEmail:', currentUserEmail); + if (!report) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.VIEW; } From 51303ad1cd1dcf2abb3df3a0cc6e2ba36262978f Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 2 Jan 2026 12:40:42 +0700 Subject: [PATCH 11/24] chore: eslint fail --- src/libs/ReportPreviewActionUtils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index 352a245586dc5..2f531aa1aa734 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -190,8 +190,6 @@ function getReportPreviewAction({ isSubmittingAnimationRunning?: boolean; violationsData?: OnyxCollection; }): ValueOf { - console.log('🚀 ~ getReportPreviewAction ~ currentUserEmail:', currentUserEmail); - if (!report) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.VIEW; } From 543bae48492f63613e64f4a4078c8f9eba732391 Mon Sep 17 00:00:00 2001 From: Linh Date: Sun, 4 Jan 2026 09:20:31 +0700 Subject: [PATCH 12/24] chore: rename param --- src/components/Search/index.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 0f9a2c7c4252f..b7bd0b5d3bde5 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -95,12 +95,11 @@ function mapTransactionItemToSelectedEntry( item: TransactionListItemType, itemTransaction: OnyxEntry, originalItemTransaction: OnyxEntry, - currentUserLogin: string, + currentUserEmail: string, outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue, ): [string, SelectedTransactionInfo] { const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy); - const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false; - + const canRejectRequest = item.report ? canRejectReportAction(currentUserEmail, item.report, item.policy) : false; return [ item.keyForList, { @@ -110,7 +109,7 @@ function mapTransactionItemToSelectedEntry( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserEmail, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, @@ -141,7 +140,7 @@ function prepareTransactionsList( itemTransaction: OnyxEntry, originalItemTransaction: OnyxEntry, selectedTransactions: SelectedTransactions, - currentUserLogin: string, + currentUserEmail: string, outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue, ) { if (selectedTransactions[item.keyForList]?.isSelected) { @@ -151,7 +150,7 @@ function prepareTransactionsList( } const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy); - const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false; + const canRejectRequest = item.report ? canRejectReportAction(currentUserEmail, item.report, item.policy) : false; return { ...selectedTransactions, @@ -162,7 +161,7 @@ function prepareTransactionsList( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserEmail, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, From 93242bc6f651b0b7c3e59ec33906e6c453795dc4 Mon Sep 17 00:00:00 2001 From: Linh Date: Sun, 4 Jan 2026 09:26:03 +0700 Subject: [PATCH 13/24] chore: update current user email and account id to deprecated --- src/libs/actions/Report.ts | 82 +++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 58b6b7d8a6bde..4d08260f9d0c8 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -273,9 +273,9 @@ type ReportError = { const addNewMessageWithText = new Set([WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_TEXT_AND_ATTACHMENT]); let conciergeReportID: string | undefined; -let currentUserAccountID = -1; +let deprecatedCurrentUserAccountID = -1; /** @deprecated This value is deprecated and will be removed soon after migration. Use the email from useCurrentUserPersonalDetails hook instead. */ -let currentUserEmail: string | undefined; +let deprecatedCurrentUserEmail: string | undefined; Onyx.connect({ key: ONYXKEYS.SESSION, @@ -286,8 +286,8 @@ Onyx.connect({ return; } // eslint-disable-next-line @typescript-eslint/no-deprecated - currentUserEmail = value.email; - currentUserAccountID = value.accountID; + deprecatedCurrentUserEmail = value.email; + deprecatedCurrentUserAccountID = value.accountID; }, }); @@ -433,7 +433,7 @@ function subscribeToReportTypingEvents(reportID: string) { } // Don't show the typing indicator if the user is typing on another platform - if (Number(accountIDOrLogin) === currentUserAccountID) { + if (Number(accountIDOrLogin) === deprecatedCurrentUserAccountID) { return; } @@ -482,7 +482,7 @@ function subscribeToReportLeavingEvents(reportID: string | undefined) { return; } - if (Number(accountIDOrLogin) !== currentUserAccountID) { + if (Number(accountIDOrLogin) !== deprecatedCurrentUserAccountID) { return; } @@ -539,7 +539,7 @@ function notifyNewAction(reportID: string | undefined, accountID: number | undef if (!actionSubscriber) { return; } - const isFromCurrentUser = accountID === currentUserAccountID; + const isFromCurrentUser = accountID === deprecatedCurrentUserAccountID; actionSubscriber.callback(isFromCurrentUser, reportAction); } @@ -591,7 +591,7 @@ function addActions(reportID: string, notifyReportID: string, ancestors: Ancesto lastVisibleActionCreated: lastAction?.created, lastMessageText: lastCommentText, lastMessageHtml: lastCommentText, - lastActorAccountID: currentUserAccountID, + lastActorAccountID: deprecatedCurrentUserAccountID, lastReadTime: currentTime, }; @@ -599,7 +599,7 @@ function addActions(reportID: string, notifyReportID: string, ancestors: Ancesto const shouldUpdateNotificationPreference = !isEmptyObject(report) && isHiddenForCurrentUser(report); if (shouldUpdateNotificationPreference) { optimisticReport.participants = { - [currentUserAccountID]: {notificationPreference: getDefaultNotificationPreferenceForReport(report)}, + [deprecatedCurrentUserAccountID]: {notificationPreference: getDefaultNotificationPreferenceForReport(report)}, }; } @@ -696,13 +696,13 @@ function addActions(reportID: string, notifyReportID: string, ancestors: Ancesto ]; // Update the timezone if it's been 5 minutes from the last time the user added a comment - if (DateUtils.canUpdateTimezone() && currentUserAccountID) { + if (DateUtils.canUpdateTimezone() && deprecatedCurrentUserAccountID) { const timezone = DateUtils.getCurrentTimezone(timezoneParam); parameters.timezone = JSON.stringify(timezone); optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.PERSONAL_DETAILS_LIST, - value: {[currentUserAccountID]: {timezone}}, + value: {[deprecatedCurrentUserAccountID]: {timezone}}, }); DateUtils.setTimezoneUpdated(); } @@ -897,7 +897,7 @@ function updatePolicyRoomAvatar(reportID: string, file?: File | CustomRNImageMan onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - lastActorAccountID: currentUserAccountID, + lastActorAccountID: deprecatedCurrentUserAccountID, lastVisibleActionCreated: optimisticAction.created, lastMessageText: (optimisticAction.message as Message[]).at(0)?.text, }, @@ -1077,9 +1077,9 @@ function openReport( // Use optimisticSelfDMReport if provided (when selfDM exists but wasn't in allReports) const parentReport = transactionParentReportID === optimisticSelfDMReport?.reportID ? optimisticSelfDMReport : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionParentReportID}`]; - const submitterAccountID = parentReport?.ownerAccountID ?? currentUserAccountID; + const submitterAccountID = parentReport?.ownerAccountID ?? deprecatedCurrentUserAccountID; // eslint-disable-next-line @typescript-eslint/no-deprecated - const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? currentUserEmail ?? ''; + const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? deprecatedCurrentUserEmail ?? ''; const submitterPersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(submitterEmail); const optimisticIOUAction = buildOptimisticIOUReportAction({ @@ -1207,7 +1207,7 @@ function openReport( if (isGroupChat) { parameters.chatType = CONST.REPORT.CHAT_TYPE.GROUP; // eslint-disable-next-line @typescript-eslint/no-deprecated - parameters.groupChatAdminLogins = currentUserEmail; + parameters.groupChatAdminLogins = deprecatedCurrentUserEmail; parameters.optimisticAccountIDList = Object.keys(newReportObject?.participants ?? {}).join(','); parameters.reportName = newReportObject?.reportName ?? ''; @@ -1402,7 +1402,7 @@ function prepareOnyxDataForCleanUpOptimisticParticipants( */ function getOptimisticChatReport(accountID: number): OptimisticChatReport { return buildOptimisticChatReport({ - participantList: [accountID, currentUserAccountID], + participantList: [accountID, deprecatedCurrentUserAccountID], notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, }); } @@ -1450,7 +1450,7 @@ function createTransactionThreadReport( optimisticTransactionThreadReportID, undefined, // eslint-disable-next-line @typescript-eslint/no-deprecated - currentUserEmail ? [currentUserEmail] : [], + deprecatedCurrentUserEmail ? [deprecatedCurrentUserEmail] : [], optimisticTransactionThread, iouReportAction?.reportActionID, false, @@ -1487,16 +1487,16 @@ function navigateToAndOpenReport( // If we are not creating a new Group Chat then we are creating a 1:1 DM and will look for an existing chat if (!isGroupChat) { - chat = getChatByParticipants([...participantAccountIDs, currentUserAccountID]); + chat = getChatByParticipants([...participantAccountIDs, deprecatedCurrentUserAccountID]); } if (isEmptyObject(chat)) { if (isGroupChat) { - // If we are creating a group chat then participantAccountIDs is expected to contain currentUserAccountID + // If we are creating a group chat then participantAccountIDs is expected to contain deprecatedCurrentUserAccountID newChat = buildOptimisticGroupChatReport(participantAccountIDs, reportName ?? '', avatarUri ?? '', optimisticReportID, CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN); } else { newChat = buildOptimisticChatReport({ - participantList: [...participantAccountIDs, currentUserAccountID], + participantList: [...participantAccountIDs, deprecatedCurrentUserAccountID], notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }); } @@ -1531,10 +1531,10 @@ function navigateToAndOpenReport( */ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) { let newChat: OptimisticChatReport | undefined; - const chat = getChatByParticipants([...participantAccountIDs, currentUserAccountID]); + const chat = getChatByParticipants([...participantAccountIDs, deprecatedCurrentUserAccountID]); if (!chat) { newChat = buildOptimisticChatReport({ - participantList: [...participantAccountIDs, currentUserAccountID], + participantList: [...participantAccountIDs, deprecatedCurrentUserAccountID], }); // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server openReport(newChat?.reportID, '', [], newChat, '0', false, participantAccountIDs); @@ -1556,7 +1556,7 @@ function navigateToAndOpenChildReport(childReportID: string | undefined, parentR if (childReport?.reportID) { Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(childReportID, undefined, undefined, Navigation.getActiveRoute())); } else { - const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction.actorAccountID)])]; + const participantAccountIDs = [...new Set([deprecatedCurrentUserAccountID, Number(parentReportAction.actorAccountID)])]; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; // Threads from DMs and selfDMs don't have a chatType. All other threads inherit the chatType from their parent const childReportChatType = parentReport && isSelfDM(parentReport) ? undefined : parentReport?.chatType; @@ -1828,7 +1828,7 @@ function markCommentAsUnread(reportID: string | undefined, reportAction: ReportA const latestReportActionFromOtherUsers = Object.values(reportActions ?? {}).reduce((latest: ReportAction | null, current: ReportAction) => { if ( !ReportActionsUtils.isDeletedAction(current) && - current.actorAccountID !== currentUserAccountID && + current.actorAccountID !== deprecatedCurrentUserAccountID && (!latest || current.created > latest.created) && // Whisper action doesn't affect lastVisibleActionCreated, so skip whisper action except actionable mention whisper (!ReportActionsUtils.isWhisperAction(current) || current.actionName === CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER) @@ -1916,7 +1916,7 @@ function saveReportDraftComment(reportID: string, comment: string | null, callba function broadcastUserIsTyping(reportID: string) { const privateReportChannelName = getReportChannelName(reportID); const typingStatus: UserIsTypingEvent = { - [currentUserAccountID]: true, + [deprecatedCurrentUserAccountID]: true, }; Pusher.sendEvent(privateReportChannelName, Pusher.TYPE.USER_IS_TYPING, typingStatus); } @@ -1925,7 +1925,7 @@ function broadcastUserIsTyping(reportID: string) { function broadcastUserIsLeavingRoom(reportID: string) { const privateReportChannelName = getReportChannelName(reportID); const leavingStatus: UserIsLeavingRoomEvent = { - [currentUserAccountID]: true, + [deprecatedCurrentUserAccountID]: true, }; Pusher.sendEvent(privateReportChannelName, Pusher.TYPE.USER_IS_LEAVING_ROOM, leavingStatus); } @@ -2337,7 +2337,7 @@ function updateNotificationPreference( key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: newValue, }, }, @@ -2351,7 +2351,7 @@ function updateNotificationPreference( key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: previousValue, }, }, @@ -2426,7 +2426,7 @@ function toggleSubscribeToChildReport( updateNotificationPreference(childReportID, prevNotificationPreference, CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, parentReportID, parentReportActionID); } } else { - const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction?.actorAccountID)])]; + const participantAccountIDs = [...new Set([deprecatedCurrentUserAccountID, Number(parentReportAction?.actorAccountID)])]; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; const newChat = buildOptimisticChatReport({ participantList: participantAccountIDs, @@ -2761,7 +2761,7 @@ function updateDescription(reportID: string, currentDescription: string, newMark value: { description: parsedDescription, pendingFields: {description: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, - lastActorAccountID: currentUserAccountID, + lastActorAccountID: deprecatedCurrentUserAccountID, lastVisibleActionCreated: optimisticDescriptionUpdatedReportAction.created, lastMessageText: (optimisticDescriptionUpdatedReportAction?.message as Message[])?.at(0)?.text, }, @@ -3427,7 +3427,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi } // If this comment is from the current user we don't want to parrot whatever they wrote back to them. - if (action && action.actorAccountID === currentUserAccountID) { + if (action && action.actorAccountID === deprecatedCurrentUserAccountID) { Log.info(`${tag} No notification because comment is from the currently logged in user`); return false; } @@ -3515,7 +3515,7 @@ function addEmojiReaction(reportID: string, reportActionID: string, emoji: Emoji createdAt, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, users: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { skinTones: { [skinTone]: createdAt, }, @@ -3573,7 +3573,7 @@ function removeEmojiReaction(reportID: string, reportActionID: string, emoji: Em value: { [emoji.name]: { users: { - [currentUserAccountID]: null, + [deprecatedCurrentUserAccountID]: null, }, }, }, @@ -3621,7 +3621,7 @@ function toggleEmojiReaction( // Only use skin tone if emoji supports it const skinTone = emoji.types === undefined ? CONST.EMOJI_DEFAULT_SKIN_TONE : paramSkinTone; - if (existingReactionObject && EmojiUtils.hasAccountIDEmojiReacted(currentUserAccountID, existingReactionObject.users, ignoreSkinToneOnCompare ? undefined : skinTone)) { + if (existingReactionObject && EmojiUtils.hasAccountIDEmojiReacted(deprecatedCurrentUserAccountID, existingReactionObject.users, ignoreSkinToneOnCompare ? undefined : skinTone)) { removeEmojiReaction(originalReportID, reportAction.reportActionID, emoji); return; } @@ -3634,7 +3634,7 @@ function doneCheckingPublicRoom() { } function getCurrentUserAccountID(): number { - return currentUserAccountID; + return deprecatedCurrentUserAccountID; } function navigateToMostRecentReport(currentReport: OnyxEntry) { @@ -3691,7 +3691,7 @@ function leaveGroupChat(reportID: string, shouldClearQuickAction: boolean) { stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.CLOSED, participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }, }, @@ -3766,7 +3766,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal isWorkspaceMemberLeavingWorkspaceRoom || isChatThread ? { participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }, }, @@ -3776,7 +3776,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.CLOSED, participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }, }, @@ -3794,7 +3794,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { participants: { - [currentUserAccountID]: { + [deprecatedCurrentUserAccountID]: { notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }, }, @@ -3843,7 +3843,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, value: { [report.parentReportActionID]: { - childReportNotificationPreference: report?.participants?.[currentUserAccountID]?.notificationPreference ?? getDefaultNotificationPreferenceForReport(report), + childReportNotificationPreference: report?.participants?.[deprecatedCurrentUserAccountID]?.notificationPreference ?? getDefaultNotificationPreferenceForReport(report), }, }, }); @@ -5868,7 +5868,7 @@ function buildOptimisticChangePolicyData( if (newStatusNum === CONST.REPORT.STATUS_NUM.OPEN) { shouldSetOutstandingChildRequest = isCurrentUserSubmitter(report); } else if (isProcessingReport(report)) { - shouldSetOutstandingChildRequest = report.managerID === currentUserAccountID; + shouldSetOutstandingChildRequest = report.managerID === deprecatedCurrentUserAccountID; } } From 2f13241cc7074dd1a33699a5d426563e9b05069b Mon Sep 17 00:00:00 2001 From: Linh Date: Sun, 4 Jan 2026 09:29:15 +0700 Subject: [PATCH 14/24] chore: update param name --- src/libs/actions/Report.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 4d08260f9d0c8..d2bca5d7da698 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2148,12 +2148,12 @@ function removeLinksFromHtml(html: string, links: string[]): string { * @param originalCommentMarkdown original markdown of the comment before editing. * @param videoAttributeCache cache of video attributes ([videoSource]: videoAttributes) */ -function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, userEmail: string, videoAttributeCache?: Record): string { +function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, currentUserEmail: string, videoAttributeCache?: Record): string { if (newCommentText.length > CONST.MAX_MARKUP_LENGTH) { return newCommentText; } - const userEmailDomain = isEmailPublicDomain(userEmail) ? '' : Str.extractEmailDomain(userEmail); + const userEmailDomain = isEmailPublicDomain(currentUserEmail) ? '' : Str.extractEmailDomain(currentUserEmail); const allPersonalDetailLogins = Object.values(allPersonalDetails ?? {}).map((personalDetail) => personalDetail?.login ?? ''); const htmlForNewComment = getParsedMessageWithShortMentions({ @@ -2177,7 +2177,7 @@ function editReportComment( textForNewComment: string, isOriginalReportArchived: boolean | undefined, isOriginalParentReportArchived: boolean | undefined, - userEmail: string, + currentUserEmail: string, videoAttributeCache?: Record, ) { const originalReportID = originalReport?.reportID; @@ -2197,7 +2197,7 @@ function editReportComment( if (originalCommentMarkdown === textForNewComment) { return; } - const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, userEmail, videoAttributeCache); + const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, currentUserEmail, videoAttributeCache); const reportComment = Parser.htmlToText(htmlForNewComment); @@ -4925,12 +4925,12 @@ function exportReportToPDF({reportID}: ExportReportPDFParams) { API.write(WRITE_COMMANDS.EXPORT_REPORT_TO_PDF, params, {optimisticData, failureData}); } -function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, userEmail: string) { +function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, currentUserEmail: string) { const baseURL = addTrailingForwardSlash(getOldDotURLFromEnvironment(environment)); const downloadFileName = `${reportName}.pdf`; setDownload(fileName, true); const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${encodeURIComponent(fileName)}&downloadName=${encodeURIComponent(downloadFileName)}&email=${encodeURIComponent( - userEmail, + currentUserEmail, )}`; fileDownload(translate, addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); } From af0bbb4ee8edc6cdd34dc10432c460bdf4a702f3 Mon Sep 17 00:00:00 2001 From: Linh Date: Wed, 7 Jan 2026 09:12:54 +0700 Subject: [PATCH 15/24] test: test fail after merge main --- tests/actions/ReportTest.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 5b9a81e2c7175..9b351812b6bb3 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -1741,6 +1741,8 @@ describe('actions/Report', () => { const MENTIONED_USER_ACCOUNT_ID = 2; const MENTIONED_USER_LOGIN = 'bob@expensify.com'; const REPORT_ID = '1'; + const REPORT: OnyxTypes.Report = createRandomReport(1, undefined); + const TEN_MINUTES_AGO = subMinutes(new Date(), 10); const created = format(addSeconds(TEN_MINUTES_AGO, 10), CONST.DATE.FNS_DB_FORMAT_STRING); @@ -1756,7 +1758,7 @@ describe('actions/Report', () => { await Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}); - Report.addComment(REPORT_ID, REPORT_ID, [], 'Initial comment', CONST.DEFAULT_TIME_ZONE); + Report.addComment(REPORT, REPORT.reportID, [], 'Initial comment', CONST.DEFAULT_TIME_ZONE); // Get the reportActionID to edit and delete the comment const newComment = PersistedRequests.getAll().at(0); From 68900ba950dc7d94b6ec69c1a784e75e6fc53624 Mon Sep 17 00:00:00 2001 From: Linh Date: Thu, 8 Jan 2026 10:15:01 +0700 Subject: [PATCH 16/24] Update Mobile-Expensify submodule to match main --- Mobile-Expensify | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mobile-Expensify b/Mobile-Expensify index eaa9d84011667..f07d88ef1fe09 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit eaa9d84011667009c7581a44cd25519ecc7e795e +Subproject commit f07d88ef1fe09961a4f2785a31f335e2781df7ac From d56de90eb11843cf96f54bee9d3f1a3c6a44c649 Mon Sep 17 00:00:00 2001 From: Linh Date: Thu, 8 Jan 2026 10:19:22 +0700 Subject: [PATCH 17/24] chore: eslint fail --- tests/actions/ReportTest.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 074934bd55dd3..d71aaf0c69132 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -1002,7 +1002,6 @@ describe('actions/Report', () => { it('should remove AddComment and UpdateComment without sending any request when DeleteComment is set', async () => { global.fetch = TestHelper.getGlobalFetchMock(); - const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const REPORT: OnyxTypes.Report = createRandomReport(1, undefined); @@ -1118,7 +1117,6 @@ describe('actions/Report', () => { it('should send DeleteComment request and remove UpdateComment accordingly', async () => { global.fetch = TestHelper.getGlobalFetchMock(); - const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const REPORT: OnyxTypes.Report = createRandomReport(1, undefined); @@ -1697,7 +1695,6 @@ describe('actions/Report', () => { it('should update AddComment text with the UpdateComment text, sending just an AddComment request', async () => { global.fetch = TestHelper.getGlobalFetchMock(); - const TEST_USER_LOGIN = 'test@gmail.com'; const TEST_USER_ACCOUNT_ID = 1; const REPORT_ID = '1'; const REPORT: OnyxTypes.Report = createRandomReport(1, undefined); @@ -1736,7 +1733,6 @@ describe('actions/Report', () => { it('it should only send the last sequential UpdateComment request to BE', async () => { global.fetch = TestHelper.getGlobalFetchMock(); const reportID = '123'; - const TEST_USER_LOGIN = 'test@gmail.com'; await Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}); From 68f519ca239f079e1b18c05eedf1866fa1f5a101 Mon Sep 17 00:00:00 2001 From: Linh Date: Fri, 9 Jan 2026 09:45:58 +0700 Subject: [PATCH 18/24] chore: rename currentUserEmail to currentUserLogin --- src/components/Search/index.tsx | 12 ++++++------ src/libs/PolicyUtils.ts | 4 ++-- src/libs/ReportPreviewActionUtils.ts | 4 ++-- src/libs/ReportPrimaryActionUtils.ts | 4 ++-- src/libs/ReportSecondaryActionUtils.ts | 22 +++++++++++----------- src/libs/SearchUIUtils.ts | 6 +++--- src/libs/actions/Report.ts | 24 ++++++++++++------------ 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 92c0bc8ac3f7f..c6acbe104aada 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -95,11 +95,11 @@ function mapTransactionItemToSelectedEntry( item: TransactionListItemType, itemTransaction: OnyxEntry, originalItemTransaction: OnyxEntry, - currentUserEmail: string, + currentUserLogin: string, outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue, ): [string, SelectedTransactionInfo] { const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy); - const canRejectRequest = item.report ? canRejectReportAction(currentUserEmail, item.report, item.policy) : false; + const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false; return [ item.keyForList, { @@ -108,7 +108,7 @@ function mapTransactionItemToSelectedEntry( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserEmail, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, @@ -140,7 +140,7 @@ function prepareTransactionsList( itemTransaction: OnyxEntry, originalItemTransaction: OnyxEntry, selectedTransactions: SelectedTransactions, - currentUserEmail: string, + currentUserLogin: string, outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue, ) { if (selectedTransactions[item.keyForList]?.isSelected) { @@ -150,7 +150,7 @@ function prepareTransactionsList( } const {canHoldRequest, canUnholdRequest} = canHoldUnholdReportAction(item.report, item.reportAction, item.holdReportAction, item, item.policy); - const canRejectRequest = item.report ? canRejectReportAction(currentUserEmail, item.report, item.policy) : false; + const canRejectRequest = item.report ? canRejectReportAction(currentUserLogin, item.report, item.policy) : false; return { ...selectedTransactions, @@ -160,7 +160,7 @@ function prepareTransactionsList( canHold: canHoldRequest, isHeld: isOnHold(item), canUnhold: canUnholdRequest, - canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserEmail, item.policy), + canSplit: isSplitAction(item.report, [itemTransaction], originalItemTransaction, currentUserLogin, item.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( item.reportAction, diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index eed6b2772a876..3c90c63c4780c 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1612,7 +1612,7 @@ const getDescriptionForPolicyDomainCard = (domainName: string): string => { return domainName; }; -function isPreferredExporter(policy: Policy, currentUserEmail: string) { +function isPreferredExporter(policy: Policy, currentUserLogin: string) { const exporters = [ policy.connections?.intacct?.config?.export?.exporter, policy.connections?.netsuite?.options?.config?.exporter, @@ -1621,7 +1621,7 @@ function isPreferredExporter(policy: Policy, currentUserEmail: string) { policy.connections?.xero?.config?.export?.exporter, ]; - return exporters.some((exporter) => exporter && exporter === currentUserEmail); + return exporters.some((exporter) => exporter && exporter === currentUserLogin); } /** diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index c830b72af7487..65254ef7b9aee 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -135,9 +135,9 @@ function canPay(report: Report, isReportArchived: boolean, currentUserAccountID: return invoiceReceiverPolicy?.role === CONST.POLICY.ROLE.ADMIN && reimbursableSpend > 0; } -function canExport(report: Report, currentUserEmail: string, policy?: Policy) { +function canExport(report: Report, currentUserLogin: string, policy?: Policy) { const isExpense = isExpenseReport(report); - const isExporter = policy ? isPreferredExporter(policy, currentUserEmail) : false; + const isExporter = policy ? isPreferredExporter(policy, currentUserLogin) : false; const isReimbursed = isSettled(report); const isClosed = isClosedReport(report); const isApproved = isReportApproved({report}); diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index d15733cab4ba6..32262d0fc4208 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -212,7 +212,7 @@ function isPrimaryPayAction( return invoiceReceiverPolicy?.role === CONST.POLICY.ROLE.ADMIN && reimbursableSpend > 0; } -function isExportAction(report: Report, currentUserEmail: string, policy?: Policy, reportActions?: ReportAction[]) { +function isExportAction(report: Report, currentUserLogin: string, policy?: Policy, reportActions?: ReportAction[]) { if (!policy) { return false; } @@ -226,7 +226,7 @@ function isExportAction(report: Report, currentUserEmail: string, policy?: Polic const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const isReportExporter = isPreferredExporter(policy, currentUserEmail); + const isReportExporter = isPreferredExporter(policy, currentUserLogin); if (!isReportExporter && !isAdmin) { return false; } diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts index e244c6250613c..86c58197846a7 100644 --- a/src/libs/ReportSecondaryActionUtils.ts +++ b/src/libs/ReportSecondaryActionUtils.ts @@ -93,7 +93,7 @@ function isSplitAction( report: OnyxEntry, reportTransactions: Array>, originalTransaction: OnyxEntry, - currentUserEmail: string, + currentUserLogin: string, policy?: OnyxEntry, ): boolean { if (Number(reportTransactions?.length) !== 1 || !report) { @@ -134,7 +134,7 @@ function isSplitAction( const isManager = (report.managerID ?? CONST.DEFAULT_NUMBER_ID) === getCurrentUserAccountID(); const isOpenReport = isOpenReportUtils(report); const isPolicyExpenseChat = !!policy?.isPolicyExpenseChatEnabled; - const userIsPolicyMember = isPolicyMember(policy, currentUserEmail); + const userIsPolicyMember = isPolicyMember(policy, currentUserLogin); if (!(userIsPolicyMember && isPolicyExpenseChat)) { return false; @@ -763,7 +763,7 @@ function isDuplicateAction(report: Report, reportTransactions: Transaction[]): b } function getSecondaryReportActions({ - currentUserEmail, + currentUserEmail: currentUserLogin, currentUserAccountID, report, chatReport, @@ -799,7 +799,7 @@ function getSecondaryReportActions({ const didExportFail = !isExported && hasExportError; if ( - isPrimaryPayAction(report, currentUserAccountID, currentUserEmail, policy, reportNameValuePairs, isChatReportArchived, undefined, reportActions, true) && + isPrimaryPayAction(report, currentUserAccountID, currentUserLogin, policy, reportNameValuePairs, isChatReportArchived, undefined, reportActions, true) && (hasOnlyHeldExpenses(report?.reportID) || didExportFail) ) { options.push(CONST.REPORT.SECONDARY_ACTIONS.PAY); @@ -810,7 +810,7 @@ function getSecondaryReportActions({ } const primaryAction = getReportPrimaryAction({ - currentUserEmail, + currentUserEmail: currentUserLogin, currentUserAccountID, report, chatReport, @@ -834,22 +834,22 @@ function getSecondaryReportActions({ isChatReportArchived, primaryAction, violations, - currentUserEmail, + currentUserEmail: currentUserLogin, currentUserAccountID, }) ) { options.push(CONST.REPORT.SECONDARY_ACTIONS.SUBMIT); } - if (isApproveAction(currentUserEmail, report, reportTransactions, violations, policy)) { + if (isApproveAction(currentUserLogin, report, reportTransactions, violations, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.APPROVE); } - if (isUnapproveAction(currentUserEmail, report, policy)) { + if (isUnapproveAction(currentUserLogin, report, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.UNAPPROVE); } - if (isCancelPaymentAction(currentUserAccountID, currentUserEmail, report, reportTransactions, policy)) { + if (isCancelPaymentAction(currentUserAccountID, currentUserLogin, report, reportTransactions, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.CANCEL_PAYMENT); } @@ -869,11 +869,11 @@ function getSecondaryReportActions({ options.push(CONST.REPORT.SECONDARY_ACTIONS.REMOVE_HOLD); } - if (canRejectReportAction(currentUserEmail, report, policy)) { + if (canRejectReportAction(currentUserLogin, report, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.REJECT); } - if (isSplitAction(report, reportTransactions, originalTransaction, currentUserEmail, policy)) { + if (isSplitAction(report, reportTransactions, originalTransaction, currentUserLogin, policy)) { options.push(CONST.REPORT.SECONDARY_ACTIONS.SPLIT); } diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 783b7b0abecca..71a7c9006b5d3 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1381,7 +1381,7 @@ function getActions( allViolations: OnyxCollection, key: string, currentSearch: SearchKey, - currentUserEmail: string, + currentUserLogin: string, reportActions: OnyxTypes.ReportAction[] = [], ): SearchTransactionAction[] { const isTransaction = isTransactionEntry(key); @@ -1402,7 +1402,7 @@ function getActions( } const policy = getPolicyFromKey(data, report); - const isExportAvailable = isExportAction(report, currentUserEmail, policy, reportActions) && !isTransaction; + const isExportAvailable = isExportAction(report, currentUserLogin, policy, reportActions) && !isTransaction; if (isSettled(report) && !isExportAvailable) { return [CONST.SEARCH.ACTION_TYPES.PAID]; @@ -1477,7 +1477,7 @@ function getActions( } // We check for isAllowedToApproveExpenseReport because if the policy has preventSelfApprovals enabled, we disable the Submit action and in that case we want to show the View action instead - if (canSubmitReport(report, policy, allReportTransactions, allViolations, isIOUReportArchived || isChatReportArchived, currentUserEmail) && isAllowedToApproveExpenseReport) { + if (canSubmitReport(report, policy, allReportTransactions, allViolations, isIOUReportArchived || isChatReportArchived, currentUserLogin) && isAllowedToApproveExpenseReport) { allActions.push(CONST.SEARCH.ACTION_TYPES.SUBMIT); } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 9c95cf0597e84..dc4822e5aadcb 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -275,7 +275,7 @@ const addNewMessageWithText = new Set([WRITE_COMMANDS.ADD_COMMENT, WRITE let conciergeReportID: string | undefined; let deprecatedCurrentUserAccountID = -1; /** @deprecated This value is deprecated and will be removed soon after migration. Use the email from useCurrentUserPersonalDetails hook instead. */ -let deprecatedCurrentUserEmail: string | undefined; +let deprecatedCurrentUserLogin: string | undefined; Onyx.connect({ key: ONYXKEYS.SESSION, @@ -286,7 +286,7 @@ Onyx.connect({ return; } // eslint-disable-next-line @typescript-eslint/no-deprecated - deprecatedCurrentUserEmail = value.email; + deprecatedCurrentUserLogin = value.email; deprecatedCurrentUserAccountID = value.accountID; }, }); @@ -1075,7 +1075,7 @@ function openReport( transactionParentReportID === optimisticSelfDMReport?.reportID ? optimisticSelfDMReport : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionParentReportID}`]; const submitterAccountID = parentReport?.ownerAccountID ?? deprecatedCurrentUserAccountID; // eslint-disable-next-line @typescript-eslint/no-deprecated - const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? deprecatedCurrentUserEmail ?? ''; + const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? deprecatedCurrentUserLogin ?? ''; const submitterPersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(submitterEmail); const optimisticIOUAction = buildOptimisticIOUReportAction({ @@ -1203,7 +1203,7 @@ function openReport( if (isGroupChat) { parameters.chatType = CONST.REPORT.CHAT_TYPE.GROUP; // eslint-disable-next-line @typescript-eslint/no-deprecated - parameters.groupChatAdminLogins = deprecatedCurrentUserEmail; + parameters.groupChatAdminLogins = deprecatedCurrentUserLogin; parameters.optimisticAccountIDList = Object.keys(newReportObject?.participants ?? {}).join(','); parameters.reportName = newReportObject?.reportName ?? ''; @@ -1446,7 +1446,7 @@ function createTransactionThreadReport( optimisticTransactionThreadReportID, undefined, // eslint-disable-next-line @typescript-eslint/no-deprecated - deprecatedCurrentUserEmail ? [deprecatedCurrentUserEmail] : [], + deprecatedCurrentUserLogin ? [deprecatedCurrentUserLogin] : [], optimisticTransactionThread, iouReportAction?.reportActionID, false, @@ -2145,12 +2145,12 @@ function removeLinksFromHtml(html: string, links: string[]): string { * @param originalCommentMarkdown original markdown of the comment before editing. * @param videoAttributeCache cache of video attributes ([videoSource]: videoAttributes) */ -function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, currentUserEmail: string, videoAttributeCache?: Record): string { +function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMarkdown: string, currentUserLogin: string, videoAttributeCache?: Record): string { if (newCommentText.length > CONST.MAX_MARKUP_LENGTH) { return newCommentText; } - const userEmailDomain = isEmailPublicDomain(currentUserEmail) ? '' : Str.extractEmailDomain(currentUserEmail); + const userEmailDomain = isEmailPublicDomain(currentUserLogin) ? '' : Str.extractEmailDomain(currentUserLogin); const allPersonalDetailLogins = Object.values(allPersonalDetails ?? {}).map((personalDetail) => personalDetail?.login ?? ''); const htmlForNewComment = getParsedMessageWithShortMentions({ @@ -2174,7 +2174,7 @@ function editReportComment( textForNewComment: string, isOriginalReportArchived: boolean | undefined, isOriginalParentReportArchived: boolean | undefined, - currentUserEmail: string, + currentUserLogin: string, videoAttributeCache?: Record, ) { const originalReportID = originalReport?.reportID; @@ -2194,7 +2194,7 @@ function editReportComment( if (originalCommentMarkdown === textForNewComment) { return; } - const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, currentUserEmail, videoAttributeCache); + const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown, currentUserLogin, videoAttributeCache); const reportComment = Parser.htmlToText(htmlForNewComment); @@ -2208,7 +2208,7 @@ function editReportComment( // Delete the comment if it's empty if (!htmlForNewComment) { - deleteReportComment(originalReportID, originalReportAction, ancestors, isOriginalReportArchived, isOriginalParentReportArchived, currentUserEmail); + deleteReportComment(originalReportID, originalReportAction, ancestors, isOriginalReportArchived, isOriginalParentReportArchived, currentUserLogin); return; } @@ -4898,12 +4898,12 @@ function exportReportToPDF({reportID}: ExportReportPDFParams) { API.write(WRITE_COMMANDS.EXPORT_REPORT_TO_PDF, params, {optimisticData, failureData}); } -function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, currentUserEmail: string) { +function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate, currentUserLogin: string) { const baseURL = addTrailingForwardSlash(getOldDotURLFromEnvironment(environment)); const downloadFileName = `${reportName}.pdf`; setDownload(fileName, true); const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${encodeURIComponent(fileName)}&downloadName=${encodeURIComponent(downloadFileName)}&email=${encodeURIComponent( - currentUserEmail, + currentUserLogin, )}`; fileDownload(translate, addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); } From a56f33c43ce417e06bd0c110172e11ff7070fcd4 Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 05:46:24 +0700 Subject: [PATCH 19/24] chore: migrate email field to login --- src/components/MoneyReportHeader.tsx | 10 +- .../ReportActionItem/MoneyRequestView.tsx | 2 +- src/hooks/useSelectedTransactionsActions.ts | 6 +- src/hooks/useTodos.ts | 8 +- src/libs/ReportPrimaryActionUtils.ts | 4 +- src/libs/ReportSecondaryActionUtils.ts | 24 ++-- .../PrivateNotes/PrivateNotesEditPage.tsx | 4 +- .../iou/SplitExpenseCreateDateRagePage.tsx | 4 +- src/pages/iou/SplitExpenseEditPage.tsx | 4 +- tests/unit/ReportPrimaryActionUtilsTest.ts | 46 +++---- tests/unit/ReportSecondaryActionUtilsTest.ts | 124 +++++++++--------- 11 files changed, 118 insertions(+), 118 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index f0e99f80430da..911a6218549d0 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -761,7 +761,7 @@ function MoneyReportHeader({ const primaryAction = useMemo(() => { return getReportPrimaryAction({ - currentUserEmail: currentUserLogin ?? '', + currentUserLogin: currentUserLogin ?? '', currentUserAccountID: accountID, report: moneyRequestReport, chatReport, @@ -1070,7 +1070,7 @@ function MoneyReportHeader({ return []; } return getSecondaryReportActions({ - currentUserEmail: currentUserLogin ?? '', + currentUserLogin: currentUserLogin ?? '', currentUserAccountID: accountID, report: moneyRequestReport, chatReport, @@ -1513,9 +1513,9 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload || !canTriggerAutomaticPDFDownload.current) { return; } - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email ?? ''); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, currentUserLogin ?? ''); canTriggerAutomaticPDFDownload.current = false; - }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate, email]); + }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate, currentUserLogin]); const shouldShowBackButton = shouldDisplayBackButton || shouldUseNarrowLayout; @@ -1825,7 +1825,7 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload) { setIsPDFModalVisible(false); } else { - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, email ?? ''); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate, currentUserLogin ?? ''); } }} text={hasFinishedPDFDownload ? translate('common.download') : translate('common.cancel')} diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 0dcee12e18f66..32f50ff6fe80f 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -321,7 +321,7 @@ function MoneyRequestView({ const companyCardPageURL = `${environmentURL}/${ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(transactionThreadReport?.policyID)}`; const [originalTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transaction?.comment?.originalTransactionID)}`, {canBeMissing: true}); const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(transaction, originalTransaction); - const isSplitAvailable = moneyRequestReport && transaction && isSplitAction(moneyRequestReport, [transaction], originalTransaction, currentUserPersonalDetails.email ?? '', policy); + const isSplitAvailable = moneyRequestReport && transaction && isSplitAction(moneyRequestReport, [transaction], originalTransaction, currentUserPersonalDetails.login ?? '', policy); const canEditTaxFields = canEdit && !isDistanceRequest; const canEditAmount = diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index 99a7938243d3c..a824efe26de28 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -77,7 +77,7 @@ function useSelectedTransactionsActions({ const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(selectedTransactionIDs); const isReportArchived = useReportIsArchived(report?.reportID); const {deleteTransactions} = useDeleteTransactions({report, reportActions, policy}); - const {email} = useCurrentUserPersonalDetails(); + const {login} = useCurrentUserPersonalDetails(); const selectedTransactionsList = useMemo( () => selectedTransactionIDs.reduce((acc, transactionID) => { @@ -331,7 +331,7 @@ function useSelectedTransactionsActions({ const originalTransaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${firstTransaction?.comment?.originalTransactionID}`]; const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(firstTransaction, originalTransaction); - const canSplitTransaction = selectedTransactionsList.length === 1 && report && !isExpenseSplit && isSplitAction(report, [firstTransaction], originalTransaction, email ?? '', policy); + const canSplitTransaction = selectedTransactionsList.length === 1 && report && !isExpenseSplit && isSplitAction(report, [firstTransaction], originalTransaction, login ?? '', policy); if (canSplitTransaction) { options.push({ @@ -400,7 +400,7 @@ function useSelectedTransactionsActions({ expensifyIcons.Trashcan, localeCompare, isOnSearch, - email, + login ]); return { diff --git a/src/hooks/useTodos.ts b/src/hooks/useTodos.ts index 26b354e431483..12ff7f2c004c6 100644 --- a/src/hooks/useTodos.ts +++ b/src/hooks/useTodos.ts @@ -12,7 +12,7 @@ export default function useTodos() { const [allReportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, {canBeMissing: false}); const [allTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {canBeMissing: false}); const [allReportActions] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {canBeMissing: false}); - const {email = '', accountID} = useCurrentUserPersonalDetails(); + const {login = '', accountID} = useCurrentUserPersonalDetails(); return useMemo(() => { const reportsToSubmit: Report[] = []; @@ -50,14 +50,14 @@ export default function useTodos() { if (isApproveAction(report, reportTransactions, policy)) { reportsToApprove.push(report); } - if (isPrimaryPayAction(report, accountID, email, policy, reportNameValuePair)) { + if (isPrimaryPayAction(report, accountID, login, policy, reportNameValuePair)) { reportsToPay.push(report); } - if (isExportAction(report, email, policy, reportActions)) { + if (isExportAction(report, login, policy, reportActions)) { reportsToExport.push(report); } } return {reportsToSubmit, reportsToApprove, reportsToPay, reportsToExport}; - }, [allReports, allTransactions, allPolicies, allReportNameValuePairs, allReportActions, accountID, email]); + }, [allReports, allTransactions, allPolicies, allReportNameValuePairs, allReportActions, accountID, login]); } diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index 32262d0fc4208..3e2f48a0f071c 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -51,7 +51,7 @@ import { } from './TransactionUtils'; type GetReportPrimaryActionParams = { - currentUserEmail: string; + currentUserLogin: string; currentUserAccountID: number; report: Report | undefined; chatReport: OnyxEntry; @@ -398,7 +398,7 @@ function getAllExpensesToHoldIfApplicable(report: Report | undefined, reportActi function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf | '' { const { - currentUserEmail, + currentUserLogin, currentUserAccountID, report, reportTransactions, diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts index 86c58197846a7..db33099c9d470 100644 --- a/src/libs/ReportSecondaryActionUtils.ts +++ b/src/libs/ReportSecondaryActionUtils.ts @@ -427,7 +427,7 @@ function isExportAction(currentAccountID: number, currentUserEmail: string, repo return isAdmin && isReportFinished && syncEnabled; } -function isMarkAsExportedAction(currentAccountID: number, currentUserEmail: string, report: Report, policy?: Policy): boolean { +function isMarkAsExportedAction(currentAccountID: number, currentUserLogin: string, report: Report, policy?: Policy): boolean { if (!policy) { return false; } @@ -450,7 +450,7 @@ function isMarkAsExportedAction(currentAccountID: number, currentUserEmail: stri return false; } - const isReportPayer = isPayerUtils(currentAccountID, currentUserEmail, report, false, policy); + const isReportPayer = isPayerUtils(currentAccountID, currentUserLogin, report, false, policy); const arePaymentsEnabled = arePaymentsEnabledUtils(policy); const isReportApproved = isReportApprovedUtils({report}); const isReportClosed = isClosedReportUtils(report); @@ -471,7 +471,7 @@ function isMarkAsExportedAction(currentAccountID: number, currentUserEmail: stri const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const isExporter = isPreferredExporter(policy, currentUserEmail); + const isExporter = isPreferredExporter(policy, currentUserLogin); return (isAdmin && syncEnabled) || (isExporter && !syncEnabled); } @@ -763,7 +763,7 @@ function isDuplicateAction(report: Report, reportTransactions: Transaction[]): b } function getSecondaryReportActions({ - currentUserEmail: currentUserLogin, + currentUserLogin, currentUserAccountID, report, chatReport, @@ -777,7 +777,7 @@ function getSecondaryReportActions({ policies, isChatReportArchived = false, }: { - currentUserEmail: string; + currentUserLogin: string; currentUserAccountID: number; report: Report; chatReport: OnyxEntry; @@ -810,7 +810,7 @@ function getSecondaryReportActions({ } const primaryAction = getReportPrimaryAction({ - currentUserEmail: currentUserLogin, + currentUserLogin, currentUserAccountID, report, chatReport, @@ -913,17 +913,17 @@ function getSecondaryReportActions({ function getSecondaryExportReportActions( currentUserAccountID: number, - currentUserEmail: string, + currentUserLogin: string, report: Report, policy?: Policy, exportTemplates: ExportTemplate[] = [], ): Array> { const options: Array> = []; - if (isExportAction(currentUserAccountID, currentUserEmail, report, policy)) { + if (isExportAction(currentUserAccountID, currentUserLogin, report, policy)) { options.push(CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION); } - if (isMarkAsExportedAction(currentUserAccountID, currentUserEmail, report, policy)) { + if (isMarkAsExportedAction(currentUserAccountID, currentUserLogin, report, policy)) { options.push(CONST.REPORT.EXPORT_OPTIONS.MARK_AS_EXPORTED); } @@ -938,7 +938,7 @@ function getSecondaryExportReportActions( } function getSecondaryTransactionThreadActions( - currentUserEmail: string, + currentUserLogin: string, parentReport: Report, reportTransaction: Transaction, reportAction: ReportAction | undefined, @@ -956,11 +956,11 @@ function getSecondaryTransactionThreadActions( options.push(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REMOVE_HOLD); } - if (canRejectReportAction(currentUserEmail, parentReport, policy)) { + if (canRejectReportAction(currentUserLogin, parentReport, policy)) { options.push(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT); } - if (isSplitAction(parentReport, [reportTransaction], originalTransaction, currentUserEmail, policy)) { + if (isSplitAction(parentReport, [reportTransaction], originalTransaction, currentUserLogin, policy)) { options.push(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.SPLIT); } diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx index 5a7bf2a675b05..5d56e89db59ce 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx @@ -52,7 +52,7 @@ function PrivateNotesEditPageInternal({route, report, accountID, privateNoteDraf const styles = useThemeStyles(); const {translate} = useLocalize(); const personalDetailsList = usePersonalDetails(); - const {email} = useCurrentUserPersonalDetails(); + const {login} = useCurrentUserPersonalDetails(); // We need to edit the note in markdown format, but display it in HTML format const [privateNote, setPrivateNote] = useState(() => privateNoteDraft || Parser.htmlToMarkdown(report?.privateNotes?.[Number(route.params.accountID)]?.note ?? '').trim()); @@ -93,7 +93,7 @@ function PrivateNotesEditPageInternal({route, report, accountID, privateNoteDraf const originalNote = report?.privateNotes?.[Number(route.params.accountID)]?.note ?? ''; let editedNote = ''; if (privateNote.trim() !== originalNote.trim()) { - editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim(), email ?? '', undefined); + editedNote = handleUserDeletedLinksInHtml(privateNote.trim(), Parser.htmlToMarkdown(originalNote).trim(), login ?? '', undefined); updatePrivateNotes(report.reportID, Number(route.params.accountID), editedNote); } diff --git a/src/pages/iou/SplitExpenseCreateDateRagePage.tsx b/src/pages/iou/SplitExpenseCreateDateRagePage.tsx index eb4fe5658d6d8..8697340f705f2 100644 --- a/src/pages/iou/SplitExpenseCreateDateRagePage.tsx +++ b/src/pages/iou/SplitExpenseCreateDateRagePage.tsx @@ -52,14 +52,14 @@ function SplitExpenseCreateDateRagePage({route}: SplitExpenseCreateDateRagePageP const currentPolicy = Object.keys(policy?.employeeList ?? {}).length ? policy : currentSearchResults?.data?.[`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(currentReport?.policyID)}`]; - const {email} = useCurrentUserPersonalDetails(); + const {login} = useCurrentUserPersonalDetails(); const updateDate = (value: FormOnyxValues) => { resetSplitExpensesByDateRange(transaction, value[INPUT_IDS.START_DATE], value[INPUT_IDS.END_DATE]); Navigation.goBack(backTo); }; - const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, email ?? '', currentPolicy); + const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, login ?? '', currentPolicy); const validate = (values: FormOnyxValues) => { const errors: FormInputErrors = {}; diff --git a/src/pages/iou/SplitExpenseEditPage.tsx b/src/pages/iou/SplitExpenseEditPage.tsx index cfd3ecec07755..30263381c8554 100644 --- a/src/pages/iou/SplitExpenseEditPage.tsx +++ b/src/pages/iou/SplitExpenseEditPage.tsx @@ -72,7 +72,7 @@ function SplitExpenseEditPage({route}: SplitExpensePageProps) { const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${currentReport?.policyID}`, {canBeMissing: false}); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${currentReport?.policyID}`, {canBeMissing: false}); - const {email} = useCurrentUserPersonalDetails(); + const {login} = useCurrentUserPersonalDetails(); const fetchData = useCallback(() => { if (!policyCategories) { @@ -106,7 +106,7 @@ function SplitExpenseEditPage({route}: SplitExpensePageProps) { const transactionTag = getTag(splitExpenseDraftTransaction); const policyTagLists = useMemo(() => getTagLists(policyTags), [policyTags]); - const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, email ?? '', currentPolicy); + const isSplitAvailable = report && transaction && isSplitAction(currentReport, [transaction], originalTransaction, login ?? '', currentPolicy); const isCategoryRequired = !!currentPolicy?.requiresCategory; const reportName = computeReportName(currentReport); diff --git a/tests/unit/ReportPrimaryActionUtilsTest.ts b/tests/unit/ReportPrimaryActionUtilsTest.ts index 252b97c835353..611d1baff62ba 100644 --- a/tests/unit/ReportPrimaryActionUtilsTest.ts +++ b/tests/unit/ReportPrimaryActionUtilsTest.ts @@ -65,7 +65,7 @@ describe('getPrimaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -95,7 +95,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -129,7 +129,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -163,7 +163,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -198,7 +198,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -236,7 +236,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -272,7 +272,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -313,7 +313,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -355,7 +355,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -386,7 +386,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -425,7 +425,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -462,7 +462,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -499,7 +499,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -564,7 +564,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -622,7 +622,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -681,7 +681,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -721,7 +721,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -758,7 +758,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -796,7 +796,7 @@ describe('getPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -834,7 +834,7 @@ describe('getPrimaryAction', () => { // Then the getReportPrimaryAction should return the empty string expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport: invoiceChatReport, @@ -1093,7 +1093,7 @@ describe('getTransactionThreadPrimaryAction', () => { expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -1132,7 +1132,7 @@ describe('getTransactionThreadPrimaryAction', () => { } as unknown as Transaction; expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, @@ -1172,7 +1172,7 @@ describe('getTransactionThreadPrimaryAction', () => { } as unknown as Transaction; expect( getReportPrimaryAction({ - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, report, chatReport, diff --git a/tests/unit/ReportSecondaryActionUtilsTest.ts b/tests/unit/ReportSecondaryActionUtilsTest.ts index b5c672c406405..d21c4fc6a77cd 100644 --- a/tests/unit/ReportSecondaryActionUtilsTest.ts +++ b/tests/unit/ReportSecondaryActionUtilsTest.ts @@ -62,7 +62,7 @@ describe('getSecondaryAction', () => { const result = [CONST.REPORT.SECONDARY_ACTIONS.EXPORT, CONST.REPORT.SECONDARY_ACTIONS.DOWNLOAD_PDF, CONST.REPORT.SECONDARY_ACTIONS.VIEW_DETAILS]; expect( getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -95,7 +95,7 @@ describe('getSecondaryAction', () => { } as unknown as Transaction; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -125,7 +125,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -155,7 +155,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -199,7 +199,7 @@ describe('getSecondaryAction', () => { } as unknown as Transaction; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -229,7 +229,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -275,7 +275,7 @@ describe('getSecondaryAction', () => { jest.spyOn(ReportUtils, 'isHoldCreator').mockReturnValue(true); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -307,7 +307,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -345,7 +345,7 @@ describe('getSecondaryAction', () => { } as unknown as Transaction; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -389,7 +389,7 @@ describe('getSecondaryAction', () => { } as TransactionViolation; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -429,7 +429,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -466,7 +466,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -505,7 +505,7 @@ describe('getSecondaryAction', () => { } as unknown as TransactionViolation; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -544,7 +544,7 @@ describe('getSecondaryAction', () => { } as unknown as TransactionViolation; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -580,7 +580,7 @@ describe('getSecondaryAction', () => { } as unknown as TransactionViolation; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -616,7 +616,7 @@ describe('getSecondaryAction', () => { } as unknown as TransactionViolation; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -649,7 +649,7 @@ describe('getSecondaryAction', () => { } as unknown as Transaction; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -673,7 +673,7 @@ describe('getSecondaryAction', () => { const policy = {approver: EMPLOYEE_EMAIL} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -700,7 +700,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -726,7 +726,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -752,7 +752,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -779,7 +779,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -806,7 +806,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -834,7 +834,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -862,7 +862,7 @@ describe('getSecondaryAction', () => { } as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -905,7 +905,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${REPORT_ID}`, {[ACTION_ID]: reportAction}); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -952,7 +952,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${REPORT_ID}`, {[ACTION_ID]: reportAction}); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -999,7 +999,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${REPORT_ID}`, {[ACTION_ID]: reportAction}); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1046,7 +1046,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${REPORT_ID}`, {[ACTION_ID]: reportAction}); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1080,7 +1080,7 @@ describe('getSecondaryAction', () => { jest.spyOn(ReportUtils, 'canHoldUnholdReportAction').mockReturnValueOnce({canHoldRequest: true, canUnholdRequest: true}); jest.spyOn(ReportActionsUtils, 'getOneTransactionThreadReportID').mockReturnValueOnce(originalMessageR14932.IOUTransactionID); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1123,7 +1123,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1167,7 +1167,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1226,7 +1226,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1285,7 +1285,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1344,7 +1344,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1369,7 +1369,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1432,7 +1432,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1476,7 +1476,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1535,7 +1535,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1579,7 +1579,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1628,7 +1628,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1668,7 +1668,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1704,7 +1704,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1755,7 +1755,7 @@ describe('getSecondaryAction', () => { // Then it should return false since the unreported card expense is imported with deleting disabled const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1797,7 +1797,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1826,7 +1826,7 @@ describe('getSecondaryAction', () => { jest.spyOn(ReportUtils, 'isHoldCreator').mockReturnValue(false); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1859,7 +1859,7 @@ describe('getSecondaryAction', () => { jest.spyOn(ReportUtils, 'isHoldCreator').mockReturnValue(false); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1902,7 +1902,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1932,7 +1932,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -1990,7 +1990,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2030,7 +2030,7 @@ describe('getSecondaryAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2073,7 +2073,7 @@ describe('getSecondaryAction', () => { const policy = {} as unknown as Policy; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2338,7 +2338,7 @@ describe('getSecondaryExportReportActions', () => { jest.spyOn(ReportUtils, 'isHoldCreator').mockReturnValue(false); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2468,7 +2468,7 @@ describe('getSecondaryTransactionThreadActions', () => { await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, personalDetails); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2636,7 +2636,7 @@ describe('getSecondaryTransactionThreadActions', () => { jest.spyOn(ReportUtils, 'isMoneyRequestReportEligibleForMerge').mockReturnValue(true); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport: undefined, @@ -2688,7 +2688,7 @@ describe('getSecondaryTransactionThreadActions', () => { jest.spyOn(ReportUtils, 'isMoneyRequestReportEligibleForMerge').mockReturnValue(true); const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport: undefined, @@ -2711,7 +2711,7 @@ describe('getSecondaryTransactionThreadActions', () => { const transactions = [{transactionID: '1'} as unknown as Transaction, {transactionID: '2'} as unknown as Transaction]; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2731,7 +2731,7 @@ describe('getSecondaryTransactionThreadActions', () => { const transactions = [{transactionID: '1'} as unknown as Transaction, {transactionID: '2'} as unknown as Transaction]; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2751,7 +2751,7 @@ describe('getSecondaryTransactionThreadActions', () => { const transactions = [{transactionID: '1'} as unknown as Transaction]; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2770,7 +2770,7 @@ describe('getSecondaryTransactionThreadActions', () => { } as unknown as Report; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2790,7 +2790,7 @@ describe('getSecondaryTransactionThreadActions', () => { const transactions = [{transactionID: '1'} as unknown as Transaction, {transactionID: '2'} as unknown as Transaction]; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, @@ -2810,7 +2810,7 @@ describe('getSecondaryTransactionThreadActions', () => { const transactions = [{transactionID: '1'} as unknown as Transaction, {transactionID: '2'} as unknown as Transaction, {transactionID: '3'} as unknown as Transaction]; const result = getSecondaryReportActions({ - currentUserEmail: EMPLOYEE_EMAIL, + currentUserLogin: EMPLOYEE_EMAIL, currentUserAccountID: EMPLOYEE_ACCOUNT_ID, report, chatReport, From af76efb09b2cc4e9d4e598e0219202d2d9868a87 Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 05:50:33 +0700 Subject: [PATCH 20/24] chore: migrate email field to login --- src/hooks/useSelectedTransactionsActions.ts | 2 +- src/libs/ReportPrimaryActionUtils.ts | 14 +++++++------- src/pages/iou/SplitExpensePage.tsx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hooks/useSelectedTransactionsActions.ts b/src/hooks/useSelectedTransactionsActions.ts index a824efe26de28..eabd1dd0aa247 100644 --- a/src/hooks/useSelectedTransactionsActions.ts +++ b/src/hooks/useSelectedTransactionsActions.ts @@ -400,7 +400,7 @@ function useSelectedTransactionsActions({ expensifyIcons.Trashcan, localeCompare, isOnSearch, - login + login, ]); return { diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index 3e2f48a0f071c..689d3ae8c3743 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -428,15 +428,15 @@ function getReportPrimaryAction(params: GetReportPrimaryActionParams): ValueOf>(() => getTransactionDetails(transaction) ?? {}, [transaction]); const transactionDetailsAmount = transactionDetails?.amount ?? 0; From 6c12a49cb7c8f6c04346c2d28cfdc20e22ee94c0 Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 05:57:47 +0700 Subject: [PATCH 21/24] chore: migrate email field to login --- .../MoneyRequestReportPreviewContent.tsx | 2 +- src/libs/ReportPreviewActionUtils.ts | 10 ++--- src/libs/ReportSecondaryActionUtils.ts | 10 ++--- tests/actions/ReportPreviewActionUtilsTest.ts | 38 +++++++++---------- tests/actions/ReportTest.ts | 2 +- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx index 877f10778e8a4..369b025fecf10 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx @@ -570,7 +570,7 @@ function MoneyRequestReportPreviewContent({ return getReportPreviewAction({ isReportArchived: isIouReportArchived || isChatReportArchived, currentUserAccountID: currentUserDetails.accountID, - currentUserEmail: currentUserDetails.email ?? '', + currentUserLogin: currentUserDetails.login ?? '', report: iouReport, policy, transactions, diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index 65254ef7b9aee..1214fd4d6809a 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -168,7 +168,7 @@ function canExport(report: Report, currentUserLogin: string, policy?: Policy) { function getReportPreviewAction({ isReportArchived, currentUserAccountID, - currentUserEmail, + currentUserLogin, report, policy, transactions, @@ -181,7 +181,7 @@ function getReportPreviewAction({ }: { isReportArchived: boolean; currentUserAccountID: number; - currentUserEmail: string; + currentUserLogin: string; report: Report | undefined; policy: Policy | undefined; transactions: Transaction[]; @@ -213,16 +213,16 @@ function getReportPreviewAction({ return CONST.REPORT.REPORT_PREVIEW_ACTIONS.VIEW; } - if (canSubmit(report, isReportArchived, currentUserAccountID, currentUserEmail, violationsData, policy, transactions)) { + if (canSubmit(report, isReportArchived, currentUserAccountID, currentUserLogin, violationsData, policy, transactions)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.SUBMIT; } if (canApprove(report, currentUserAccountID, policy, transactions)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.APPROVE; } - if (canPay(report, isReportArchived, currentUserAccountID, currentUserEmail, policy, invoiceReceiverPolicy)) { + if (canPay(report, isReportArchived, currentUserAccountID, currentUserLogin, policy, invoiceReceiverPolicy)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.PAY; } - if (canExport(report, currentUserEmail, policy)) { + if (canExport(report, currentUserLogin, policy)) { return CONST.REPORT.REPORT_PREVIEW_ACTIONS.EXPORT_TO_ACCOUNTING; } diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts index db33099c9d470..91cf012784b02 100644 --- a/src/libs/ReportSecondaryActionUtils.ts +++ b/src/libs/ReportSecondaryActionUtils.ts @@ -158,7 +158,7 @@ function isSubmitAction({ isChatReportArchived = false, primaryAction, violations, - currentUserEmail, + currentUserLogin, currentUserAccountID, }: { report: Report; @@ -170,7 +170,7 @@ function isSubmitAction({ isChatReportArchived?: boolean; primaryAction?: ValueOf | ''; violations?: OnyxCollection; - currentUserEmail?: string; + currentUserLogin?: string; currentUserAccountID?: number; }): boolean { if (isArchivedReport(reportNameValuePairs) || isChatReportArchived) { @@ -193,8 +193,8 @@ function isSubmitAction({ return false; } - if (violations && currentUserEmail && currentUserAccountID !== undefined) { - if (reportTransactions.some((transaction) => hasSmartScanFailedViolation(transaction, violations, currentUserEmail, currentUserAccountID, report, policy))) { + if (violations && currentUserLogin && currentUserAccountID !== undefined) { + if (reportTransactions.some((transaction) => hasSmartScanFailedViolation(transaction, violations, currentUserLogin, currentUserAccountID, report, policy))) { return false; } } @@ -834,7 +834,7 @@ function getSecondaryReportActions({ isChatReportArchived, primaryAction, violations, - currentUserEmail: currentUserLogin, + currentUserLogin, currentUserAccountID, }) ) { diff --git a/tests/actions/ReportPreviewActionUtilsTest.ts b/tests/actions/ReportPreviewActionUtilsTest.ts index 2a99e36a3d04c..f29c113b39ac6 100644 --- a/tests/actions/ReportPreviewActionUtilsTest.ts +++ b/tests/actions/ReportPreviewActionUtilsTest.ts @@ -71,7 +71,7 @@ describe('getReportPreviewAction', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report); const policy = createRandomPolicy(0, CONST.POLICY.TYPE.PERSONAL); - expect(getReportPreviewAction({isReportArchived: false, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, currentUserEmail: CURRENT_USER_EMAIL, report, policy, transactions: []})).toBe( + expect(getReportPreviewAction({isReportArchived: false, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: []})).toBe( CONST.REPORT.REPORT_PREVIEW_ACTIONS.ADD_EXPENSE, ); }); @@ -109,7 +109,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -151,7 +151,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -193,7 +193,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -244,7 +244,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -290,7 +290,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -327,7 +327,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: false, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -365,7 +365,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: false, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -405,7 +405,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -439,7 +439,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -474,7 +474,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: false, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -512,7 +512,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -567,7 +567,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -610,7 +610,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -648,7 +648,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isChatReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -681,7 +681,7 @@ describe('getReportPreviewAction', () => { getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: CURRENT_USER_EMAIL, + currentUserLogin: CURRENT_USER_EMAIL, report, policy, transactions: [transaction], @@ -715,7 +715,7 @@ describe('getReportPreviewAction', () => { const result = getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: '', + currentUserLogin: '', report, policy, transactions: [transaction], @@ -759,7 +759,7 @@ describe('getReportPreviewAction', () => { const result = getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: '', + currentUserLogin: '', report, policy, transactions: [transaction], @@ -803,7 +803,7 @@ describe('getReportPreviewAction', () => { const result = getReportPreviewAction({ isReportArchived: isReportArchived.current, currentUserAccountID: CURRENT_USER_ACCOUNT_ID, - currentUserEmail: '', + currentUserLogin: '', report, policy, transactions: [transaction], diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index d71aaf0c69132..37875ec3960bb 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -1827,7 +1827,7 @@ describe('actions/Report', () => { await waitForBatchedUpdates(); }); - it('it should only send the last sequential UpdateComment request to BE with currentUserEmail', async () => { + it('it should only send the last sequential UpdateComment request to BE with currentUserLogin', async () => { global.fetch = TestHelper.getGlobalFetchMock(); await Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}); From c4e9016e2714a5258fcabd5094571644c9b0a033 Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 06:09:57 +0700 Subject: [PATCH 22/24] chore: add login to deps --- .../MoneyRequestReportPreviewContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx index 0d2faf65df8dd..1a83aff84b923 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx @@ -542,7 +542,7 @@ function MoneyRequestReportPreviewContent({ isIouReportArchived, isChatReportArchived, currentUserDetails.accountID, - currentUserDetails.email, + currentUserDetails.login, iouReport, policy, transactions, From fa3a028f0f016e025b5ccf57aaf6a6b0bf9431c9 Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 06:14:29 +0700 Subject: [PATCH 23/24] chore: migrate email field to login --- src/components/Search/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index aeb4a2d422b8d..0dd71cc58cbb3 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -244,7 +244,7 @@ function Search({ const [reportActions] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {canBeMissing: true}); const [outstandingReportsByPolicyID] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID, {canBeMissing: true}); const [violations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); - const {accountID, email} = useCurrentUserPersonalDetails(); + const {accountID, email,login} = useCurrentUserPersonalDetails(); const [isActionLoadingSet = new Set()] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}`, {canBeMissing: true, selector: isActionLoadingSetSelector}); const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true, selector: columnsSelector}); const [customCardNames] = useOnyx(ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES, {canBeMissing: true}); @@ -519,7 +519,7 @@ function Search({ canHold: canHoldRequest, isHeld: isOnHold(transactionItem), canUnhold: canUnholdRequest, - canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, email ?? '', transactionItem.policy), + canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, login ?? '', transactionItem.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( transactionItem.reportAction, @@ -572,7 +572,7 @@ function Search({ canHold: canHoldRequest, isHeld: isOnHold(transactionItem), canUnhold: canUnholdRequest, - canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, email ?? '', transactionItem.policy), + canSplit: isSplitAction(transactionItem.report, [itemTransaction], originalItemTransaction, login ?? '', transactionItem.policy), hasBeenSplit: getOriginalTransactionWithSplitInfo(itemTransaction, originalItemTransaction).isExpenseSplit, canChangeReport: canEditFieldOfMoneyRequest( transactionItem.reportAction, From fb6340b91ad6d3e43aa466d71c426049a0c3d6dc Mon Sep 17 00:00:00 2001 From: Linh Date: Sat, 10 Jan 2026 06:18:03 +0700 Subject: [PATCH 24/24] chore: migrate email field to login --- src/components/Search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 0dd71cc58cbb3..43d4f81606ce1 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -244,7 +244,7 @@ function Search({ const [reportActions] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {canBeMissing: true}); const [outstandingReportsByPolicyID] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID, {canBeMissing: true}); const [violations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true}); - const {accountID, email,login} = useCurrentUserPersonalDetails(); + const {accountID, email, login} = useCurrentUserPersonalDetails(); const [isActionLoadingSet = new Set()] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}`, {canBeMissing: true, selector: isActionLoadingSetSelector}); const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true, selector: columnsSelector}); const [customCardNames] = useOnyx(ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES, {canBeMissing: true});