Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
61b7e0e
refactor: Remove deprecated report name functions in ReportUtils
mohammadjafarinejad Mar 7, 2026
4f08930
refactor: pass report attributes to getReportName calls
mohammadjafarinejad Mar 7, 2026
8cec2a8
refactor: add reportAttributes to notification functions
mohammadjafarinejad Mar 7, 2026
44f6262
refactor: pass reportAttributes to getShareDestination function
mohammadjafarinejad Mar 7, 2026
677c770
refactor: integrate reportAttributes into SearchAutocompleteList, use…
mohammadjafarinejad Mar 7, 2026
775a1dc
Merge branch 'main' into fix/76852-part4
mohammadjafarinejad Mar 11, 2026
6ef9cfc
refactor: pass reportAttributes to user event subscription
mohammadjafarinejad Mar 11, 2026
c65fd64
fix: handle optional getReportAttributes in user event subscription
mohammadjafarinejad Mar 11, 2026
18ba6af
Merge branch 'main' into fix/76852-part4
mohammadjafarinejad Mar 13, 2026
3c08df4
Refactor showCommentNotification signature to remove unnecessary para…
mohammadjafarinejad Mar 13, 2026
54b08ff
Remove unnecessary parameter from showCommentNotification call
mohammadjafarinejad Mar 14, 2026
e970f05
Merge branch 'main' into fix/76852-part4
mohammadjafarinejad Mar 14, 2026
9670e1c
Refactor: Remove conciergeReportID parameter from multiple functions …
mohammadjafarinejad Mar 14, 2026
2e5a5c4
Merge branch 'main' into fix/76852-part4
mohammadjafarinejad Mar 19, 2026
5c616b8
fix: Remove 'concierge-report-id' parameter from buildSubstitutionsMa…
mohammadjafarinejad Mar 19, 2026
7789270
Merge branch 'main' into fix/76852-part4
sosek108 Mar 20, 2026
a2128a7
Merge branch 'main' into fix/76852-part4
sosek108 Mar 20, 2026
71121b9
fixes after merge from main
sosek108 Mar 20, 2026
5f92362
tests fixes after merge from main
sosek108 Mar 20, 2026
ab309a5
lint fixes
sosek108 Mar 20, 2026
c9664ac
lint fixes
sosek108 Mar 20, 2026
4dc7758
lint fixes
sosek108 Mar 20, 2026
81457a0
lint and typecheck fixes
sosek108 Mar 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportU
import Navigation from '@libs/Navigation/Navigation';
import {getConnectedIntegration, hasDynamicExternalWorkflow} from '@libs/PolicyUtils';
import {hasPendingDEWSubmit} from '@libs/ReportActionsUtils';
import {getInvoicePayerName} from '@libs/ReportNameUtils';
import {getInvoicePayerName, getReportName} from '@libs/ReportNameUtils';
import getReportPreviewAction from '@libs/ReportPreviewActionUtils';
import {
areAllRequestsBeingSmartScanned as areAllRequestsBeingSmartScannedReportUtils,
Expand All @@ -59,7 +59,6 @@ import {
getMoneyRequestSpendBreakdown,
getNonHeldAndFullAmount,
getPolicyName,
getReportName,
getReportStatusColorStyle,
getReportStatusTranslation,
getTransactionsWithReceipts,
Expand Down Expand Up @@ -927,9 +926,7 @@ function MoneyRequestReportPreviewContent({
style={[styles.headerText]}
testID="MoneyRequestReportPreview-reportName"
>
{/* This will be fixed as follow up https://github.com/Expensify/App/pull/75357 */}
{/* eslint-disable-next-line @typescript-eslint/no-deprecated */}
{getReportName({report: iouReport, reportAttributes}) || action.childReportName}
{getReportName(iouReport, reportAttributes) || action.childReportName}
</Text>
</Animated.View>
</View>
Expand Down
5 changes: 3 additions & 2 deletions src/components/Search/SearchAutocompleteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import useFeedKeysWithAssignedCards from '@hooks/useFeedKeysWithAssignedCards';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useReportAttributes from '@hooks/useReportAttributes';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import FS from '@libs/Fullstory';
Expand Down Expand Up @@ -150,6 +151,7 @@ function SearchAutocompleteList({

const [betas] = useOnyx(ONYXKEYS.BETAS);
const feedKeysWithCards = useFeedKeysWithAssignedCards();
const reportAttributes = useReportAttributes();
const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT);
const [nvpDismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING);
const [recentSearches, recentSearchesMetadata] = useOnyx(ONYXKEYS.RECENT_SEARCHES);
Expand All @@ -160,7 +162,6 @@ function SearchAutocompleteList({
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const currentUserEmail = currentUserPersonalDetails.email ?? '';
const currentUserAccountID = currentUserPersonalDetails.accountID;
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const expensifyIcons = useMemoizedLazyExpensifyIcons(['History', 'MagnifyingGlass']);
const taxRates = getAllTaxRates(policies);

Expand Down Expand Up @@ -311,7 +312,7 @@ function SearchAutocompleteList({
autoCompleteWithSpace: false,
translate,
feedKeysWithCards,
conciergeReportID,
reportAttributes,
})
: query,
singleIcon: expensifyIcons.History,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import useFeedKeysWithAssignedCards from '@hooks/useFeedKeysWithAssignedCards';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useReportAttributes from '@hooks/useReportAttributes';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down Expand Up @@ -64,13 +65,13 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo
const personalDetails = usePersonalDetails();
const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT);
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
const reportAttributes = useReportAttributes();
const taxRates = useMemo(() => getAllTaxRates(policies), [policies]);
const [personalAndWorkspaceCards] = useOnyx(ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST);
const [allFeeds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER);
const feedKeysWithCards = useFeedKeysWithAssignedCards();
const {inputQuery: originalInputQuery} = queryJSON;
const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [betas] = useOnyx(ONYXKEYS.BETAS);
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
Expand All @@ -86,7 +87,7 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo
autoCompleteWithSpace: true,
translate,
feedKeysWithCards,
conciergeReportID,
reportAttributes,
});

const [searchContext] = useOnyx(ONYXKEYS.SEARCH_CONTEXT);
Expand Down Expand Up @@ -144,10 +145,10 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo
policies,
currentUserAccountID,
translate,
conciergeReportID,
reportAttributes,
);
setAutocompleteSubstitutions(substitutionsMap);
}, [allFeeds, personalAndWorkspaceCards, originalInputQuery, personalDetails, reports, taxRates, policies, currentUserAccountID, translate, conciergeReportID]);
}, [allFeeds, personalAndWorkspaceCards, originalInputQuery, personalDetails, reports, taxRates, policies, currentUserAccountID, translate, reportAttributes]);

