From 0a4a8cd6eb25c7bbcb53fc91f1030e05065fbffd Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 2 Dec 2024 14:34:16 +0100 Subject: [PATCH 01/19] Remove ReportConnection util --- src/libs/DistanceRequestUtils.ts | 15 ++- src/libs/Firebase/utils.ts | 16 ++- src/libs/ModifiedExpenseMessage.ts | 14 +- src/libs/Navigation/Navigation.ts | 15 ++- .../linkingConfig/getAdaptedStateFromPath.ts | 15 ++- .../subscribePushNotification/index.ts | 15 ++- src/libs/Parser.ts | 23 +++- src/libs/ReportActionsUtils.ts | 18 ++- src/libs/ReportConnection.ts | 71 ---------- src/libs/ReportUtils.ts | 125 +++++++++++------- src/libs/TaskUtils.ts | 15 ++- src/libs/TransactionUtils/index.ts | 15 ++- src/libs/UnreadIndicatorUpdater/index.ts | 14 +- src/libs/actions/IOU.ts | 39 +++--- src/libs/actions/Policy/Policy.ts | 12 +- src/libs/actions/Policy/ReportField.ts | 14 +- src/libs/actions/PriorityMode.ts | 15 ++- src/libs/actions/Report.ts | 51 ++++--- src/libs/actions/ReportActions.ts | 16 ++- src/libs/actions/Task.ts | 18 ++- src/libs/markAllPolicyReportsAsRead.ts | 18 ++- .../report/ContextMenu/ContextMenuActions.tsx | 4 +- src/pages/home/report/ReportActionsList.tsx | 5 +- 23 files changed, 336 insertions(+), 227 deletions(-) delete mode 100644 src/libs/ReportConnection.ts diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 3b8e26c9cd33..fe40ea67f905 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -1,15 +1,14 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {LastSelectedDistanceRates, OnyxInputOrEntry, Transaction} from '@src/types/onyx'; +import type {LastSelectedDistanceRates, OnyxInputOrEntry, Report, Transaction} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type Policy from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as CurrencyUtils from './CurrencyUtils'; import * as PolicyUtils from './PolicyUtils'; -import * as ReportConnection from './ReportConnection'; import * as ReportUtils from './ReportUtils'; import * as TransactionUtils from './TransactionUtils'; @@ -30,6 +29,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter @@ -282,7 +290,6 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { * Returns custom unit rate ID for the distance transaction */ function getCustomUnitRateID(reportID: string) { - const allReports = ReportConnection.getAllReports(); const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? '-1'); diff --git a/src/libs/Firebase/utils.ts b/src/libs/Firebase/utils.ts index 01df2bfc8a7e..385fda4c817b 100644 --- a/src/libs/Firebase/utils.ts +++ b/src/libs/Firebase/utils.ts @@ -1,18 +1,30 @@ +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import {getAllTransactions, getAllTransactionViolationsLength} from '@libs/actions/Transaction'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import {getActivePolicy, getAllPoliciesLength} from '@libs/PolicyUtils'; import {getReportActionsLength} from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as SessionUtils from '@libs/SessionUtils'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Report} from '@src/types/onyx'; import type {PerfAttributes} from './types'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function getAttributes(attributes?: T[]): Pick { const session = SessionUtils.getSession(); const policy = getActivePolicy(); const allAttributes: PerfAttributes = { accountId: session?.accountID?.toString() ?? 'N/A', - reportsLength: ReportConnection.getAllReportsLength().toString(), + reportsLength: Object.keys(allReports ?? {}).length.toString(), reportActionsLength: getReportActionsLength().toString(), personalDetailsLength: PersonalDetailsUtils.getPersonalDetailsLength().toString(), transactionViolationsLength: getAllTransactionViolationsLength().toString(), diff --git a/src/libs/ModifiedExpenseMessage.ts b/src/libs/ModifiedExpenseMessage.ts index f5109cbea74b..b46d864cadcd 100644 --- a/src/libs/ModifiedExpenseMessage.ts +++ b/src/libs/ModifiedExpenseMessage.ts @@ -2,14 +2,13 @@ import Onyx from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PolicyTagLists, ReportAction} from '@src/types/onyx'; +import type {PolicyTagLists, Report, ReportAction} from '@src/types/onyx'; import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; import * as Localize from './Localize'; import Log from './Log'; import * as PolicyUtils from './PolicyUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; -import * as ReportConnection from './ReportConnection'; import * as TransactionUtils from './TransactionUtils'; let allPolicyTags: OnyxCollection = {}; @@ -25,6 +24,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + /** * Utility to get message based on boolean literal value. */ @@ -137,7 +145,7 @@ function getForReportAction(reportID: string | undefined, reportAction: OnyxEntr return ''; } const reportActionOriginalMessage = ReportActionsUtils.getOriginalMessage(reportAction); - const policyID = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.policyID ?? '-1'; + const policyID = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.policyID ?? '-1'; const removalFragments: string[] = []; const setFragments: string[] = []; diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index d54668bf3f69..eeb6db21447e 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -1,10 +1,10 @@ import {findFocusedRoute} from '@react-navigation/core'; import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native'; import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import {isCentralPaneName, removePolicyIDParamFromState} from '@libs/NavigationUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; @@ -30,6 +30,15 @@ import setNavigationActionToMicrotaskQueue from './setNavigationActionToMicrotas import switchPolicyID from './switchPolicyID'; import type {NavigationStateRoute, RootStackParamList, State, StateOrRoute, SwitchPolicyIDParams} from './types'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { resolveNavigationIsReadyPromise = resolve; @@ -66,7 +75,7 @@ const dismissModal = (reportID?: string, ref = navigationRef) => { originalDismissModal(ref); return; } - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; originalDismissModalWithReport({reportID, ...report}, ref); }; // Re-exporting the closeRHPFlow here to fill in default value for navigationRef. The closeRHPFlow isn't defined in this file to avoid cyclic dependencies. diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 518d27da8feb..33a2ea9946a8 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -1,6 +1,8 @@ import type {NavigationState, PartialState, Route} from '@react-navigation/native'; import {findFocusedRoute, getStateFromPath} from '@react-navigation/native'; import pick from 'lodash/pick'; +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import type {TupleToUnion} from 'type-fest'; import type {TopTabScreen} from '@components/FocusTrap/TOP_TAB_SCREENS'; import {isAnonymousUser} from '@libs/actions/Session'; @@ -8,13 +10,13 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {isCentralPaneName} from '@libs/NavigationUtils'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import extractPolicyIDFromQuery from '@navigation/extractPolicyIDFromQuery'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; +import type {Report} from '@src/types/onyx'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config, {normalizedConfigs} from './config'; import FULL_SCREEN_TO_RHP_MAPPING from './FULL_SCREEN_TO_RHP_MAPPING'; @@ -23,6 +25,15 @@ import getMatchingCentralPaneRouteForState from './getMatchingCentralPaneRouteFo import getOnboardingAdaptedState from './getOnboardingAdaptedState'; import replacePathInNestedState from './replacePathInNestedState'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + const RHP_SCREENS_OPENED_FROM_LHN = [ SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, @@ -160,7 +171,7 @@ function getMatchingRootRouteForRHPRoute(route: NavigationPartialRoute): Navigat // check for valid reportID in the route params // if the reportID is valid, we should navigate back to screen report in CPN const reportID = (route.params as Record)?.reportID; - if (ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportID) { + if (allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportID) { return {name: SCREENS.REPORT, params: {reportID}}; } } diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index 34d982469825..61af079f9ed1 100644 --- a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts +++ b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts @@ -1,5 +1,6 @@ import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import Log from '@libs/Log'; @@ -7,7 +8,6 @@ import Navigation from '@libs/Navigation/Navigation'; import type {ReportActionPushNotificationData} from '@libs/Notification/PushNotification/NotificationType'; import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils'; import {extractPolicyIDFromPath} from '@libs/PolicyUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; import Visibility from '@libs/Visibility'; import {updateLastVisitedPath} from '@userActions/App'; @@ -15,7 +15,7 @@ import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {OnyxUpdatesFromServer} from '@src/types/onyx'; +import type {OnyxUpdatesFromServer, Report} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import PushNotification from '..'; @@ -30,6 +30,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function getLastUpdateIDAppliedToClient(): Promise { return new Promise((resolve) => { Onyx.connect({ @@ -77,7 +86,7 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati Log.info('[PushNotification] Navigating to report', false, {reportID, reportActionID}); const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath); - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const policyEmployeeAccountIDs = policyID ? getPolicyEmployeeAccountIDs(policyID) : []; const reportBelongsToWorkspace = policyID && !isEmptyObject(report) && doesReportBelongToWorkspace(report, policyEmployeeAccountIDs, policyID); diff --git a/src/libs/Parser.ts b/src/libs/Parser.ts index 9d791b1d4f7b..8076496f2f79 100644 --- a/src/libs/Parser.ts +++ b/src/libs/Parser.ts @@ -3,10 +3,27 @@ import {ExpensiMark} from 'expensify-common'; import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import Log from './Log'; -import * as ReportConnection from './ReportConnection'; const accountIDToNameMap: Record = {}; +const reportIDToNameMap: Record = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + if (!value) { + return; + } + + Object.values(value).forEach((report) => { + if (!report) { + return; + } + reportIDToNameMap[report.reportID] = report.reportName ?? report.reportID; + }); + }, +}); + Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (personalDetailsList) => { @@ -30,7 +47,7 @@ type Extras = { class ExpensiMarkWithContext extends ExpensiMark { htmlToMarkdown(htmlString: string, extras?: Extras): string { return super.htmlToMarkdown(htmlString, { - reportIDToName: extras?.reportIDToName ?? ReportConnection.getAllReportsNameMap(), + reportIDToName: extras?.reportIDToName ?? reportIDToNameMap, accountIDToName: extras?.accountIDToName ?? accountIDToNameMap, cacheVideoAttributes: extras?.cacheVideoAttributes, }); @@ -38,7 +55,7 @@ class ExpensiMarkWithContext extends ExpensiMark { htmlToText(htmlString: string, extras?: Extras): string { return super.htmlToText(htmlString, { - reportIDToName: extras?.reportIDToName ?? ReportConnection.getAllReportsNameMap(), + reportIDToName: extras?.reportIDToName ?? reportIDToNameMap, accountIDToName: extras?.accountIDToName ?? accountIDToNameMap, cacheVideoAttributes: extras?.cacheVideoAttributes, }); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 8d828f457ece..ab84d835074f 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -26,7 +26,6 @@ import type {MessageElementBase, MessageTextElement} from './MessageElement'; import Parser from './Parser'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; -import * as ReportConnection from './ReportConnection'; import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle @@ -63,6 +62,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let isNetworkOffline = false; Onyx.connect({ key: ONYXKEYS.NETWORK, @@ -441,7 +449,7 @@ function getCombinedReportActions( filteredParentReportActions = reportActions?.filter((action) => action.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED); } - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const isSelfDM = report?.chatType === CONST.REPORT.CHAT_TYPE.SELF_DM; // Filter out request and send money request actions because we don't want to show any preview actions for one transaction reports const filteredReportActions = [...filteredParentReportActions, ...filteredTransactionThreadReportActions].filter((action) => { @@ -951,7 +959,7 @@ function getMostRecentReportActionLastModified(): string { // We might not have actions so we also look at the report objects to see if any have a lastVisibleActionLastModified that is more recent. We don't need to get // any reports that have been updated before either a recently updated report or reportAction as we should be up to date on these - Object.values(ReportConnection.getAllReports() ?? {}).forEach((report) => { + Object.values(allReports ?? {}).forEach((report) => { const reportLastVisibleActionLastModified = report?.lastVisibleActionLastModified ?? report?.lastVisibleActionCreated; if (!reportLastVisibleActionLastModified || reportLastVisibleActionLastModified < mostRecentReportActionLastModified) { return; @@ -1044,7 +1052,7 @@ const iouRequestTypes = new Set>([ */ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEntry | ReportAction[], isOffline: boolean | undefined = undefined): string | undefined { // If the report is not an IOU, Expense report, or Invoice, it shouldn't be treated as one-transaction report. - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE && report?.type !== CONST.REPORT.TYPE.INVOICE) { return; } @@ -1571,7 +1579,7 @@ function wasActionTakenByCurrentUser(reportAction: OnyxInputOrEntry { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const reportActions = getAllReportActions(report?.reportID ?? ''); const action = Object.values(reportActions ?? {})?.find((reportAction) => { const IOUTransactionID = isMoneyRequestAction(reportAction) ? getOriginalMessage(reportAction)?.IOUTransactionID : -1; diff --git a/src/libs/ReportConnection.ts b/src/libs/ReportConnection.ts deleted file mode 100644 index 7b61b22681e5..000000000000 --- a/src/libs/ReportConnection.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type {OnyxCollection} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type {Report} from '@src/types/onyx'; -import * as PriorityModeActions from './actions/PriorityMode'; -import * as ReportHelperActions from './actions/Report'; - -// Dynamic Import to avoid circular dependency -const UnreadIndicatorUpdaterHelper = () => import('./UnreadIndicatorUpdater'); - -const reportIDToNameMap: Record = {}; -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - UnreadIndicatorUpdaterHelper().then((module) => { - module.triggerUnreadUpdate(); - }); - // Each time a new report is added we will check to see if the user should be switched - PriorityModeActions.autoSwitchToFocusMode(); - - if (!value) { - return; - } - Object.values(value).forEach((report) => { - if (!report) { - return; - } - reportIDToNameMap[report.reportID] = report.reportName ?? report.reportID; - ReportHelperActions.handleReportChanged(report); - }); - }, -}); - -// This function is used to get all reports -function getAllReports() { - return allReports; -} - -// This function is used to get all reports name map -function getAllReportsNameMap() { - return reportIDToNameMap; -} - -function getAllReportsLength() { - return Object.keys(allReports ?? {}).length; -} - -function getReport(reportID: string) { - if (!reportID || !allReports) { - return; - } - return allReports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; -} - -function updateReportData(reportID: string, reportData?: Partial) { - const report = getReport(reportID); - - if (!allReports || !report || !report.reportID) { - return; - } - - allReports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] = { - ...report, - ...reportData, - }; -} - -export {getAllReports, getAllReportsNameMap, getAllReportsLength, updateReportData, getReport}; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index b8a59fffdf38..e8d867ac99c0 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -60,7 +60,9 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; import * as IOU from './actions/IOU'; import * as PolicyActions from './actions/Policy/Policy'; +import * as PriorityModeActions from './actions/PriorityMode'; import * as store from './actions/ReimbursementAccount/store'; +import * as ReportHelperActions from './actions/Report'; import * as SessionUtils from './actions/Session'; import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; @@ -84,8 +86,8 @@ import * as PhoneNumber from './PhoneNumber'; import * as PolicyUtils from './PolicyUtils'; import type {LastVisibleMessage} from './ReportActionsUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; -import * as ReportConnection from './ReportConnection'; import * as TransactionUtils from './TransactionUtils'; +import * as UnreadIndicatorUpdaterHelper from './UnreadIndicatorUpdater'; import * as Url from './Url'; import type {AvatarSource} from './UserUtils'; import * as UserUtils from './UserUtils'; @@ -624,6 +626,29 @@ Onyx.connect({ callback: (value) => (allPolicies = value), }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + UnreadIndicatorUpdaterHelper.triggerUnreadUpdate(); + + // Each time a new report is added we will check to see if the user should be switched + PriorityModeActions.autoSwitchToFocusMode(); + + if (!value) { + return; + } + Object.values(value).forEach((report) => { + if (!report) { + return; + } + ReportHelperActions.handleReportChanged(report); + }); + }, +}); + let allBetas: OnyxEntry; Onyx.connect({ key: ONYXKEYS.BETAS, @@ -741,7 +766,6 @@ function getChatType(report: OnyxInputOrEntry | Participant): ValueOf { - const allReports = ReportConnection.getAllReports(); return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? allReportsDraft?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`]; } @@ -758,7 +782,7 @@ function isDraftReport(reportID: string | undefined): boolean { * Returns the report */ function getReport(reportID: string): OnyxEntry { - return ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; } /** @@ -775,7 +799,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry { if (!report?.parentReportID) { return undefined; } - return ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]; + return getReport(report.parentReportID); } /** @@ -876,7 +900,7 @@ function isExpenseReport(report: OnyxInputOrEntry | SearchReport): boole * Checks if a report is an IOU report using report or reportID */ function isIOUReport(reportOrID: OnyxInputOrEntry | SearchReport | string): boolean { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) ?? null : reportOrID; return report?.type === CONST.REPORT.TYPE.IOU; } @@ -941,7 +965,7 @@ function isReportManager(report: OnyxEntry): boolean { * Checks if the supplied report has been approved */ function isReportApproved(reportOrID: OnyxInputOrEntry | string, parentReportAction: OnyxEntry = undefined): boolean { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) ?? null : reportOrID; if (!report) { return parentReportAction?.childStateNum === CONST.REPORT.STATE_NUM.APPROVED && parentReportAction?.childStatusNum === CONST.REPORT.STATUS_NUM.APPROVED; } @@ -988,7 +1012,7 @@ function isSettled(reportOrID: OnyxInputOrEntry | SearchReport | string if (!reportOrID) { return false; } - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) ?? null : reportOrID; if (!report) { return false; } @@ -1010,7 +1034,6 @@ function isSettled(reportOrID: OnyxInputOrEntry | SearchReport | string * Whether the current user is the submitter of the report */ function isCurrentUserSubmitter(reportID: string): boolean { - const allReports = ReportConnection.getAllReports(); if (!allReports) { return false; } @@ -1072,8 +1095,11 @@ function isInvoiceRoom(report: OnyxEntry): boolean { } function isInvoiceRoomWithID(reportID?: string): boolean { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID || -1}`]; + if (!reportID) { + return false; + } + + const report = getReport(reportID); return isInvoiceRoom(report); } @@ -1202,7 +1228,7 @@ function isWorkspaceTaskReport(report: OnyxEntry): boolean { if (!isTaskReport(report)) { return false; } - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; + const parentReport = report?.parentReportID ? getReport(report?.parentReportID) : undefined; return isPolicyExpenseChat(parentReport); } @@ -1288,7 +1314,6 @@ function isConciergeChatReport(report: OnyxInputOrEntry): boolean { } function findSelfDMReportID(): string | undefined { - const allReports = ReportConnection.getAllReports(); if (!allReports) { return; } @@ -1409,7 +1434,6 @@ function findLastAccessedReport(ignoreDomainRooms: boolean, openOnAdminRoom = fa const policyMemberAccountIDs = PolicyUtils.getPolicyEmployeeListByIdWithoutCurrentUser(allPolicies, policyID, currentUserAccountID); - const allReports = ReportConnection.getAllReports(); let reportsValues = Object.values(allReports ?? {}); if (!!policyID || policyMemberAccountIDs.length > 0) { @@ -1479,8 +1503,11 @@ function isArchivedRoom(report: OnyxInputOrEntry | SearchReport, reportN * Whether the report with the provided reportID is an archived room */ function isArchivedRoomWithID(reportID?: string) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID || -1}`]; + if (!reportID) { + return false; + } + + const report = getReport(reportID); return isArchivedRoom(report, getReportNameValuePairs(reportID)); } @@ -1625,7 +1652,7 @@ function isChildReport(report: OnyxEntry): boolean { function isExpenseRequest(report: OnyxInputOrEntry): report is Thread { if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; + const parentReport = getReport(report?.parentReportID); return isExpenseReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } return false; @@ -1638,7 +1665,7 @@ function isExpenseRequest(report: OnyxInputOrEntry): report is Thread { function isIOURequest(report: OnyxInputOrEntry): boolean { if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; + const parentReport = getReport(report?.parentReportID); return isIOUReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } return false; @@ -1661,7 +1688,7 @@ function isTrackExpenseReport(report: OnyxInputOrEntry): boolean { * Checks if a report is an IOU or expense request. */ function isMoneyRequest(reportOrID: OnyxEntry | string): boolean { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) ?? null : reportOrID; return isIOURequest(report) || isExpenseRequest(report); } @@ -1669,7 +1696,7 @@ function isMoneyRequest(reportOrID: OnyxEntry | string): boolean { * Checks if a report is an IOU or expense report. */ function isMoneyRequestReport(reportOrID: OnyxInputOrEntry | SearchReport | string): boolean { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) ?? null : reportOrID; return isIOUReport(report) || isExpenseReport(report); } @@ -1898,7 +1925,7 @@ function getReportRecipientAccountIDs(report: OnyxEntry, currentLoginAcc // In 1:1 chat threads, the participants will be the same as parent report. If a report is specifically a 1:1 chat thread then we will // get parent report and use its participants array. if (isThread(report) && !(isTaskReport(report) || isMoneyRequestReport(report))) { - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; + const parentReport = getReport(report?.parentReportID); if (isOneOnOneChat(parentReport)) { finalReport = parentReport; } @@ -2569,7 +2596,7 @@ function getReimbursementQueuedActionMessage( reportOrID: OnyxEntry | string, shouldUseShortDisplayName = true, ): string { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID; const submitterDisplayName = getDisplayNameForParticipant(report?.ownerAccountID, shouldUseShortDisplayName) ?? ''; const originalMessage = ReportActionsUtils.getOriginalMessage(reportAction); let messageKey: TranslationPaths; @@ -2590,7 +2617,7 @@ function getReimbursementDeQueuedActionMessage( reportOrID: OnyxEntry | string, isLHNPreview = false, ): string { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID; const originalMessage = ReportActionsUtils.getOriginalMessage(reportAction); const amount = originalMessage?.amount; const currency = originalMessage?.currency; @@ -2844,7 +2871,7 @@ function hasNonReimbursableTransactions(iouReportID: string | undefined): boolea } function getMoneyRequestSpendBreakdown(report: OnyxInputOrEntry, allReportsDict?: OnyxCollection): SpendBreakdown { - const allAvailableReports = allReportsDict ?? ReportConnection.getAllReports(); + const allAvailableReports = allReportsDict ?? allReports; let moneyRequestReport; if (isMoneyRequestReport(report) || isInvoiceReport(report)) { moneyRequestReport = report; @@ -3221,7 +3248,7 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry } const iouMessage = ReportActionsUtils.getOriginalMessage(reportAction); - const moneyRequestReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${iouMessage?.IOUReportID}`] ?? ({} as Report); + const moneyRequestReport = iouMessage?.IOUReportID ? getReport(iouMessage?.IOUReportID) ?? ({} as Report) : ({} as Report); const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${iouMessage?.IOUTransactionID}`] ?? ({} as Transaction); if (isSettled(String(moneyRequestReport.reportID)) || isReportApproved(String(moneyRequestReport.reportID))) { @@ -3505,7 +3532,7 @@ function getReportPreviewMessage( isForListPreview = false, originalReportAction: OnyxInputOrEntry = iouReportAction, ): string { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID; const reportActionMessage = ReportActionsUtils.getReportActionHtml(iouReportAction); if (isEmptyObject(report) || !report?.reportID) { @@ -4686,7 +4713,7 @@ function buildOptimisticExpenseReport( ): OptimisticExpenseReport { // The amount for Expense reports are stored as negative value in the database const storedTotal = total * -1; - const policyName = getPolicyName(ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`]); + const policyName = getPolicyName(getReport(chatReportID)); const formattedTotal = CurrencyUtils.convertToDisplayString(storedTotal, currency); const policy = getPolicy(policyID); @@ -6260,7 +6287,7 @@ function isUnread(report: OnyxEntry): boolean { } function isIOUOwnedByCurrentUser(report: OnyxEntry, allReportsDict?: OnyxCollection): boolean { - const allAvailableReports = allReportsDict ?? ReportConnection.getAllReports(); + const allAvailableReports = allReportsDict ?? allReports; if (!report || !allAvailableReports) { return false; } @@ -6348,8 +6375,8 @@ function shouldDisplayViolationsRBRInLHN(report: OnyxEntry, transactionV // - Are either open or submitted // - Belong to the same workspace // And if any have a violation, then it should have a RBR - const allReports = Object.values(ReportConnection.getAllReports() ?? {}) as Report[]; - const potentialReports = allReports.filter((r) => r?.ownerAccountID === currentUserAccountID && (r?.stateNum ?? 0) <= 1 && r?.policyID === report.policyID); + const reports = Object.values(allReports ?? {}) as Report[]; + const potentialReports = reports.filter((r) => r?.ownerAccountID === currentUserAccountID && (r?.stateNum ?? 0) <= 1 && r?.policyID === report.policyID); return potentialReports.some( (potentialReport) => hasViolations(potentialReport.reportID, transactionViolations) || hasWarningTypeViolations(potentialReport.reportID, transactionViolations), ); @@ -6661,7 +6688,7 @@ function shouldReportBeInOptionList(params: ShouldReportBeInOptionListParams) { /** * Attempts to find a report in onyx with the provided list of participants. Does not include threads, task, expense, room, and policy expense chat. */ -function getChatByParticipants(newParticipantList: number[], reports: OnyxCollection = ReportConnection.getAllReports(), shouldIncludeGroupChats = false): OnyxEntry { +function getChatByParticipants(newParticipantList: number[], reports: OnyxCollection = allReports, shouldIncludeGroupChats = false): OnyxEntry { const sortedNewParticipantList = newParticipantList.sort(); return Object.values(reports ?? {}).find((report) => { const participantAccountIDs = Object.keys(report?.participants ?? {}); @@ -6686,7 +6713,7 @@ function getChatByParticipants(newParticipantList: number[], reports: OnyxCollec /** * Attempts to find an invoice chat report in onyx with the provided policyID and receiverID. */ -function getInvoiceChatByParticipants(policyID: string, receiverID: string | number, reports: OnyxCollection = ReportConnection.getAllReports()): OnyxEntry { +function getInvoiceChatByParticipants(policyID: string, receiverID: string | number, reports: OnyxCollection = allReports): OnyxEntry { return Object.values(reports ?? {}).find((report) => { if (!report || !isInvoiceRoom(report) || isArchivedRoom(report)) { return false; @@ -6705,7 +6732,7 @@ function getInvoiceChatByParticipants(policyID: string, receiverID: string | num * Attempts to find a policy expense report in onyx that is owned by ownerAccountID in a given policy */ function getPolicyExpenseChat(ownerAccountID: number, policyID: string): OnyxEntry { - return Object.values(ReportConnection.getAllReports() ?? {}).find((report: OnyxEntry) => { + return Object.values(allReports ?? {}).find((report: OnyxEntry) => { // If the report has been deleted, then skip it if (!report) { return false; @@ -6716,7 +6743,7 @@ function getPolicyExpenseChat(ownerAccountID: number, policyID: string): OnyxEnt } function getAllPolicyReports(policyID: string): Array> { - return Object.values(ReportConnection.getAllReports() ?? {}).filter((report) => report?.policyID === policyID); + return Object.values(allReports ?? {}).filter((report) => report?.policyID === policyID); } /** @@ -6728,8 +6755,11 @@ function chatIncludesChronos(report: OnyxInputOrEntry): boolean { } function chatIncludesChronosWithID(reportID?: string): boolean { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID || -1}`]; + if (!reportID) { + return false; + } + + const report = getReport(reportID); return chatIncludesChronos(report); } @@ -6881,7 +6911,7 @@ function getReportIDFromLink(url: string | null): string { */ function hasIOUWaitingOnCurrentUserBankAccount(chatReport: OnyxInputOrEntry): boolean { if (chatReport?.iouReportID) { - const iouReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport?.iouReportID}`]; + const iouReport = getReport(chatReport.iouReportID); if (iouReport?.isWaitingOnBankAccount && iouReport?.ownerAccountID === currentUserAccountID) { return true; } @@ -7209,7 +7239,6 @@ function shouldReportShowSubscript(report: OnyxEntry): boolean { * Return true if reports data exists */ function isReportDataReady(): boolean { - const allReports = ReportConnection.getAllReports(); return !isEmptyObject(allReports) && Object.keys(allReports ?? {}).some((key) => allReports?.[key]?.reportID); } @@ -7233,7 +7262,7 @@ function getAddWorkspaceRoomOrChatReportErrors(report: OnyxEntry): Error * Return true if the expense report is marked for deletion. */ function isMoneyRequestReportPendingDeletion(reportOrID: OnyxEntry | string): boolean { - const report = typeof reportOrID === 'string' ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] : reportOrID; + const report = typeof reportOrID === 'string' ? getReport(reportOrID) : reportOrID; if (!isMoneyRequestReport(report)) { return false; } @@ -7263,7 +7292,7 @@ function getOriginalReportID(reportID: string, reportAction: OnyxInputOrEntry, policy: OnyxEntry, return requestOptions.includes(iouType); } -function getWorkspaceChats(policyID: string, accountIDs: number[], allReports: OnyxCollection = ReportConnection.getAllReports()): Array> { - return Object.values(allReports ?? {}).filter((report) => isPolicyExpenseChat(report) && (report?.policyID ?? '-1') === policyID && accountIDs.includes(report?.ownerAccountID ?? -1)); +function getWorkspaceChats(policyID: string, accountIDs: number[], reports: OnyxCollection = allReports): Array> { + return Object.values(reports ?? {}).filter((report) => isPolicyExpenseChat(report) && (report?.policyID ?? '-1') === policyID && accountIDs.includes(report?.ownerAccountID ?? -1)); } /** @@ -7313,7 +7342,6 @@ function getWorkspaceChats(policyID: string, accountIDs: number[], allReports: O * @param policyID - the workspace ID to get all associated reports */ function getAllWorkspaceReports(policyID: string): Array> { - const allReports = ReportConnection.getAllReports(); return Object.values(allReports ?? {}).filter((report) => (report?.policyID ?? '-1') === policyID); } @@ -7620,7 +7648,7 @@ function shouldUseFullTitleToDisplay(report: OnyxEntry): boolean { } function getRoom(type: ValueOf, policyID: string): OnyxEntry { - const room = Object.values(ReportConnection.getAllReports() ?? {}).find((report) => report?.policyID === policyID && report?.chatType === type && !isThread(report)); + const room = Object.values(allReports ?? {}).find((report) => report?.policyID === policyID && report?.chatType === type && !isThread(report)); return room; } @@ -8021,7 +8049,7 @@ function shouldCreateNewMoneyRequestReport(existingIOUReport: OnyxInputOrEntry report && report?.[reportFieldToCompare] === tripRoomReportID) .map((report) => report?.reportID); return tripTransactionReportIDs.flatMap((reportID) => reportsTransactions[reportID ?? ''] ?? []); @@ -8274,7 +8302,6 @@ function canReportBeMentionedWithinPolicy(report: OnyxEntry, policyID: s } function shouldShowMerchantColumn(transactions: Transaction[]) { - const allReports = ReportConnection.getAllReports(); return transactions.some((transaction) => isExpenseReport(allReports?.[transaction.reportID] ?? null)); } @@ -8297,7 +8324,7 @@ function isChatUsedForOnboarding(optionOrReport: OnyxEntry | OptionData) * we also used the system DM for A/B tests. */ function getChatUsedForOnboarding(): OnyxEntry { - return Object.values(ReportConnection.getAllReports() ?? {}).find(isChatUsedForOnboarding); + return Object.values(allReports ?? {}).find(isChatUsedForOnboarding); } /** @@ -8339,7 +8366,7 @@ function getReportViolations(reportID: string): ReportViolations | undefined { } function findPolicyExpenseChatByPolicyID(policyID: string): OnyxEntry { - return Object.values(ReportConnection.getAllReports() ?? {}).find((report) => isPolicyExpenseChat(report) && report?.policyID === policyID); + return Object.values(allReports ?? {}).find((report) => isPolicyExpenseChat(report) && report?.policyID === policyID); } /** @@ -8446,8 +8473,8 @@ function hasMissingInvoiceBankAccount(iouReportID: string): boolean { } function hasInvoiceReports() { - const allReports = Object.values(ReportConnection.getAllReports() ?? {}); - return allReports.some((report) => isInvoiceReport(report)); + const reports = Object.values(allReports ?? {}); + return reports.some((report) => isInvoiceReport(report)); } export { diff --git a/src/libs/TaskUtils.ts b/src/libs/TaskUtils.ts index 11434373dafb..975c3e617ce5 100644 --- a/src/libs/TaskUtils.ts +++ b/src/libs/TaskUtils.ts @@ -1,4 +1,5 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -8,7 +9,15 @@ import type ReportAction from '@src/types/onyx/ReportAction'; import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import {getReportActionHtml, getReportActionText} from './ReportActionsUtils'; -import * as ReportConnection from './ReportConnection'; + +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); /** * Check if the active route belongs to task edit flow. @@ -46,7 +55,7 @@ function getTaskTitleFromReport(taskReport: OnyxEntry, fallbackTitle = ' } function getTaskTitle(taskReportID: string, fallbackTitle = ''): string { - const taskReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]; + const taskReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]; return getTaskTitleFromReport(taskReport, fallbackTitle); } diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index a7c6baae85a1..7066edbd949b 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -20,7 +20,6 @@ import {getCleanedTagName, getDistanceRateCustomUnitRate} from '@libs/PolicyUtil import * as PolicyUtils from '@libs/PolicyUtils'; // eslint-disable-next-line import/no-cycle import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import type {IOURequestType} from '@userActions/IOU'; import CONST from '@src/CONST'; @@ -46,6 +45,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let allTransactionViolations: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, @@ -239,7 +247,6 @@ function isCreatedMissing(transaction: OnyxEntry) { } function areRequiredFieldsEmpty(transaction: OnyxEntry): boolean { - const allReports = ReportConnection.getAllReports(); const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`] ?? null; const isFromExpenseReport = parentReport?.type === CONST.REPORT.TYPE.EXPENSE; const isSplitPolicyExpenseChat = !!transaction?.comment?.splits?.some((participant) => allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`]?.isOwnPolicyExpenseChat); @@ -1130,7 +1137,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor const keys = fieldsToCompare[fieldName]; const firstTransaction = transactions.at(0); const isFirstTransactionCommentEmptyObject = typeof firstTransaction?.comment === 'object' && firstTransaction?.comment?.comment === ''; - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; const policy = PolicyUtils.getPolicy(report?.policyID); const areAllFieldsEqualForKey = areAllFieldsEqual(transactions, (item) => keys.map((key) => item?.[key]).join('|')); @@ -1205,7 +1212,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor } function getTransactionID(threadReportID: string): string { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${threadReportID}`] ?? null; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${threadReportID}`] ?? null; const parentReportAction = ReportActionsUtils.getReportAction(report?.parentReportID ?? '', report?.parentReportActionID ?? ''); const IOUTransactionID = ReportActionsUtils.isMoneyRequestAction(parentReportAction) ? ReportActionsUtils.getOriginalMessage(parentReportAction)?.IOUTransactionID ?? '-1' : '-1'; diff --git a/src/libs/UnreadIndicatorUpdater/index.ts b/src/libs/UnreadIndicatorUpdater/index.ts index f4b8e3281308..4d38d410cbfd 100644 --- a/src/libs/UnreadIndicatorUpdater/index.ts +++ b/src/libs/UnreadIndicatorUpdater/index.ts @@ -1,13 +1,23 @@ import debounce from 'lodash/debounce'; import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import memoize from '@libs/memoize'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import Navigation, {navigationRef} from '@navigation/Navigation'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {Report} from '@src/types/onyx'; import updateUnread from './updateUnread'; +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function getUnreadReportsForUnreadIndicator(reports: OnyxCollection, currentReportID: string) { return Object.values(reports ?? {}).filter((report) => { const notificationPreference = ReportUtils.getReportNotificationPreference(report); @@ -42,7 +52,7 @@ const triggerUnreadUpdate = debounce(() => { const currentReportID = navigationRef?.isReady?.() ? Navigation.getTopmostReportId() ?? '-1' : '-1'; // We want to keep notification count consistent with what can be accessed from the LHN list - const unreadReports = memoizedGetUnreadReportsForUnreadIndicator(ReportConnection.getAllReports(), currentReportID); + const unreadReports = memoizedGetUnreadReportsForUnreadIndicator(allReports, currentReportID); updateUnread(unreadReports.length); }, CONST.TIMING.UNREAD_UPDATE_DEBOUNCE_TIME); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 90719ffeed55..c4cde450f13a 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -48,7 +48,6 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import type {OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails} from '@libs/ReportUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as SessionUtils from '@libs/SessionUtils'; @@ -268,6 +267,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let userAccountID = -1; let currentUserEmail = ''; Onyx.connect({ @@ -589,7 +597,7 @@ function buildOnyxDataForMoneyRequest( if (TransactionUtils.isDistanceRequest(transaction)) { newQuickAction = CONST.QUICK_ACTIONS.REQUEST_DISTANCE; } - const existingTransactionThreadReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${existingTransactionThreadReportID}`] ?? null; + const existingTransactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingTransactionThreadReportID}`] ?? null; if (chatReport) { optimisticData.push({ @@ -1362,7 +1370,7 @@ function buildOnyxDataForTrackExpense( } else if (isDistanceRequest) { newQuickAction = CONST.QUICK_ACTIONS.TRACK_DISTANCE; } - const existingTransactionThreadReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${existingTransactionThreadReportID}`] ?? null; + const existingTransactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingTransactionThreadReportID}`] ?? null; if (chatReport) { optimisticData.push( @@ -1719,7 +1727,6 @@ function getDeleteTrackExpenseInformation( actionableWhisperReportActionID = '', resolution = '', ) { - const allReports = ReportConnection.getAllReports(); // STEP 1: Get all collections we're updating const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; @@ -2076,7 +2083,6 @@ function getMoneyRequestInformation( let isNewChatReport = false; let chatReport = !isEmptyObject(parentChatReport) && parentChatReport?.reportID ? parentChatReport : null; - const allReports = ReportConnection.getAllReports(); // If this is a policyExpenseChat, the chatReport must exist and we can get it from Onyx. // report is null if the flow is initiated from the global create menu. However, participant always stores the reportID if it exists, which is the case for policyExpenseChats if (!chatReport && isPolicyExpenseChat) { @@ -2294,7 +2300,7 @@ function getTrackExpenseInformation( // STEP 1: Get existing chat report let chatReport = !isEmptyObject(parentChatReport) && parentChatReport?.reportID ? parentChatReport : null; - const allReports = ReportConnection.getAllReports(); + // The chatReport always exists, and we can get it from Onyx if chatReport is null. if (!chatReport) { chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.reportID}`] ?? null; @@ -2533,7 +2539,6 @@ function getUpdateMoneyRequestParams( const clearedPendingFields = Object.fromEntries(Object.keys(transactionChanges).map((key) => [key, null])); const errorFields = Object.fromEntries(Object.keys(pendingFields).map((key) => [key, {[DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericEditFailureMessage')}])); - const allReports = ReportConnection.getAllReports(); // Step 2: Get all the collections being updated const transactionThread = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; @@ -2859,7 +2864,6 @@ function getUpdateTrackExpenseParams( const clearedPendingFields = Object.fromEntries(Object.keys(transactionChanges).map((key) => [key, null])); const errorFields = Object.fromEntries(Object.keys(pendingFields).map((key) => [key, {[DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericEditFailureMessage')}])); - const allReports = ReportConnection.getAllReports(); // Step 2: Get all the collections being updated const transactionThread = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; @@ -3029,7 +3033,6 @@ function updateMoneyRequestDate( const transactionChanges: TransactionChanges = { created: value, }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; @@ -3070,7 +3073,6 @@ function updateMoneyRequestMerchant( const transactionChanges: TransactionChanges = { merchant: value, }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; @@ -3177,7 +3179,6 @@ function updateMoneyRequestDistance({ waypoints: sanitizeRecentWaypoints(waypoints), routes, }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; @@ -3226,7 +3227,6 @@ function updateMoneyRequestDescription( const transactionChanges: TransactionChanges = { comment, }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; @@ -3255,7 +3255,6 @@ function updateMoneyRequestDistanceRate( ...(typeof updatedTaxAmount === 'number' ? {taxAmount: updatedTaxAmount} : {}), ...(updatedTaxCode ? {taxCode: updatedTaxCode} : {}), }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; @@ -3972,7 +3971,7 @@ function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, const existingChatReportID = existingSplitChatReportID || (participants.at(0)?.reportID ?? '-1'); // Check if the report is available locally if we do have one - let existingSplitChatReport = existingChatReportID ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`] : null; + let existingSplitChatReport = existingChatReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`] : null; const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; if (!existingSplitChatReport) { @@ -4271,9 +4270,7 @@ function createSplitsAndOnyxData( } // STEP 2: Get existing IOU/Expense report and update its total OR build a new optimistic one - let oneOnOneIOUReport: OneOnOneIOUReport = oneOnOneChatReport.iouReportID - ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`] - : null; + let oneOnOneIOUReport: OneOnOneIOUReport = oneOnOneChatReport.iouReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`] : null; const shouldCreateNewOneOnOneIOUReport = ReportUtils.shouldCreateNewMoneyRequestReport(oneOnOneIOUReport, oneOnOneChatReport); if (!oneOnOneIOUReport || shouldCreateNewOneOnOneIOUReport) { @@ -5025,7 +5022,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA let oneOnOneChatReport: OnyxEntry; let isNewOneOnOneChatReport = false; - const allReports = ReportConnection.getAllReports(); + if (isPolicyExpenseChat) { // The workspace chat reportID is saved in the splits array when starting a split expense with a workspace oneOnOneChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`]; @@ -5376,7 +5373,6 @@ function updateMoneyRequestAmountAndCurrency({ taxCode, taxAmount, }; - const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.parentReportID}`] ?? null; let data: UpdateMoneyRequestData; @@ -5398,7 +5394,6 @@ function updateMoneyRequestAmountAndCurrency({ */ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { // STEP 1: Get all collections we're updating - const allReports = ReportConnection.getAllReports(); const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID : '-1'; const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReport?.chatReportID}`]; @@ -5917,7 +5912,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor function deleteTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { // STEP 1: Get all collections we're updating - const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; + const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; if (!ReportUtils.isSelfDM(chatReport)) { return deleteMoneyRequest(transactionID, reportAction, isSingleTransactionView); } @@ -8192,7 +8187,7 @@ function mergeDuplicates(params: TransactionMergeParams) { return total + duplicateTransaction.amount; }, 0); - const expenseReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${params.reportID}`]; + const expenseReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${params.reportID}`]; const expenseReportOptimisticData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${params.reportID}`, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 01a5909de9db..5d7d58fd4177 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -71,7 +71,6 @@ import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportActionsConnection from '@libs/ReportActionsConnection'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -172,6 +171,15 @@ Onyx.connect({ callback: (value) => (lastAccessedWorkspacePolicyID = value), }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let sessionEmail = ''; let sessionAccountID = 0; Onyx.connect({ @@ -308,7 +316,7 @@ function deleteWorkspace(policyID: string, policyName: string) { : []), ]; - const reportsToArchive = Object.values(ReportConnection.getAllReports() ?? {}).filter( + const reportsToArchive = Object.values(allReports ?? {}).filter( (report) => ReportUtils.isPolicyRelatedReport(report, policyID) && (ReportUtils.isChatRoom(report) || ReportUtils.isPolicyExpenseChat(report) || ReportUtils.isTaskReport(report)), ); const finallyData: OnyxUpdate[] = []; diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts index 2ee1707c21d1..2ada745ca6cf 100644 --- a/src/libs/actions/Policy/ReportField.ts +++ b/src/libs/actions/Policy/ReportField.ts @@ -14,7 +14,6 @@ import type { import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import Log from '@libs/Log'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import * as WorkspaceReportFieldUtils from '@libs/WorkspaceReportFieldUtils'; import CONST from '@src/CONST'; @@ -39,6 +38,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, @@ -179,9 +187,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR value: type === CONST.REPORT_FIELD_TYPES.LIST ? CONST.REPORT_FIELD_TYPES.LIST : null, }; - const policyExpenseReports = Object.values(ReportConnection.getAllReports() ?? {}).filter( - (report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE, - ) as Report[]; + const policyExpenseReports = Object.values(allReports ?? {}).filter((report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE) as Report[]; const optimisticData = [ { diff --git a/src/libs/actions/PriorityMode.ts b/src/libs/actions/PriorityMode.ts index 2aca5d9f9de8..02cd3a765e8c 100644 --- a/src/libs/actions/PriorityMode.ts +++ b/src/libs/actions/PriorityMode.ts @@ -1,10 +1,11 @@ import debounce from 'lodash/debounce'; import Onyx from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import Log from '@libs/Log'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Report} from '@src/types/onyx'; /** * This actions file is used to automatically switch a user into #focus mode when they exceed a certain number of reports. We do this primarily for performance reasons. @@ -68,6 +69,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function resetHasReadRequiredDataFromStorage() { // Create a new promise and a new resolve function isReadyPromise = new Promise((resolve) => { @@ -77,7 +87,7 @@ function resetHasReadRequiredDataFromStorage() { } function checkRequiredData() { - if (ReportConnection.getAllReports() === undefined || hasTriedFocusMode === undefined || isInFocusMode === undefined || isLoadingReportData) { + if (allReports === undefined || hasTriedFocusMode === undefined || isInFocusMode === undefined || isLoadingReportData) { return; } @@ -98,7 +108,6 @@ function tryFocusModeUpdate() { } const validReports = []; - const allReports = ReportConnection.getAllReports(); Object.keys(allReports ?? {}).forEach((key) => { const report = allReports?.[key]; if (!report) { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index efd8ca63350d..21299f4e2883 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -81,7 +81,6 @@ import {extractPolicyIDFromPath, getPolicy} from '@libs/PolicyUtils'; import processReportIDDeeplink from '@libs/processReportIDDeeplink'; import * as Pusher from '@libs/Pusher/pusher'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import type {OptimisticAddCommentReportAction} from '@libs/ReportUtils'; import * as ReportUtils from '@libs/ReportUtils'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; @@ -229,6 +228,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let allPersonalDetails: OnyxEntry = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, @@ -535,7 +543,7 @@ function addActions(reportID: string, text = '', file?: FileObject) { lastReadTime: currentTime, }; - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const shouldUpdateNotificationPrefernece = !isEmptyObject(report) && ReportUtils.getReportNotificationPreference(report) === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; if (shouldUpdateNotificationPrefernece) { @@ -713,7 +721,7 @@ function updateGroupChatName(reportID: string, reportName: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - reportName: ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? null, + reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? null, pendingFields: { reportName: null, }, @@ -742,7 +750,7 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani }, ]; - const fetchedReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const fetchedReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -811,7 +819,7 @@ function openReport( const optimisticReport = reportActionsExist(reportID) ? {} : { - reportName: ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, + reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, }; const optimisticData: OnyxUpdate[] = [ @@ -1036,7 +1044,7 @@ function openReport( } } - parameters.clientLastReadTime = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastReadTime ?? ''; + parameters.clientLastReadTime = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastReadTime ?? ''; const paginationConfig = { resourceID: reportID, @@ -1147,7 +1155,7 @@ function navigateToAndOpenChildReport(childReportID = '-1', parentReportAction: Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(childReportID)); } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction.actorAccountID)])]; - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; + 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 && ReportUtils.isSelfDM(parentReport) ? undefined : parentReport?.chatType; const newChat = ReportUtils.buildOptimisticChatReport( @@ -1345,8 +1353,7 @@ function markCommentAsUnread(reportID: string, reportActionCreated: string) { // If no action created date is provided, use the last action's from other user const actionCreationTime = - reportActionCreated || - (latestReportActionFromOtherUsers?.created ?? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); + reportActionCreated || (latestReportActionFromOtherUsers?.created ?? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); // We subtract 1 millisecond so that the lastReadTime is updated to just before a given reportAction's created date // For example, if we want to mark a report action with ID 100 and created date '2014-04-01 16:07:02.999' unread, we set the lastReadTime to '2014-04-01 16:07:02.998' @@ -1520,7 +1527,7 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { lastVisibleActionCreated: '', }; const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportUtils.getLastVisibleMessage(originalReportID, optimisticReportActions as ReportActions); - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (lastMessageText || lastMessageTranslationKey) { const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(originalReportID, canUserPerformWriteAction, optimisticReportActions as ReportActions); @@ -1906,7 +1913,7 @@ function toggleSubscribeToChildReport(childReportID = '-1', parentReportAction: } } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction?.actorAccountID)])]; - const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; const newChat = ReportUtils.buildOptimisticChatReport( participantAccountIDs, ReportActionsUtils.getReportActionText(parentReportAction), @@ -2381,7 +2388,7 @@ function addPolicyReport(policyReport: ReportUtils.OptimisticChatReport) { /** Deletes a report, along with its reportActions, any linked reports, and any linked IOU report. */ function deleteReport(reportID: string, shouldDeleteChildReports = false) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const onyxData: Record = { [`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]: null, [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]: null, @@ -2545,7 +2552,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi } // We don't want to send a local notification if the user preference is daily, mute or hidden. - const notificationPreference = ReportUtils.getReportNotificationPreference(ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]); + const notificationPreference = ReportUtils.getReportNotificationPreference(allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]); if (notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS) { Log.info(`${tag} No notification because user preference is to be notified: ${notificationPreference}`); return false; @@ -2563,7 +2570,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi return false; } - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report || (report && report.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE)) { Log.info(`${tag} No notification because the report does not exist or is pending deleted`, false); return false; @@ -2598,7 +2605,7 @@ function showReportActionNotification(reportID: string, reportAction: ReportActi Log.info('[LocalNotification] Creating notification'); const localReportID = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - const report = ReportConnection.getAllReports()?.[localReportID] ?? null; + const report = allReports?.[localReportID] ?? null; if (!report) { Log.hmmm("[LocalNotification] couldn't show report action notification because the report wasn't found", {localReportID, reportActionID: reportAction.reportActionID}); return; @@ -2883,7 +2890,7 @@ function joinRoom(report: OnyxEntry) { } function leaveGroupChat(reportID: string) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { Log.warn('Attempting to leave Group Chat that does not existing locally'); return; @@ -2938,7 +2945,7 @@ function leaveGroupChat(reportID: string) { /** Leave a report by setting the state to submitted and closed */ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = false) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; @@ -3042,7 +3049,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal /** Invites people to a room */ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmailsToAccountIDs) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; } @@ -3147,7 +3154,7 @@ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmails } function clearAddRoomMemberError(reportID: string, invitedAccountID: string) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { pendingChatMembers: report?.pendingChatMembers?.filter((pendingChatMember) => pendingChatMember.accountID !== invitedAccountID), participants: { @@ -3209,7 +3216,7 @@ function inviteToGroupChat(reportID: string, inviteeEmailsToAccountIDs: InvitedE * Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details */ function removeFromRoom(reportID: string, targetAccountIDs: number[]) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; } @@ -4053,7 +4060,7 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt }, }; - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { @@ -4128,7 +4135,7 @@ function resolveActionableReportMentionWhisper( }, }; - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index 9338527eaccc..d880c1a8fb20 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -1,23 +1,31 @@ import type {OnyxCollection} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as ReportActionUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReportActions} from '@src/types/onyx'; +import type * as OnyxTypes from '@src/types/onyx'; import type ReportAction from '@src/types/onyx/ReportAction'; import * as Report from './Report'; type IgnoreDirection = 'parent' | 'child'; -let allReportActions: OnyxCollection; +let allReportActions: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, waitForCollectionCallback: true, callback: (value) => (allReportActions = value), }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function clearReportActionErrors(reportID: string, reportAction: ReportAction, keys?: string[]) { const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction); @@ -81,7 +89,7 @@ function clearAllRelatedReportActionErrors(reportID: string, reportAction: Repor clearReportActionErrors(reportID, reportAction, keys); - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (report?.parentReportID && report?.parentReportActionID && ignore !== 'parent') { const parentReportAction = ReportActionUtils.getReportAction(report.parentReportID, report.parentReportActionID); const parentErrorKeys = Object.keys(parentReportAction?.errors ?? {}).filter((err) => errorKeys.includes(err)); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index ea87f5dd5cc6..71c7f478abe1 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -12,7 +12,6 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import CONST from '@src/CONST'; @@ -66,6 +65,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let allReportActions: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, @@ -312,9 +320,7 @@ function createTaskAndNavigate( API.write(WRITE_COMMANDS.CREATE_TASK, parameters, {optimisticData, successData, failureData}); - ReportConnection.updateReportData(parentReportID, { - lastReadTime: currentTime, - }); + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, {lastReadTime: currentTime}); if (!isCreatedUsingMarkdown) { clearOutTaskInfo(); @@ -962,7 +968,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry, sessionAccountID } function clearTaskErrors(reportID: string) { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; // Delete the task preview in the parent report if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { diff --git a/src/libs/markAllPolicyReportsAsRead.ts b/src/libs/markAllPolicyReportsAsRead.ts index 259a5e426d89..5f9ea2042aa3 100644 --- a/src/libs/markAllPolicyReportsAsRead.ts +++ b/src/libs/markAllPolicyReportsAsRead.ts @@ -1,13 +1,23 @@ +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {Report} from '@src/types/onyx'; import * as ReportActionFile from './actions/Report'; -import * as ReportConnection from './ReportConnection'; import * as ReportUtils from './ReportUtils'; +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + export default function markAllPolicyReportsAsRead(policyID: string) { let delay = 0; - const allReports = ReportConnection.getAllReports() ?? {}; - Object.keys(allReports).forEach((key: string) => { - const report: Report | null | undefined = allReports[key]; + Object.keys(allReports ?? {}).forEach((key: string) => { + const report: Report | null | undefined = allReports?.[key]; if (report?.policyID !== policyID || !ReportUtils.isUnread(report)) { return; } diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 705b85d4c3fc..a31137e53c6a 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -22,14 +22,12 @@ import Navigation from '@libs/Navigation/Navigation'; import Parser from '@libs/Parser'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import * as TaskUtils from '@libs/TaskUtils'; import * as Download from '@userActions/Download'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction, User} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; @@ -606,7 +604,7 @@ const ContextMenuActions: ContextMenuAction[] = [ successIcon: Expensicons.Checkmark, shouldShow: ({type, isProduction}) => type === CONST.CONTEXT_MENU_TYPES.REPORT && !isProduction, onPress: (closePopover, {reportID}) => { - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); Clipboard.setString(JSON.stringify(report, null, 4)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index d562669a6bac..a840e6ac3585 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -23,7 +23,6 @@ import DateUtils from '@libs/DateUtils'; import isSearchTopmostCentralPane from '@libs/Navigation/isSearchTopmostCentralPane'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import Visibility from '@libs/Visibility'; import type {AuthScreensParamList} from '@navigation/types'; @@ -208,8 +207,8 @@ function ReportActionsList({ const prevSortedVisibleReportActionsObjects = usePrevious(sortedVisibleReportActionsObjects); const reportLastReadTime = useMemo(() => { - return ReportConnection.getReport(report.reportID)?.lastReadTime ?? report.lastReadTime ?? ''; - }, [report.reportID, report.lastReadTime]); + return report.lastReadTime ?? ''; + }, [report.lastReadTime]); /** * The timestamp for the unread marker. From bed2343b88eb23dedfe9ac7e0f7f59ecff7c52b0 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 2 Dec 2024 15:10:24 +0100 Subject: [PATCH 02/19] Fix import --- src/libs/ReportUtils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e8d867ac99c0..eb6b79bbb1f5 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -87,11 +87,13 @@ import * as PolicyUtils from './PolicyUtils'; import type {LastVisibleMessage} from './ReportActionsUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; import * as TransactionUtils from './TransactionUtils'; -import * as UnreadIndicatorUpdaterHelper from './UnreadIndicatorUpdater'; import * as Url from './Url'; import type {AvatarSource} from './UserUtils'; import * as UserUtils from './UserUtils'; +// Dynamic Import to avoid circular dependency +const UnreadIndicatorUpdaterHelper = () => import('./UnreadIndicatorUpdater'); + type AvatarRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18; type SpendBreakdown = { @@ -632,7 +634,9 @@ Onyx.connect({ waitForCollectionCallback: true, callback: (value) => { allReports = value; - UnreadIndicatorUpdaterHelper.triggerUnreadUpdate(); + UnreadIndicatorUpdaterHelper().then((module) => { + module.triggerUnreadUpdate(); + }); // Each time a new report is added we will check to see if the user should be switched PriorityModeActions.autoSwitchToFocusMode(); From d1399eac1454aa3de78edcdbdaa7c6e15ab45711 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 2 Dec 2024 16:26:57 +0100 Subject: [PATCH 03/19] Fix after merging main --- src/libs/actions/Report.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 003a0064b376..1240c25fd8b3 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3891,7 +3891,7 @@ function prepareOnboardingOptimisticData( if (engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM) { const selfDMReportID = ReportUtils.findSelfDMReportID(); - const selfDMReport = ReportConnection.getReport(selfDMReportID ?? '-1'); + const selfDMReport = ReportUtils.getReport(selfDMReportID ?? '-1'); optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`, From f729c68f6be0a8245a5c91a7f43cf8e9dbb81f29 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 4 Dec 2024 17:23:58 +0100 Subject: [PATCH 04/19] Updates after merging main --- src/libs/actions/IOU.ts | 4 ++-- src/libs/actions/Report.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index c5c136e6c86d..53d7187dbf75 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7951,7 +7951,7 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea const updatedViolations = [...transactionViolations, newViolation]; const parentReportActionOptimistic = ReportUtils.getOptimisticDataForParentReportAction(reportID, createdReportActionComment.created, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; - const iouReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; + const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; const optimisticData: OnyxUpdate[] = [ { @@ -8074,7 +8074,7 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num const createdReportAction = ReportUtils.buildOptimisticUnHoldReportAction(); const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]; const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; - const iouReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; + const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; const optimisticData: OnyxUpdate[] = [ { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 7f16890167ef..05d7a697b209 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3500,7 +3500,7 @@ function prepareOnboardingOptimisticData( // Guides are assigned and tasks are posted in the #admins room for the MANAGE_TEAM onboarding action, except for emails that have a '+'. const shouldPostTasksInAdminsRoom = engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM && !currentUserEmail?.includes('+'); const integrationName = userReportedIntegration ? CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration] : ''; - const adminsChatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; + const adminsChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; const targetChatReport = shouldPostTasksInAdminsRoom ? adminsChatReport : ReportUtils.getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, currentUserAccountID]); const {reportID: targetChatReportID = '', policyID: targetChatPolicyID = ''} = targetChatReport ?? {}; const assignedGuideEmail = getPolicy(targetChatPolicyID)?.assignedGuide?.email ?? 'Setup Specialist'; From d98bf23a4f08711b2dcfb531fb5b2bc6e2c5460d Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 4 Dec 2024 17:32:40 +0100 Subject: [PATCH 05/19] Remove ReportActionsConnection --- src/libs/ReportActionsConnection.ts | 25 ------------------------- src/libs/actions/Policy/Policy.ts | 4 ++-- 2 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 src/libs/ReportActionsConnection.ts diff --git a/src/libs/ReportActionsConnection.ts b/src/libs/ReportActionsConnection.ts deleted file mode 100644 index e3c8a4c3cf60..000000000000 --- a/src/libs/ReportActionsConnection.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type {OnyxCollection} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReportActions} from '@src/types/onyx/ReportAction'; - -let allReportActions: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, - waitForCollectionCallback: true, - callback: (actions) => { - if (!actions) { - return; - } - - allReportActions = actions; - }, -}); - -// This function is used to get all reports -function getAllReportActions() { - return allReportActions; -} - -// eslint-disable-next-line import/prefer-default-export -export {getAllReportActions}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index e623f4c2c7a6..43e69bf08d2a 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -70,7 +70,7 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; -import * as ReportActionsConnection from '@libs/ReportActionsConnection'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -2455,7 +2455,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF }); // We need to move the report preview action from the DM to the workspace chat. - const parentReport = ReportActionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`]; + const parentReport = iouReport.parentReportID ? ReportActionsUtils.getAllReportActions(iouReport.parentReportID) : undefined; const parentReportActionID = iouReport.parentReportActionID; const reportPreview = iouReport?.parentReportID && parentReportActionID ? parentReport?.[parentReportActionID] : undefined; From 85d6e92d878bc423d27c0102b334611e2a869320 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 4 Dec 2024 17:33:48 +0100 Subject: [PATCH 06/19] Minor code improvement --- src/libs/markAllPolicyReportsAsRead.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/markAllPolicyReportsAsRead.ts b/src/libs/markAllPolicyReportsAsRead.ts index 5f9ea2042aa3..e01a351882a6 100644 --- a/src/libs/markAllPolicyReportsAsRead.ts +++ b/src/libs/markAllPolicyReportsAsRead.ts @@ -17,7 +17,7 @@ Onyx.connect({ export default function markAllPolicyReportsAsRead(policyID: string) { let delay = 0; Object.keys(allReports ?? {}).forEach((key: string) => { - const report: Report | null | undefined = allReports?.[key]; + const report = allReports?.[key]; if (report?.policyID !== policyID || !ReportUtils.isUnread(report)) { return; } From 808d09a0f8e8a7238abc0c0fb42fb18251ff0233 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 5 Dec 2024 10:04:58 +0100 Subject: [PATCH 07/19] Fixes after merging main --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 679256027967..09a792a18697 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5598,7 +5598,7 @@ function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportActio * @returns The URL to navigate to */ function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined { - const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; + const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; // If not a self DM, handle it as a regular money request if (!ReportUtils.isSelfDM(chatReport)) { From edd45374f4d1003451ad3d0833cb27251379dd73 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 5 Dec 2024 13:36:41 +0100 Subject: [PATCH 08/19] Use ReportUtils.getReport --- src/libs/DistanceRequestUtils.ts | 17 ++++------------- src/libs/Navigation/Navigation.ts | 15 ++------------- .../linkingConfig/getAdaptedStateFromPath.ts | 16 ++-------------- .../subscribePushNotification/index.ts | 15 +++------------ src/libs/TaskUtils.ts | 16 +++------------- 5 files changed, 14 insertions(+), 65 deletions(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index fe40ea67f905..9132ed3e6bce 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -1,9 +1,9 @@ -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {LastSelectedDistanceRates, OnyxInputOrEntry, Report, Transaction} from '@src/types/onyx'; +import type {LastSelectedDistanceRates, OnyxInputOrEntry, Transaction} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type Policy from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -29,15 +29,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter @@ -290,8 +281,8 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { * Returns custom unit rate ID for the distance transaction */ function getCustomUnitRateID(reportID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; + const report = ReportUtils.getReport(reportID); + const parentReport = report?.parentReportID ? ReportUtils.getReport(report?.parentReportID) : undefined; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? '-1'); let customUnitRateID: string = CONST.CUSTOM_UNITS.FAKE_P2P_ID; diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index eeb6db21447e..70ca284aa78b 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -1,14 +1,12 @@ import {findFocusedRoute} from '@react-navigation/core'; import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native'; import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native'; -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import Log from '@libs/Log'; import {isCentralPaneName, removePolicyIDParamFromState} from '@libs/NavigationUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; -import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; import ROUTES, {HYBRID_APP_ROUTES} from '@src/ROUTES'; import {PROTECTED_SCREENS} from '@src/SCREENS'; @@ -30,15 +28,6 @@ import setNavigationActionToMicrotaskQueue from './setNavigationActionToMicrotas import switchPolicyID from './switchPolicyID'; import type {NavigationStateRoute, RootStackParamList, State, StateOrRoute, SwitchPolicyIDParams} from './types'; -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { resolveNavigationIsReadyPromise = resolve; @@ -75,7 +64,7 @@ const dismissModal = (reportID?: string, ref = navigationRef) => { originalDismissModal(ref); return; } - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); originalDismissModalWithReport({reportID, ...report}, ref); }; // Re-exporting the closeRHPFlow here to fill in default value for navigationRef. The closeRHPFlow isn't defined in this file to avoid cyclic dependencies. diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 33a2ea9946a8..e718305e401d 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -1,8 +1,6 @@ import type {NavigationState, PartialState, Route} from '@react-navigation/native'; import {findFocusedRoute, getStateFromPath} from '@react-navigation/native'; import pick from 'lodash/pick'; -import type {OnyxCollection} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; import type {TupleToUnion} from 'type-fest'; import type {TopTabScreen} from '@components/FocusTrap/TOP_TAB_SCREENS'; import {isAnonymousUser} from '@libs/actions/Session'; @@ -10,13 +8,12 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {isCentralPaneName} from '@libs/NavigationUtils'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import extractPolicyIDFromQuery from '@navigation/extractPolicyIDFromQuery'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; -import ONYXKEYS from '@src/ONYXKEYS'; import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; -import type {Report} from '@src/types/onyx'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config, {normalizedConfigs} from './config'; import FULL_SCREEN_TO_RHP_MAPPING from './FULL_SCREEN_TO_RHP_MAPPING'; @@ -25,15 +22,6 @@ import getMatchingCentralPaneRouteForState from './getMatchingCentralPaneRouteFo import getOnboardingAdaptedState from './getOnboardingAdaptedState'; import replacePathInNestedState from './replacePathInNestedState'; -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - const RHP_SCREENS_OPENED_FROM_LHN = [ SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, @@ -171,7 +159,7 @@ function getMatchingRootRouteForRHPRoute(route: NavigationPartialRoute): Navigat // check for valid reportID in the route params // if the reportID is valid, we should navigate back to screen report in CPN const reportID = (route.params as Record)?.reportID; - if (allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportID) { + if (reportID && ReportUtils.getReport(reportID)?.reportID) { return {name: SCREENS.REPORT, params: {reportID}}; } } diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index 61af079f9ed1..dac9432074c7 100644 --- a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts +++ b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts @@ -1,6 +1,5 @@ import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; -import type {OnyxCollection} from 'react-native-onyx'; import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import Log from '@libs/Log'; @@ -9,13 +8,14 @@ import type {ReportActionPushNotificationData} from '@libs/Notification/PushNoti import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils'; import {extractPolicyIDFromPath} from '@libs/PolicyUtils'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import Visibility from '@libs/Visibility'; import {updateLastVisitedPath} from '@userActions/App'; import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {OnyxUpdatesFromServer, Report} from '@src/types/onyx'; +import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import PushNotification from '..'; @@ -30,15 +30,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - function getLastUpdateIDAppliedToClient(): Promise { return new Promise((resolve) => { Onyx.connect({ @@ -86,7 +77,7 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati Log.info('[PushNotification] Navigating to report', false, {reportID, reportActionID}); const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath); - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID.toString()); const policyEmployeeAccountIDs = policyID ? getPolicyEmployeeAccountIDs(policyID) : []; const reportBelongsToWorkspace = policyID && !isEmptyObject(report) && doesReportBelongToWorkspace(report, policyEmployeeAccountIDs, policyID); diff --git a/src/libs/TaskUtils.ts b/src/libs/TaskUtils.ts index 975c3e617ce5..42e268ce5830 100644 --- a/src/libs/TaskUtils.ts +++ b/src/libs/TaskUtils.ts @@ -1,7 +1,5 @@ -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import type {Message} from '@src/types/onyx/ReportAction'; @@ -9,15 +7,7 @@ import type ReportAction from '@src/types/onyx/ReportAction'; import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import {getReportActionHtml, getReportActionText} from './ReportActionsUtils'; - -let allReports: OnyxCollection = {}; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); +import * as ReportUtils from './ReportUtils'; /** * Check if the active route belongs to task edit flow. @@ -55,7 +45,7 @@ function getTaskTitleFromReport(taskReport: OnyxEntry, fallbackTitle = ' } function getTaskTitle(taskReportID: string, fallbackTitle = ''): string { - const taskReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]; + const taskReport = ReportUtils.getReport(taskReportID); return getTaskTitleFromReport(taskReport, fallbackTitle); } From c623446a7124ba9fe14da8b70bf9fb13aab67e9e Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 5 Dec 2024 14:33:54 +0100 Subject: [PATCH 09/19] Code improvements --- src/libs/DistanceRequestUtils.ts | 2 +- src/libs/actions/Report.ts | 50 +++++++++++++------------------ src/libs/actions/ReportActions.ts | 11 +------ src/libs/actions/Task.ts | 13 ++------ 4 files changed, 24 insertions(+), 52 deletions(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 9132ed3e6bce..11a403e8a0e0 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -282,7 +282,7 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { */ function getCustomUnitRateID(reportID: string) { const report = ReportUtils.getReport(reportID); - const parentReport = report?.parentReportID ? ReportUtils.getReport(report?.parentReportID) : undefined; + const parentReport = report?.parentReportID ? ReportUtils.getReport(report.parentReportID) : undefined; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? '-1'); let customUnitRateID: string = CONST.CUSTOM_UNITS.FAKE_P2P_ID; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index c99bbe0791ed..5fbf34cce02b 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -228,15 +228,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - let allPersonalDetails: OnyxEntry = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, @@ -543,7 +534,7 @@ function addActions(reportID: string, text = '', file?: FileObject) { lastReadTime: currentTime, }; - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); const shouldUpdateNotificationPrefernece = !isEmptyObject(report) && ReportUtils.getReportNotificationPreference(report) === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; if (shouldUpdateNotificationPrefernece) { @@ -721,7 +712,7 @@ function updateGroupChatName(reportID: string, reportName: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? null, + reportName: ReportUtils.getReport(reportID)?.reportName ?? null, pendingFields: { reportName: null, }, @@ -750,7 +741,7 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani }, ]; - const fetchedReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const fetchedReport = ReportUtils.getReport(reportID); const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -819,7 +810,7 @@ function openReport( const optimisticReport = reportActionsExist(reportID) ? {} : { - reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, + reportName: ReportUtils.getReport(reportID)?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, }; const optimisticData: OnyxUpdate[] = [ @@ -1044,7 +1035,7 @@ function openReport( } } - parameters.clientLastReadTime = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastReadTime ?? ''; + parameters.clientLastReadTime = ReportUtils.getReport(reportID)?.lastReadTime ?? ''; const paginationConfig = { resourceID: reportID, @@ -1155,7 +1146,7 @@ function navigateToAndOpenChildReport(childReportID = '-1', parentReportAction: Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(childReportID)); } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction.actorAccountID)])]; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; + const parentReport = ReportUtils.getReport(parentReportID); // Threads from DMs and selfDMs don't have a chatType. All other threads inherit the chatType from their parent const childReportChatType = parentReport && ReportUtils.isSelfDM(parentReport) ? undefined : parentReport?.chatType; const newChat = ReportUtils.buildOptimisticChatReport( @@ -1352,8 +1343,7 @@ function markCommentAsUnread(reportID: string, reportActionCreated: string) { }, null); // If no action created date is provided, use the last action's from other user - const actionCreationTime = - reportActionCreated || (latestReportActionFromOtherUsers?.created ?? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); + const actionCreationTime = reportActionCreated || (latestReportActionFromOtherUsers?.created ?? ReportUtils.getReport(reportID)?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); // We subtract 1 millisecond so that the lastReadTime is updated to just before a given reportAction's created date // For example, if we want to mark a report action with ID 100 and created date '2014-04-01 16:07:02.999' unread, we set the lastReadTime to '2014-04-01 16:07:02.998' @@ -1527,7 +1517,7 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { lastVisibleActionCreated: '', }; const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportUtils.getLastVisibleMessage(originalReportID, optimisticReportActions as ReportActions); - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (lastMessageText || lastMessageTranslationKey) { const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(originalReportID, canUserPerformWriteAction, optimisticReportActions as ReportActions); @@ -1913,7 +1903,7 @@ function toggleSubscribeToChildReport(childReportID = '-1', parentReportAction: } } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction?.actorAccountID)])]; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; + const parentReport = ReportUtils.getReport(parentReportID); const newChat = ReportUtils.buildOptimisticChatReport( participantAccountIDs, ReportActionsUtils.getReportActionText(parentReportAction), @@ -2388,7 +2378,7 @@ function addPolicyReport(policyReport: ReportUtils.OptimisticChatReport) { /** Deletes a report, along with its reportActions, any linked reports, and any linked IOU report. */ function deleteReport(reportID: string, shouldDeleteChildReports = false) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); const onyxData: Record = { [`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]: null, [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]: null, @@ -2552,7 +2542,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi } // We don't want to send a local notification if the user preference is daily, mute or hidden. - const notificationPreference = ReportUtils.getReportNotificationPreference(allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]); + const notificationPreference = ReportUtils.getReportNotificationPreference(ReportUtils.getReport(reportID)); if (notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS) { Log.info(`${tag} No notification because user preference is to be notified: ${notificationPreference}`); return false; @@ -2570,7 +2560,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi return false; } - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (!report || (report && report.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE)) { Log.info(`${tag} No notification because the report does not exist or is pending deleted`, false); return false; @@ -2605,7 +2595,7 @@ function showReportActionNotification(reportID: string, reportAction: ReportActi Log.info('[LocalNotification] Creating notification'); const localReportID = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - const report = allReports?.[localReportID] ?? null; + const report = ReportUtils.getReport(reportID) ?? null; if (!report) { Log.hmmm("[LocalNotification] couldn't show report action notification because the report wasn't found", {localReportID, reportActionID: reportAction.reportActionID}); return; @@ -2890,7 +2880,7 @@ function joinRoom(report: OnyxEntry) { } function leaveGroupChat(reportID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (!report) { Log.warn('Attempting to leave Group Chat that does not existing locally'); return; @@ -2947,7 +2937,7 @@ function leaveGroupChat(reportID: string) { /** Leave a report by setting the state to submitted and closed */ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = false) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (!report) { return; @@ -3051,7 +3041,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal /** Invites people to a room */ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmailsToAccountIDs) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (!report) { return; } @@ -3156,7 +3146,7 @@ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmails } function clearAddRoomMemberError(reportID: string, invitedAccountID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { pendingChatMembers: report?.pendingChatMembers?.filter((pendingChatMember) => pendingChatMember.accountID !== invitedAccountID), participants: { @@ -3218,7 +3208,7 @@ function inviteToGroupChat(reportID: string, inviteeEmailsToAccountIDs: InvitedE * Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details */ function removeFromRoom(reportID: string, targetAccountIDs: number[]) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (!report) { return; } @@ -4082,7 +4072,7 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt }, }; - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const report = ReportUtils.getReport(reportId); const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { @@ -4157,7 +4147,7 @@ function resolveActionableReportMentionWhisper( }, }; - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const report = ReportUtils.getReport(reportId); const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index d880c1a8fb20..f9daa5bcbfbc 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -17,15 +17,6 @@ Onyx.connect({ callback: (value) => (allReportActions = value), }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - function clearReportActionErrors(reportID: string, reportAction: ReportAction, keys?: string[]) { const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction); @@ -89,7 +80,7 @@ function clearAllRelatedReportActionErrors(reportID: string, reportAction: Repor clearReportActionErrors(reportID, reportAction, keys); - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); if (report?.parentReportID && report?.parentReportActionID && ignore !== 'parent') { const parentReportAction = ReportActionUtils.getReportAction(report.parentReportID, report.parentReportActionID); const parentErrorKeys = Object.keys(parentReportAction?.errors ?? {}).filter((err) => errorKeys.includes(err)); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index b000bf97d99c..75ba6bf9761a 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -65,15 +65,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - let allReportActions: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, @@ -964,7 +955,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry, sessionAccountID } function clearTaskErrors(reportID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); // Delete the task preview in the parent report if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { From 88a6349188c9a52795082de1a338cf3131426625 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 5 Dec 2024 14:41:40 +0100 Subject: [PATCH 10/19] Remove unnecessary changes --- src/libs/actions/ReportActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index f9daa5bcbfbc..38e90d2bd799 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -4,13 +4,13 @@ import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type * as OnyxTypes from '@src/types/onyx'; +import type {ReportActions} from '@src/types/onyx'; import type ReportAction from '@src/types/onyx/ReportAction'; import * as Report from './Report'; type IgnoreDirection = 'parent' | 'child'; -let allReportActions: OnyxCollection; +let allReportActions: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, waitForCollectionCallback: true, From cd0a31ec4e364ae2e8935e5421e03e4ce22050d0 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 5 Dec 2024 15:34:00 +0100 Subject: [PATCH 11/19] Code improvements --- src/libs/TransactionUtils/index.ts | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 8319732dd325..2b9602da3fb7 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -44,15 +44,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection = {}; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - let allTransactionViolations: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, @@ -240,9 +231,11 @@ function isCreatedMissing(transaction: OnyxEntry) { } function areRequiredFieldsEmpty(transaction: OnyxEntry): boolean { - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`] ?? null; + const parentReport = transaction?.reportID ? ReportUtils.getReport(transaction.reportID) : undefined; const isFromExpenseReport = parentReport?.type === CONST.REPORT.TYPE.EXPENSE; - const isSplitPolicyExpenseChat = !!transaction?.comment?.splits?.some((participant) => allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`]?.isOwnPolicyExpenseChat); + const isSplitPolicyExpenseChat = !!transaction?.comment?.splits?.some( + (participant) => participant.chatReportID && ReportUtils.getReport(participant.chatReportID)?.isOwnPolicyExpenseChat, + ); const isMerchantRequired = isFromExpenseReport || isSplitPolicyExpenseChat; return (isMerchantRequired && isMerchantMissing(transaction)) || isAmountMissing(transaction) || isCreatedMissing(transaction); } @@ -1126,7 +1119,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor const keys = fieldsToCompare[fieldName]; const firstTransaction = transactions.at(0); const isFirstTransactionCommentEmptyObject = typeof firstTransaction?.comment === 'object' && firstTransaction?.comment?.comment === ''; - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; + const report = ReportUtils.getReport(reportID); const policy = PolicyUtils.getPolicy(report?.policyID); const areAllFieldsEqualForKey = areAllFieldsEqual(transactions, (item) => keys.map((key) => item?.[key]).join('|')); @@ -1201,7 +1194,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor } function getTransactionID(threadReportID: string): string { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${threadReportID}`] ?? null; + const report = ReportUtils.getReport(threadReportID); const parentReportAction = ReportActionsUtils.getReportAction(report?.parentReportID ?? '', report?.parentReportActionID ?? ''); const IOUTransactionID = ReportActionsUtils.isMoneyRequestAction(parentReportAction) ? ReportActionsUtils.getOriginalMessage(parentReportAction)?.IOUTransactionID ?? '-1' : '-1'; From fd08b489a9005b6e2b7e189e9b2439987f2df578 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 9 Dec 2024 17:29:31 +0100 Subject: [PATCH 12/19] Code improvements --- src/libs/ReportUtils.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a810bb22a6f5..99806f9aa2d5 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1108,8 +1108,7 @@ function isInvoiceRoomWithID(reportID?: string): boolean { return false; } - const report = getReport(reportID); - return isInvoiceRoom(report); + return isInvoiceRoom(getReport(reportID)); } /** @@ -1516,8 +1515,7 @@ function isArchivedRoomWithID(reportID?: string) { return false; } - const report = getReport(reportID); - return isArchivedRoom(report, getReportNameValuePairs(reportID)); + return isArchivedRoom(getReport(reportID), getReportNameValuePairs(reportID)); } /** @@ -6776,8 +6774,7 @@ function chatIncludesChronosWithID(reportID?: string): boolean { return false; } - const report = getReport(reportID); - return chatIncludesChronos(report); + return chatIncludesChronos(getReport(reportID)); } /** From d01ac8d7677dd9bd7305dd8215fb99f3aa5e62b3 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Tue, 10 Dec 2024 11:45:21 +0100 Subject: [PATCH 13/19] Get rid of outdated code --- src/libs/actions/Task.ts | 2 -- src/pages/home/report/ReportActionsList.tsx | 8 ++------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 75ba6bf9761a..5f353a8815f7 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -311,8 +311,6 @@ function createTaskAndNavigate( API.write(WRITE_COMMANDS.CREATE_TASK, parameters, {optimisticData, successData, failureData}); - Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, {lastReadTime: currentTime}); - if (!isCreatedUsingMarkdown) { clearOutTaskInfo(); Navigation.dismissModal(parentReportID); diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index d162bc0a89ed..6530fcdacab3 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -206,10 +206,6 @@ function ReportActionsList({ ); const prevSortedVisibleReportActionsObjects = usePrevious(sortedVisibleReportActionsObjects); - const reportLastReadTime = useMemo(() => { - return report.lastReadTime ?? ''; - }, [report.lastReadTime]); - /** * The timestamp for the unread marker. * @@ -218,9 +214,9 @@ function ReportActionsList({ * - marks a message as read/unread * - reads a new message as it is received */ - const [unreadMarkerTime, setUnreadMarkerTime] = useState(reportLastReadTime); + const [unreadMarkerTime, setUnreadMarkerTime] = useState(report.lastReadTime ?? ''); useEffect(() => { - setUnreadMarkerTime(reportLastReadTime); + setUnreadMarkerTime(report.lastReadTime ?? ''); // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, [report.reportID]); From 81a912bec69f31ba46482b5ae435e814cdfa4a61 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 09:59:29 +0100 Subject: [PATCH 14/19] Revert "Use ReportUtils.getReport" This reverts commit edd45374 --- src/libs/DistanceRequestUtils.ts | 17 +++++++++++++---- src/libs/Navigation/Navigation.ts | 15 +++++++++++++-- .../linkingConfig/getAdaptedStateFromPath.ts | 16 ++++++++++++++-- .../subscribePushNotification/index.ts | 15 ++++++++++++--- src/libs/TaskUtils.ts | 16 +++++++++++++--- 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 11a403e8a0e0..8e366bc69b3f 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -1,9 +1,9 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {LastSelectedDistanceRates, OnyxInputOrEntry, Transaction} from '@src/types/onyx'; +import type {LastSelectedDistanceRates, OnyxInputOrEntry, Report, Transaction} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type Policy from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -29,6 +29,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter @@ -281,8 +290,8 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { * Returns custom unit rate ID for the distance transaction */ function getCustomUnitRateID(reportID: string) { - const report = ReportUtils.getReport(reportID); - const parentReport = report?.parentReportID ? ReportUtils.getReport(report.parentReportID) : undefined; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? '-1'); let customUnitRateID: string = CONST.CUSTOM_UNITS.FAKE_P2P_ID; diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 70ca284aa78b..eeb6db21447e 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -1,12 +1,14 @@ import {findFocusedRoute} from '@react-navigation/core'; import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native'; import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import {isCentralPaneName, removePolicyIDParamFromState} from '@libs/NavigationUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; import ROUTES, {HYBRID_APP_ROUTES} from '@src/ROUTES'; import {PROTECTED_SCREENS} from '@src/SCREENS'; @@ -28,6 +30,15 @@ import setNavigationActionToMicrotaskQueue from './setNavigationActionToMicrotas import switchPolicyID from './switchPolicyID'; import type {NavigationStateRoute, RootStackParamList, State, StateOrRoute, SwitchPolicyIDParams} from './types'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { resolveNavigationIsReadyPromise = resolve; @@ -64,7 +75,7 @@ const dismissModal = (reportID?: string, ref = navigationRef) => { originalDismissModal(ref); return; } - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; originalDismissModalWithReport({reportID, ...report}, ref); }; // Re-exporting the closeRHPFlow here to fill in default value for navigationRef. The closeRHPFlow isn't defined in this file to avoid cyclic dependencies. diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 72951a34103f..ef927e6f2cf5 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -1,6 +1,8 @@ import type {NavigationState, PartialState, Route} from '@react-navigation/native'; import {findFocusedRoute, getStateFromPath} from '@react-navigation/native'; import pick from 'lodash/pick'; +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import type {TupleToUnion} from 'type-fest'; import type {TopTabScreen} from '@components/FocusTrap/TOP_TAB_SCREENS'; import {isAnonymousUser} from '@libs/actions/Session'; @@ -8,12 +10,13 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {isCentralPaneName} from '@libs/NavigationUtils'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import extractPolicyIDFromQuery from '@navigation/extractPolicyIDFromQuery'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; +import type {Report} from '@src/types/onyx'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config, {normalizedConfigs} from './config'; import FULL_SCREEN_TO_RHP_MAPPING from './FULL_SCREEN_TO_RHP_MAPPING'; @@ -22,6 +25,15 @@ import getMatchingCentralPaneRouteForState from './getMatchingCentralPaneRouteFo import getOnboardingAdaptedState from './getOnboardingAdaptedState'; import replacePathInNestedState from './replacePathInNestedState'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + const RHP_SCREENS_OPENED_FROM_LHN = [ SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, @@ -159,7 +171,7 @@ function getMatchingRootRouteForRHPRoute(route: NavigationPartialRoute): Navigat // check for valid reportID in the route params // if the reportID is valid, we should navigate back to screen report in CPN const reportID = (route.params as Record)?.reportID; - if (reportID && ReportUtils.getReport(reportID)?.reportID) { + if (allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportID) { return {name: SCREENS.REPORT, params: {reportID}}; } } diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index dac9432074c7..61af079f9ed1 100644 --- a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts +++ b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts @@ -1,5 +1,6 @@ import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import Log from '@libs/Log'; @@ -8,14 +9,13 @@ import type {ReportActionPushNotificationData} from '@libs/Notification/PushNoti import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils'; import {extractPolicyIDFromPath} from '@libs/PolicyUtils'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import Visibility from '@libs/Visibility'; import {updateLastVisitedPath} from '@userActions/App'; import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {OnyxUpdatesFromServer} from '@src/types/onyx'; +import type {OnyxUpdatesFromServer, Report} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import PushNotification from '..'; @@ -30,6 +30,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function getLastUpdateIDAppliedToClient(): Promise { return new Promise((resolve) => { Onyx.connect({ @@ -77,7 +86,7 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati Log.info('[PushNotification] Navigating to report', false, {reportID, reportActionID}); const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath); - const report = ReportUtils.getReport(reportID.toString()); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const policyEmployeeAccountIDs = policyID ? getPolicyEmployeeAccountIDs(policyID) : []; const reportBelongsToWorkspace = policyID && !isEmptyObject(report) && doesReportBelongToWorkspace(report, policyEmployeeAccountIDs, policyID); diff --git a/src/libs/TaskUtils.ts b/src/libs/TaskUtils.ts index 42e268ce5830..975c3e617ce5 100644 --- a/src/libs/TaskUtils.ts +++ b/src/libs/TaskUtils.ts @@ -1,5 +1,7 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import type {Message} from '@src/types/onyx/ReportAction'; @@ -7,7 +9,15 @@ import type ReportAction from '@src/types/onyx/ReportAction'; import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import {getReportActionHtml, getReportActionText} from './ReportActionsUtils'; -import * as ReportUtils from './ReportUtils'; + +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); /** * Check if the active route belongs to task edit flow. @@ -45,7 +55,7 @@ function getTaskTitleFromReport(taskReport: OnyxEntry, fallbackTitle = ' } function getTaskTitle(taskReportID: string, fallbackTitle = ''): string { - const taskReport = ReportUtils.getReport(taskReportID); + const taskReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]; return getTaskTitleFromReport(taskReport, fallbackTitle); } From ae50129c0bd26a2b7b77854b2a10581de896fe25 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 10:06:55 +0100 Subject: [PATCH 15/19] Remove ReportUtils.getReport usage --- src/libs/DistanceRequestUtils.ts | 2 +- src/libs/TransactionUtils/index.ts | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 8e366bc69b3f..fe40ea67f905 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -291,7 +291,7 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { */ function getCustomUnitRateID(reportID: string) { const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? '-1'); let customUnitRateID: string = CONST.CUSTOM_UNITS.FAKE_P2P_ID; diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 2b9602da3fb7..81a738f724e0 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -44,6 +44,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let allTransactionViolations: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, @@ -231,11 +240,9 @@ function isCreatedMissing(transaction: OnyxEntry) { } function areRequiredFieldsEmpty(transaction: OnyxEntry): boolean { - const parentReport = transaction?.reportID ? ReportUtils.getReport(transaction.reportID) : undefined; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`]; const isFromExpenseReport = parentReport?.type === CONST.REPORT.TYPE.EXPENSE; - const isSplitPolicyExpenseChat = !!transaction?.comment?.splits?.some( - (participant) => participant.chatReportID && ReportUtils.getReport(participant.chatReportID)?.isOwnPolicyExpenseChat, - ); + const isSplitPolicyExpenseChat = !!transaction?.comment?.splits?.some((participant) => allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`]?.isOwnPolicyExpenseChat); const isMerchantRequired = isFromExpenseReport || isSplitPolicyExpenseChat; return (isMerchantRequired && isMerchantMissing(transaction)) || isAmountMissing(transaction) || isCreatedMissing(transaction); } @@ -1119,7 +1126,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor const keys = fieldsToCompare[fieldName]; const firstTransaction = transactions.at(0); const isFirstTransactionCommentEmptyObject = typeof firstTransaction?.comment === 'object' && firstTransaction?.comment?.comment === ''; - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const policy = PolicyUtils.getPolicy(report?.policyID); const areAllFieldsEqualForKey = areAllFieldsEqual(transactions, (item) => keys.map((key) => item?.[key]).join('|')); @@ -1194,7 +1201,7 @@ function compareDuplicateTransactionFields(reviewingTransactionID: string, repor } function getTransactionID(threadReportID: string): string { - const report = ReportUtils.getReport(threadReportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${threadReportID}`]; const parentReportAction = ReportActionsUtils.getReportAction(report?.parentReportID ?? '', report?.parentReportActionID ?? ''); const IOUTransactionID = ReportActionsUtils.isMoneyRequestAction(parentReportAction) ? ReportActionsUtils.getOriginalMessage(parentReportAction)?.IOUTransactionID ?? '-1' : '-1'; From c5dfcbcbd9526f9e5a3e877aecc504f580fd73f0 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 10:20:37 +0100 Subject: [PATCH 16/19] Remove ReportUtils.getReport usage and fix lint error after merging main --- src/libs/actions/Report.ts | 64 ++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index bad62b6f7332..7baf66adc5c5 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -105,13 +105,13 @@ import type { PolicyReportField, QuickAction, RecentlyUsedReportFields, + Report, ReportAction, ReportActionReactions, ReportUserIsTyping, } from '@src/types/onyx'; import type {Decision} from '@src/types/onyx/OriginalMessage'; import type {ConnectionName} from '@src/types/onyx/Policy'; -import type Report from '@src/types/onyx/Report'; import type {NotificationPreference, Participants, Participant as ReportParticipant, RoomVisibility, WriteCapability} from '@src/types/onyx/Report'; import type {Message, ReportActions} from '@src/types/onyx/ReportAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -219,6 +219,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + let isNetworkOffline = false; let networkStatus: NetworkStatus; Onyx.connect({ @@ -319,7 +328,7 @@ registerPaginationConfig({ resourceCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS, pageCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES, sortItems: (reportActions, reportID) => { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); return ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, canUserPerformWriteAction, true); }, @@ -535,7 +544,7 @@ function addActions(reportID: string, text = '', file?: FileObject) { lastReadTime: currentTime, }; - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const shouldUpdateNotificationPrefernece = !isEmptyObject(report) && ReportUtils.getReportNotificationPreference(report) === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; if (shouldUpdateNotificationPrefernece) { @@ -713,7 +722,7 @@ function updateGroupChatName(reportID: string, reportName: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - reportName: ReportUtils.getReport(reportID)?.reportName ?? null, + reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? null, pendingFields: { reportName: null, }, @@ -742,7 +751,7 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani }, ]; - const fetchedReport = ReportUtils.getReport(reportID); + const fetchedReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -811,7 +820,7 @@ function openReport( const optimisticReport = reportActionsExist(reportID) ? {} : { - reportName: ReportUtils.getReport(reportID)?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, + reportName: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, }; const optimisticData: OnyxUpdate[] = [ @@ -1061,7 +1070,7 @@ function openReport( } } - parameters.clientLastReadTime = ReportUtils.getReport(reportID)?.lastReadTime ?? ''; + parameters.clientLastReadTime = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastReadTime ?? ''; const paginationConfig = { resourceID: reportID, @@ -1172,7 +1181,7 @@ function navigateToAndOpenChildReport(childReportID = '-1', parentReportAction: Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(childReportID)); } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction.actorAccountID)])]; - const parentReport = ReportUtils.getReport(parentReportID); + 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 && ReportUtils.isSelfDM(parentReport) ? undefined : parentReport?.chatType; const newChat = ReportUtils.buildOptimisticChatReport( @@ -1369,7 +1378,8 @@ function markCommentAsUnread(reportID: string, reportActionCreated: string) { }, null); // If no action created date is provided, use the last action's from other user - const actionCreationTime = reportActionCreated || (latestReportActionFromOtherUsers?.created ?? ReportUtils.getReport(reportID)?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); + const actionCreationTime = + reportActionCreated || (latestReportActionFromOtherUsers?.created ?? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.lastVisibleActionCreated ?? DateUtils.getDBTime(0)); // We subtract 1 millisecond so that the lastReadTime is updated to just before a given reportAction's created date // For example, if we want to mark a report action with ID 100 and created date '2014-04-01 16:07:02.999' unread, we set the lastReadTime to '2014-04-01 16:07:02.998' @@ -1543,7 +1553,7 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { lastVisibleActionCreated: '', }; const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportUtils.getLastVisibleMessage(originalReportID, optimisticReportActions as ReportActions); - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (lastMessageText || lastMessageTranslationKey) { const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(originalReportID, canUserPerformWriteAction, optimisticReportActions as ReportActions); @@ -1686,7 +1696,7 @@ function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMar /** Saves a new message for a comment. Marks the comment as edited, which will be reflected in the UI. */ function editReportComment(reportID: string, originalReportAction: OnyxEntry, textForNewComment: string, videoAttributeCache?: Record) { const originalReportID = ReportUtils.getOriginalReportID(reportID, originalReportAction); - const report = ReportUtils.getReport(originalReportID ?? '-1'); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${originalReportID}`]; const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (!originalReportID || !originalReportAction) { @@ -1929,7 +1939,7 @@ function toggleSubscribeToChildReport(childReportID = '-1', parentReportAction: } } else { const participantAccountIDs = [...new Set([currentUserAccountID, Number(parentReportAction?.actorAccountID)])]; - const parentReport = ReportUtils.getReport(parentReportID); + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; const newChat = ReportUtils.buildOptimisticChatReport( participantAccountIDs, ReportActionsUtils.getReportActionText(parentReportAction), @@ -2205,7 +2215,7 @@ function updateDescription(reportID: string, previousValue: string, newValue: st const parsedDescription = ReportUtils.getParsedComment(newValue, {reportID}); const optimisticDescriptionUpdatedReportAction = ReportUtils.buildOptimisticRoomDescriptionUpdatedReportAction(parsedDescription); - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const optimisticData: OnyxUpdate[] = [ { @@ -2410,7 +2420,7 @@ function addPolicyReport(policyReport: ReportUtils.OptimisticChatReport) { /** Deletes a report, along with its reportActions, any linked reports, and any linked IOU report. */ function deleteReport(reportID: string, shouldDeleteChildReports = false) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const onyxData: Record = { [`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]: null, [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]: null, @@ -2574,7 +2584,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi } // We don't want to send a local notification if the user preference is daily, mute or hidden. - const notificationPreference = ReportUtils.getReportNotificationPreference(ReportUtils.getReport(reportID)); + const notificationPreference = ReportUtils.getReportNotificationPreference(allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]); if (notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS) { Log.info(`${tag} No notification because user preference is to be notified: ${notificationPreference}`); return false; @@ -2592,7 +2602,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi return false; } - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report || (report && report.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE)) { Log.info(`${tag} No notification because the report does not exist or is pending deleted`, false); return false; @@ -2627,7 +2637,7 @@ function showReportActionNotification(reportID: string, reportAction: ReportActi Log.info('[LocalNotification] Creating notification'); const localReportID = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - const report = ReportUtils.getReport(reportID) ?? null; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { Log.hmmm("[LocalNotification] couldn't show report action notification because the report wasn't found", {localReportID, reportActionID: reportAction.reportActionID}); return; @@ -2912,7 +2922,7 @@ function joinRoom(report: OnyxEntry) { } function leaveGroupChat(reportID: string) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { Log.warn('Attempting to leave Group Chat that does not existing locally'); return; @@ -2969,7 +2979,7 @@ function leaveGroupChat(reportID: string) { /** Leave a report by setting the state to submitted and closed */ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = false) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; @@ -3073,7 +3083,7 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal /** Invites people to a room */ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmailsToAccountIDs) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; } @@ -3178,7 +3188,7 @@ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: InvitedEmails } function clearAddRoomMemberError(reportID: string, invitedAccountID: string) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { pendingChatMembers: report?.pendingChatMembers?.filter((pendingChatMember) => pendingChatMember.accountID !== invitedAccountID), participants: { @@ -3240,7 +3250,7 @@ function inviteToGroupChat(reportID: string, inviteeEmailsToAccountIDs: InvitedE * Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details */ function removeFromRoom(reportID: string, targetAccountIDs: number[]) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (!report) { return; } @@ -3523,7 +3533,7 @@ function prepareOnboardingOptimisticData( // Guides are assigned and tasks are posted in the #admins room for the MANAGE_TEAM onboarding action, except for emails that have a '+'. const shouldPostTasksInAdminsRoom = engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM && !currentUserEmail?.includes('+'); const integrationName = userReportedIntegration ? CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration] : ''; - const adminsChatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; + const adminsChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`]; const targetChatReport = shouldPostTasksInAdminsRoom ? adminsChatReport : ReportUtils.getChatByParticipants([CONST.ACCOUNT_ID.CONCIERGE, currentUserAccountID]); const {reportID: targetChatReportID = '', policyID: targetChatPolicyID = ''} = targetChatReport ?? {}; const assignedGuideEmail = getPolicy(targetChatPolicyID)?.assignedGuide?.email ?? 'Setup Specialist'; @@ -3844,7 +3854,7 @@ function prepareOnboardingOptimisticData( lastVisibleActionCreated: '', hasOutstandingChildTask: false, }; - const report = ReportUtils.getReport(targetChatReportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`]; const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportActionsUtils.getLastVisibleMessage(targetChatReportID, canUserPerformWriteAction); if (lastMessageText || lastMessageTranslationKey) { @@ -3961,7 +3971,7 @@ function prepareOnboardingOptimisticData( if (engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM) { const selfDMReportID = ReportUtils.findSelfDMReportID(); - const selfDMReport = ReportUtils.getReport(selfDMReportID ?? '-1'); + const selfDMReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`]; optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`, @@ -4150,7 +4160,7 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt }, }; - const report = ReportUtils.getReport(reportId); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { @@ -4225,7 +4235,7 @@ function resolveActionableReportMentionWhisper( }, }; - const report = ReportUtils.getReport(reportId); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { From 815b4ede21991d6a29f84123774a0f1ad85de4ab Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 10:49:54 +0100 Subject: [PATCH 17/19] Clean up --- src/libs/actions/Policy/Policy.ts | 13 +++++++++++-- src/libs/actions/ReportActions.ts | 15 ++++++++++++--- src/libs/actions/Task.ts | 15 ++++++++++++--- .../report/ContextMenu/ContextMenuActions.tsx | 19 +++++++++++++++---- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index f40b14508987..f81539d1e921 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -71,7 +71,6 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -87,6 +86,7 @@ import type { ReimbursementAccount, Report, ReportAction, + ReportActions, Request, TaxRatesWithDefault, Transaction, @@ -181,6 +181,15 @@ Onyx.connect({ }, }); +let allReportActions: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + waitForCollectionCallback: true, + callback: (actions) => { + allReportActions = actions; + }, +}); + let sessionEmail = ''; let sessionAccountID = 0; Onyx.connect({ @@ -2499,7 +2508,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF }); // We need to move the report preview action from the DM to the workspace chat. - const parentReport = iouReport.parentReportID ? ReportActionsUtils.getAllReportActions(iouReport.parentReportID) : undefined; + const parentReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`]; const parentReportActionID = iouReport.parentReportActionID; const reportPreview = iouReport?.parentReportID && parentReportActionID ? parentReport?.[parentReportActionID] : undefined; diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index 38e90d2bd799..d880c1a8fb20 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -4,19 +4,28 @@ import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReportActions} from '@src/types/onyx'; +import type * as OnyxTypes from '@src/types/onyx'; import type ReportAction from '@src/types/onyx/ReportAction'; import * as Report from './Report'; type IgnoreDirection = 'parent' | 'child'; -let allReportActions: OnyxCollection; +let allReportActions: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, waitForCollectionCallback: true, callback: (value) => (allReportActions = value), }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + function clearReportActionErrors(reportID: string, reportAction: ReportAction, keys?: string[]) { const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction); @@ -80,7 +89,7 @@ function clearAllRelatedReportActionErrors(reportID: string, reportAction: Repor clearReportActionErrors(reportID, reportAction, keys); - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; if (report?.parentReportID && report?.parentReportActionID && ignore !== 'parent') { const parentReportAction = ReportActionUtils.getReportAction(report.parentReportID, report.parentReportActionID); const parentErrorKeys = Object.keys(parentReportAction?.errors ?? {}).filter((err) => errorKeys.includes(err)); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index fbb993aa0fa9..ffc6230a6ca3 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -78,6 +78,15 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + /** * Clears out the task info from the store */ @@ -127,7 +136,7 @@ function createTaskAndNavigate( const currentTime = DateUtils.getDBTimeWithSkew(); const lastCommentText = ReportUtils.formatReportLastMessageText(ReportActionsUtils.getReportActionText(optimisticAddCommentReport.reportAction)); - const parentReport = ReportUtils.getReport(parentReportID); + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`]; const optimisticParentReport = { lastVisibleActionCreated: optimisticAddCommentReport.reportAction.created, lastMessageText: lastCommentText, @@ -973,7 +982,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry, sessionAccountID } function clearTaskErrors(reportID: string) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; // Delete the task preview in the parent report if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index a31137e53c6a..223169849a08 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -4,7 +4,8 @@ import React from 'react'; import {InteractionManager} from 'react-native'; // eslint-disable-next-line no-restricted-imports import type {GestureResponderEvent, Text, View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import type {Emoji} from '@assets/emojis/types'; import * as Expensicons from '@components/Icon/Expensicons'; import MiniQuickEmojiReactions from '@components/Reactions/MiniQuickEmojiReactions'; @@ -28,12 +29,22 @@ import * as Download from '@userActions/Download'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction, User} from '@src/types/onyx'; +import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Report as ReportType, Transaction, User} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type {ContextMenuAnchor} from './ReportActionContextMenu'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => { + allReports = value; + }, +}); + /** Gets the HTML version of the message in an action */ function getActionHtml(reportAction: OnyxInputOrEntry): string { const message = Array.isArray(reportAction?.message) ? reportAction?.message?.at(-1) ?? null : reportAction?.message ?? null; @@ -476,7 +487,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const {label, errorMessage} = ReportActionsUtils.getOriginalMessage(reportAction) ?? {label: '', errorMessage: ''}; setClipboardMessage(Localize.translateLocal('report.actions.type.integrationSyncFailed', {label, errorMessage})); } else if (ReportActionsUtils.isCardIssuedAction(reportAction)) { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; setClipboardMessage(ReportActionsUtils.getCardIssuedMessage(reportAction, true, report?.policyID, hasCard)); } else if (ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION)) { setClipboardMessage(ReportActionsUtils.getRemovedConnectionMessage(reportAction)); @@ -604,7 +615,7 @@ const ContextMenuActions: ContextMenuAction[] = [ successIcon: Expensicons.Checkmark, shouldShow: ({type, isProduction}) => type === CONST.CONTEXT_MENU_TYPES.REPORT && !isProduction, onPress: (closePopover, {reportID}) => { - const report = ReportUtils.getReport(reportID); + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; Clipboard.setString(JSON.stringify(report, null, 4)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, From 6aa985eca6d666fc5984dcaf62b435881dab8f7c Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 11:03:28 +0100 Subject: [PATCH 18/19] Lint fix --- .../report/ContextMenu/ContextMenuActions.tsx | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 223169849a08..a31137e53c6a 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -4,8 +4,7 @@ import React from 'react'; import {InteractionManager} from 'react-native'; // eslint-disable-next-line no-restricted-imports import type {GestureResponderEvent, Text, View} from 'react-native'; -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import type {Emoji} from '@assets/emojis/types'; import * as Expensicons from '@components/Icon/Expensicons'; import MiniQuickEmojiReactions from '@components/Reactions/MiniQuickEmojiReactions'; @@ -29,22 +28,12 @@ import * as Download from '@userActions/Download'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Report as ReportType, Transaction, User} from '@src/types/onyx'; +import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction, User} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type {ContextMenuAnchor} from './ReportActionContextMenu'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - /** Gets the HTML version of the message in an action */ function getActionHtml(reportAction: OnyxInputOrEntry): string { const message = Array.isArray(reportAction?.message) ? reportAction?.message?.at(-1) ?? null : reportAction?.message ?? null; @@ -487,7 +476,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const {label, errorMessage} = ReportActionsUtils.getOriginalMessage(reportAction) ?? {label: '', errorMessage: ''}; setClipboardMessage(Localize.translateLocal('report.actions.type.integrationSyncFailed', {label, errorMessage})); } else if (ReportActionsUtils.isCardIssuedAction(reportAction)) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); setClipboardMessage(ReportActionsUtils.getCardIssuedMessage(reportAction, true, report?.policyID, hasCard)); } else if (ReportActionsUtils.isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.DELETE_INTEGRATION)) { setClipboardMessage(ReportActionsUtils.getRemovedConnectionMessage(reportAction)); @@ -615,7 +604,7 @@ const ContextMenuActions: ContextMenuAction[] = [ successIcon: Expensicons.Checkmark, shouldShow: ({type, isProduction}) => type === CONST.CONTEXT_MENU_TYPES.REPORT && !isProduction, onPress: (closePopover, {reportID}) => { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const report = ReportUtils.getReport(reportID); Clipboard.setString(JSON.stringify(report, null, 4)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, From b0d3624793a965f52f3127a0e81b275311b8801a Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 11 Dec 2024 11:13:53 +0100 Subject: [PATCH 19/19] Re-run checks