useEffect(() => {
if (searchRouterListVisible) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Search/SearchRouter/buildSubstitutionsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {SearchAutocompleteQueryRange, SearchFilterKey} from '@components/Se
import {parse} from '@libs/SearchParser/autocompleteParser';
import {getFilterDisplayValue} from '@libs/SearchQueryUtils';
import CONST from '@src/CONST';
import type {CardFeeds, CardList, PersonalDetailsList, Policy, Report} from '@src/types/onyx';
import type {CardFeeds, CardList, PersonalDetailsList, Policy, Report, ReportAttributesDerivedValue} from '@src/types/onyx';
import type {SubstitutionMap} from './getQueryWithSubstitutions';

const getSubstitutionsKey = (filterKey: SearchFilterKey, value: string) => `${filterKey}:${value}`;
Expand Down Expand Up @@ -35,7 +35,7 @@ function buildSubstitutionsMap(
policies: OnyxCollection<Policy>,
currentUserAccountID: number,
translate: LocalizedTranslate,
conciergeReportID: string | undefined,
reportAttributes?: ReportAttributesDerivedValue['reports'],
): SubstitutionMap {
const parsedQuery = parse(query) as {ranges: SearchAutocompleteQueryRange[]};

Expand Down Expand Up @@ -84,7 +84,7 @@ function buildSubstitutionsMap(
policies,
currentUserAccountID,
translate,
conciergeReportID,
reportAttributes,
});

// If displayValue === filterValue, then it means there is nothing to substitute, so we don't add any key to map
Expand Down
9 changes: 5 additions & 4 deletions src/hooks/useSearchTypeMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import useFeedKeysWithAssignedCards from './useFeedKeysWithAssignedCards';
import {useMemoizedLazyExpensifyIcons} from './useLazyAsset';
import useLocalize from './useLocalize';
import useOnyx from './useOnyx';
import useReportAttributes from './useReportAttributes';
import useSearchTypeMenuSections from './useSearchTypeMenuSections';
import useSingleExecution from './useSingleExecution';
import useTheme from './useTheme';
Expand All @@ -45,7 +46,6 @@ export default function useSearchTypeMenu(queryJSON: SearchQueryJSON) {
const taxRates = getAllTaxRates(allPolicies);
const [personalAndWorkspaceCards] = useOnyx(ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST);
const [savedSearches] = useOnyx(ONYXKEYS.SAVED_SEARCHES);
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
const [reportCounts = CONST.EMPTY_TODOS_REPORT_COUNTS] = useOnyx(ONYXKEYS.DERIVED.TODOS, {selector: todosReportCountsSelector});
const expensifyIcons = useMemoizedLazyExpensifyIcons([
Expand All @@ -70,6 +70,7 @@ export default function useSearchTypeMenu(queryJSON: SearchQueryJSON) {

const [allFeeds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER);
const feedKeysWithCards = useFeedKeysWithAssignedCards();
const reportAttributes = useReportAttributes();
const flattenedMenuItems = useMemo(() => typeMenuSections.flatMap((section) => section.menuItems), [typeMenuSections]);

// this is a performance fix, rendering popover menu takes a lot of time and we don't need this component initially, that's why we postpone rendering it until everything else is rendered
Expand Down Expand Up @@ -116,7 +117,7 @@ export default function useSearchTypeMenu(queryJSON: SearchQueryJSON) {
autoCompleteWithSpace: false,
translate,
feedKeysWithCards,
conciergeReportID,
reportAttributes,
});
}

Expand Down Expand Up @@ -166,11 +167,11 @@ export default function useSearchTypeMenu(queryJSON: SearchQueryJSON) {
taxRates,
personalAndWorkspaceCards,
allFeeds,
feedKeysWithCards,
allPolicies,
currentUserAccountID,
translate,
conciergeReportID,
feedKeysWithCards,
reportAttributes,
]);

const activeItemIndex = useMemo(() => {
Expand Down
19 changes: 8 additions & 11 deletions src/libs/ModifiedExpenseMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {Entries, ValueOf} from 'type-fest';
import type {LocalizedTranslate} from '@components/LocaleContextProvider';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {Policy, PolicyTagLists, Report, ReportAction} from '@src/types/onyx';
import type {Policy, PolicyTagLists, Report, ReportAction, ReportAttributesDerivedValue} from '@src/types/onyx';
import type {PersonalRulesModifiedFields, PolicyRulesModifiedFields} from '@src/types/onyx/OriginalMessage';
import ObjectUtils from '@src/types/utils/ObjectUtils';
import {getDecodedCategoryName, isCategoryMissing} from './CategoryUtils';
Expand All @@ -21,9 +21,9 @@ import {getOriginalMessage, isModifiedExpenseAction} from './ReportActionsUtils'
// The functions imported here are pure utility functions that don't create initialization-time dependencies.
// ReportNameUtils imports helper functions from ReportUtils, and ReportUtils imports name generation functions from ReportNameUtils.
// eslint-disable-next-line import/no-cycle
import {buildReportNameFromParticipantNames, getPolicyExpenseChatName} from './ReportNameUtils';
import {buildReportNameFromParticipantNames, getPolicyExpenseChatName, getReportName} from './ReportNameUtils';
// eslint-disable-next-line import/no-cycle
import {getPolicyName, getReportName, getRootParentReport, isPolicyExpenseChat, isSelfDM} from './ReportUtils';
import {getPolicyName, getRootParentReport, isPolicyExpenseChat, isSelfDM} from './ReportUtils';
import {getFormattedAttendees, getTagArrayFromName} from './TransactionUtils';
import {isInvalidMerchantValue} from './ValidationUtils';

Expand Down Expand Up @@ -165,16 +165,14 @@ function getMovedFromOrToReportMessage(
movedFromReport: OnyxEntry<Report> | undefined,
movedToReport: OnyxEntry<Report> | undefined,
currentUserLogin: string,
// TODO: This will be required eventually. Refactor issue: https://github.com/Expensify/App/issues/66411
conciergeReportID?: string,
reportAttributes?: ReportAttributesDerivedValue['reports'],
): string | undefined {
if (movedToReport) {
return getForExpenseMovedFromSelfDM(translate, movedToReport, currentUserLogin);
}

if (movedFromReport) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const originReportName = getReportName({report: movedFromReport, conciergeReportID});
const originReportName = getReportName(movedFromReport, reportAttributes);
return translate('iou.movedFromReport', originReportName ?? '');
}
}
Expand Down Expand Up @@ -253,7 +251,7 @@ function getForReportAction({
movedToReport,
policyTags,
currentUserLogin,
conciergeReportID,
reportAttributes,
}: {
translate: LocalizedTranslate;
reportAction: OnyxEntry<ReportAction>;
Expand All @@ -265,14 +263,13 @@ function getForReportAction({
// See https://github.com/Expensify/App/pull/75562
policyTags?: OnyxEntry<PolicyTagLists>;
currentUserLogin: string;
// TODO: This will be required eventually. Refactor issue: https://github.com/Expensify/App/issues/66411
conciergeReportID?: string;
reportAttributes?: ReportAttributesDerivedValue['reports'];
}): string {
if (!isModifiedExpenseAction(reportAction)) {
return '';
}

const movedFromOrToReportMessage = getMovedFromOrToReportMessage(translate, movedFromReport, movedToReport, currentUserLogin, conciergeReportID);
const movedFromOrToReportMessage = getMovedFromOrToReportMessage(translate, movedFromReport, movedToReport, currentUserLogin, reportAttributes);
if (movedFromOrToReportMessage) {
return movedFromOrToReportMessage;
}
Expand Down
23 changes: 13 additions & 10 deletions src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {useEffect, useRef} from 'react';
import {useInitialURLActions, useInitialURLState} from '@components/InitialURLContextProvider';
import useHasActiveAdminPolicies from '@hooks/useHasActiveAdminPolicies';
import useOnyx from '@hooks/useOnyx';
import useReportAttributes from '@hooks/useReportAttributes';
import {init, isClientTheLeader} from '@libs/ActiveClientManager';
import Log from '@libs/Log';
import getCurrentUrl from '@libs/Navigation/currentUrl';
Expand All @@ -23,15 +24,15 @@ import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
import type {ReportAttributesDerivedValue} from '@src/types/onyx';

function initializePusher(conciergeReportID: string | undefined, currentUserAccountID?: number) {
function initializePusher(currentUserAccountID?: number, getReportAttributes?: () => ReportAttributesDerivedValue['reports'] | undefined) {
return Pusher.init({
appKey: CONFIG.PUSHER.APP_KEY,
cluster: CONFIG.PUSHER.CLUSTER,
authEndpoint: `${CONFIG.EXPENSIFY.DEFAULT_API_ROOT}api/AuthenticatePusher?`,
}).then(() => {
User.subscribeToUserEvents(currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID, conciergeReportID);
User.subscribeToUserEvents(currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID, getReportAttributes);
});
}

Expand Down Expand Up @@ -60,13 +61,17 @@ function AuthScreensInitHandler() {

const [lastUpdateIDAppliedToClient] = useOnyx(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT);
const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP);
const [conciergeReportID, conciergeReportIDMetadata] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const lastUpdateIDAppliedToClientRef = useRef(lastUpdateIDAppliedToClient);
const isLoadingAppRef = useRef(isLoadingApp);

lastUpdateIDAppliedToClientRef.current = lastUpdateIDAppliedToClient;
isLoadingAppRef.current = isLoadingApp;

const reportAttributes = useReportAttributes();
// We use a ref so the Pusher callback (registered once on mount) always reads the latest value without re-subscribing.
const reportAttributesRef = useRef(reportAttributes);
reportAttributesRef.current = reportAttributes;

const handleNetworkReconnect = () => {
if (isLoadingAppRef.current) {
App.openApp();
Expand All @@ -80,12 +85,9 @@ function AuthScreensInitHandler() {
if (!Navigation.isActiveRoute(ROUTES.SIGN_IN_MODAL)) {
return;
}
if (isLoadingOnyxValue(conciergeReportIDMetadata)) {
return;
}
// This means sign in in RHP was successful, so we can subscribe to user events
initializePusher(conciergeReportID, session?.accountID);
}, [session?.accountID, conciergeReportID, conciergeReportIDMetadata]);
initializePusher(session?.accountID, () => reportAttributesRef.current);
}, [session?.accountID]);

useEffect(() => {
const isLoggingInAsNewUser = !!session?.email && SessionUtils.isLoggingInAsNewUser(currentUrl, session.email);
Expand All @@ -107,7 +109,8 @@ function AuthScreensInitHandler() {
parentSpan: getSpan(CONST.TELEMETRY.SPAN_BOOTSPLASH.ROOT),
});
PusherConnectionManager.init();
initializePusher(conciergeReportID, session?.accountID).finally(() => {

initializePusher(session?.accountID, () => reportAttributesRef.current).finally(() => {
endSpan(CONST.TELEMETRY.SPAN_NAVIGATION.PUSHER_INIT);
});

Expand Down
19 changes: 12 additions & 7 deletions src/libs/Notification/LocalNotification/BrowserNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import * as AppUpdate from '@libs/actions/AppUpdate';
import {translateLocal} from '@libs/Localize';
import {getForReportAction} from '@libs/ModifiedExpenseMessage';
import {getTextFromHtml} from '@libs/ReportActionsUtils';
import {getReportName} from '@libs/ReportNameUtils';
import * as ReportUtils from '@libs/ReportUtils';
import playSound, {SOUNDS} from '@libs/Sound';
import type {Report, ReportAction} from '@src/types/onyx';
import type {Report, ReportAction, ReportAttributesDerivedValue} from '@src/types/onyx';
import SafeString from '@src/utils/SafeString';
import type {LocalNotificationClickHandler, LocalNotificationData, LocalNotificationModifiedExpensePushParams} from './types';

Expand Down Expand Up @@ -96,7 +97,13 @@ export default {
*
* @param usesIcon true if notification uses right circular icon
*/
pushReportCommentNotification(report: Report, reportAction: ReportAction, onClick: LocalNotificationClickHandler, conciergeReportID: string | undefined, usesIcon = false) {
pushReportCommentNotification(
report: Report,
reportAction: ReportAction,
onClick: LocalNotificationClickHandler,
usesIcon = false,
reportAttributes?: ReportAttributesDerivedValue['reports'],
) {
let title;
let body;
const icon = usesIcon ? EXPENSIFY_ICON_URL : '';
Expand All @@ -115,9 +122,7 @@ export default {
}

if (isRoomOrGroupChat) {
// Will be fixed in https://github.com/Expensify/App/issues/76852
// eslint-disable-next-line @typescript-eslint/no-deprecated
const roomName = ReportUtils.getReportName({report, conciergeReportID});
const roomName = getReportName(report, reportAttributes);
title = roomName;
body = `${plainTextPerson}: ${plainTextMessage}`;
} else {
Expand All @@ -142,7 +147,7 @@ export default {
policyTags,
policy,
currentUserLogin,
conciergeReportID,
reportAttributes,
}: LocalNotificationModifiedExpensePushParams) {
const title = reportAction.person?.map((f) => f.text).join(', ') ?? '';
const bodyWithHTML = getForReportAction({
Expand All @@ -154,7 +159,7 @@ export default {
movedToReport,
policyTags,
currentUserLogin,
conciergeReportID,
reportAttributes,
});
// Strip HTML tags for plain text notification body
const body = getTextFromHtml(bodyWithHTML);
Expand Down
Loading
Loading