Skip to content

Commit

Permalink
Merge pull request Expensify#43632 from nkdengineer/fix/40316
Browse files Browse the repository at this point in the history
Remove export ReportUtil.getReport function
  • Loading branch information
tgolen authored Jun 20, 2024
2 parents 57663ed + 45a3c12 commit 9a6019a
Show file tree
Hide file tree
Showing 26 changed files with 245 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ import type {ValueOf} from 'type-fest';
import type {Attachment} from '@components/Attachments/types';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import {getReport} from '@libs/ReportUtils';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import CONST from '@src/CONST';
import type {ReportAction, ReportActions} from '@src/types/onyx';
import type {Note} from '@src/types/onyx/Report';

/**
* Constructs the initial component state from report actions
*/
function extractAttachments(
type: ValueOf<typeof CONST.ATTACHMENT_TYPE>,
{reportID, accountID, parentReportAction, reportActions}: {reportID?: string; accountID?: number; parentReportAction?: OnyxEntry<ReportAction>; reportActions?: OnyxEntry<ReportActions>},
{
privateNotes,
accountID,
parentReportAction,
reportActions,
}: {privateNotes?: Record<number, Note>; accountID?: number; parentReportAction?: OnyxEntry<ReportAction>; reportActions?: OnyxEntry<ReportActions>},
) {
const report = getReport(reportID);
const privateNotes = report?.privateNotes;
const targetNote = privateNotes?.[Number(accountID)]?.note ?? '';
const attachments: Attachment[] = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
let targetAttachments: Attachment[] = [];
if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {reportID: report.reportID, accountID});
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID});
} else {
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions});
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Attachments/AttachmentCarousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined;
let targetAttachments: Attachment[] = [];
if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) {
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {reportID: report.reportID, accountID});
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID});
} else {
targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined});
}
Expand Down Expand Up @@ -91,7 +91,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
onNavigate(targetAttachments[initialPage]);
}
}
}, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID, type]);
}, [report.privateNotes, reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, type]);

// Scroll position is affected when window width is resized, so we readjust it on width changes
useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import React, {useMemo} from 'react';
import type {TextStyle} from 'react-native';
import {StyleSheet} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx, withOnyx} from 'react-native-onyx';
import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
import {ShowContextMenuContext} from '@components/ShowContextMenuContext';
import Text from '@components/Text';
import useCurrentReportID from '@hooks/useCurrentReportID';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import {getReport} from '@libs/ReportUtils';
import Navigation from '@navigation/Navigation';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand All @@ -34,8 +33,7 @@ const getMentionDetails = (htmlAttributeReportID: string, currentReport: OnyxEnt

// Get mention details based on reportID from tag attribute
if (!isEmpty(htmlAttributeReportID)) {
const report = getReport(htmlAttributeReportID);

const report = reports?.[htmlAttributeReportID];
reportID = report?.reportID ?? htmlAttributeReportID;
mentionDisplayText = removeLeadingLTRAndHash(report?.reportName ?? report?.displayName ?? htmlAttributeReportID);
// Get mention details from name inside tnode
Expand All @@ -61,7 +59,8 @@ function MentionReportRenderer({style, tnode, TDefaultRenderer, reports, ...defa
const htmlAttributeReportID = tnode.attributes.reportid;

const currentReportID = useCurrentReportID();
const currentReport = getReport(currentReportID?.currentReportID);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [currentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${currentReportID?.currentReportID || -1}`);

// When we invite someone to a room they don't have the policy object, but we still want them to be able to see and click on report mentions, so we only check if the policyID in the report is from a workspace
const isGroupPolicyReport = useMemo(() => currentReport && !isEmptyObject(currentReport) && !!currentReport.policyID && currentReport.policyID !== CONST.POLICY.ID_FAKE, [currentReport]);
Expand Down
6 changes: 5 additions & 1 deletion src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useRef, useState} from 'react';
import type {GestureResponderEvent, ViewStyle} from 'react-native';
import {StyleSheet, View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import DisplayNames from '@components/DisplayNames';
import Hoverable from '@components/Hoverable';
import Icon from '@components/Icon';
Expand All @@ -26,6 +27,7 @@ import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManag
import * as ReportUtils from '@libs/ReportUtils';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type {OptionRowLHNProps} from './types';

Expand All @@ -37,6 +39,9 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
const isFocusedRef = useRef(true);
const {shouldUseNarrowLayout} = useResponsiveLayout();

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${optionItem?.reportID || -1}`);

const {translate} = useLocalize();
const [isContextMenuActive, setIsContextMenuActive] = useState(false);

Expand Down Expand Up @@ -120,7 +125,6 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
const statusClearAfterDate = optionItem.status?.clearAfter ?? '';
const formattedDate = DateUtils.getStatusUntilDate(statusClearAfterDate);
const statusContent = formattedDate ? `${statusText ? `${statusText} ` : ''}(${formattedDate})` : statusText;
const report = ReportUtils.getReport(optionItem.reportID ?? '-1');
const isStatusVisible = !!emojiCode && ReportUtils.isOneOnOneChat(!isEmptyObject(report) ? report : undefined);

const isGroupChat = ReportUtils.isGroupChat(optionItem) || ReportUtils.isDeprecatedGroupDM(optionItem);
Expand Down
5 changes: 3 additions & 2 deletions src/components/SettlementButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useMemo} from 'react';
import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx, withOnyx} from 'react-native-onyx';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import * as ReportUtils from '@libs/ReportUtils';
Expand Down Expand Up @@ -144,7 +144,8 @@ function SettlementButton({
const {isOffline} = useNetwork();

const session = useSession();
const chatReport = ReportUtils.getReport(chatReportID);
// The app would crash due to subscribing to the entire report collection if chatReportID is an empty string. So we should have a fallback ID here.
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID || -1}`);
const isInvoiceReport = (!isEmptyObject(iouReport) && ReportUtils.isInvoiceReport(iouReport)) || false;
const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport);
const shouldShowPaywithExpensifyOption = !isPaidGroupPolicy || (!shouldHidePaymentOptions && ReportUtils.isPayer(session, iouReport as OnyxEntry<Report>));
Expand Down
12 changes: 9 additions & 3 deletions src/libs/ModifiedExpenseMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ 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 {PolicyTagList, ReportAction} from '@src/types/onyx';
import type {PolicyTagList, Report, ReportAction} from '@src/types/onyx';
import type {ModifiedExpense} from '@src/types/onyx/OriginalMessage';
import * as CurrencyUtils from './CurrencyUtils';
import DateUtils from './DateUtils';
import getReportPolicyID from './getReportPolicyID';
import * as Localize from './Localize';
import * as PolicyUtils from './PolicyUtils';
import * as TransactionUtils from './TransactionUtils';
Expand All @@ -24,6 +23,13 @@ Onyx.connect({
},
});

let allReports: OnyxCollection<Report>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => (allReports = value),
});

/**
* Builds the partial message fragment for a modified field on the expense.
*/
Expand Down Expand Up @@ -110,7 +116,7 @@ function getForReportAction(reportID: string | undefined, reportAction: OnyxEntr
return '';
}
const reportActionOriginalMessage = reportAction?.originalMessage as ModifiedExpense | undefined;
const policyID = getReportPolicyID(reportID) ?? '-1';
const policyID = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.policyID ?? '-1';

const removalFragments: string[] = [];
const setFragments: string[] = [];
Expand Down
13 changes: 11 additions & 2 deletions src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import Log from '@libs/Log';
import * as ReportUtils from '@libs/ReportUtils';
import {getReport} 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';
Expand All @@ -32,6 +34,13 @@ let pendingRoute: Route | null = null;

let shouldPopAllStateOnUP = false;

let allReports: OnyxCollection<Report>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => (allReports = value),
});

/**
* Inform the navigation that next time user presses UP we should pop all the state back to LHN.
*/
Expand Down Expand Up @@ -59,7 +68,7 @@ const dismissModal = (reportID?: string, ref = navigationRef) => {
originalDismissModal(ref);
return;
}
const report = 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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
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';
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 {doesReportBelongToWorkspace, getReport} from '@libs/ReportUtils';
import {doesReportBelongToWorkspace} from '@libs/ReportUtils';
import Visibility from '@libs/Visibility';
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 '..';

Expand All @@ -27,6 +28,13 @@ Onyx.connect({
},
});

let allReports: OnyxCollection<Report>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => (allReports = value),
});

function getLastUpdateIDAppliedToClient(): Promise<number> {
return new Promise((resolve) => {
Onyx.connect({
Expand Down Expand Up @@ -74,7 +82,7 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati
Log.info('[PushNotification] Navigating to report', false, {reportID, reportActionID});

const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath);
const report = getReport(reportID.toString());
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const policyEmployeeAccountIDs = policyID ? getPolicyEmployeeAccountIDs(policyID) : [];
const reportBelongsToWorkspace = policyID && !isEmptyObject(report) && doesReportBelongToWorkspace(report, policyEmployeeAccountIDs, policyID);

Expand Down
36 changes: 32 additions & 4 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,34 @@ Onyx.connect({
},
});

let allReports: OnyxCollection<Report> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => (allReports = value),
});

let allReportsDraft: OnyxCollection<Report>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_DRAFT,
waitForCollectionCallback: true,
callback: (value) => (allReportsDraft = value),
});

/**
* Get the report or draft report given a reportID
*/
function getReportOrDraftReport(reportID: string | undefined): OnyxEntry<Report> {
if (!allReports && !allReportsDraft) {
return undefined;
}

const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const draftReport = allReportsDraft?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`];

return report ?? draftReport;
}

/**
* @param defaultValues {login: accountID} In workspace invite page, when new user is added we pass available data to opt in
* @returns Returns avatar data for a list of user accountIDs
Expand Down Expand Up @@ -577,7 +605,7 @@ function getLastActorDisplayName(lastActorDetails: Partial<PersonalDetails> | nu
* Update alternate text for the option when applicable
*/
function getAlternateText(option: ReportUtils.OptionData, {showChatPreviewLine = false, forcePolicyNamePreview = false}: PreviewConfig) {
const report = ReportUtils.getReport(option.reportID);
const report = getReportOrDraftReport(option.reportID);
const isAdminRoom = ReportUtils.isAdminRoom(report);
const isAnnounceRoom = ReportUtils.isAnnounceRoom(report);

Expand Down Expand Up @@ -653,7 +681,7 @@ function getLastMessageTextForReport(report: OnyxEntry<Report>, lastActorDetails
const properSchemaForMoneyRequestMessage = ReportUtils.getReportPreviewMessage(report, lastReportAction, true, false, null, true);
lastMessageTextFromReport = ReportUtils.formatReportLastMessageText(properSchemaForMoneyRequestMessage);
} else if (ReportActionUtils.isReportPreviewAction(lastReportAction)) {
const iouReport = ReportUtils.getReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction));
const iouReport = getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction));
const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find(
(reportAction, key) =>
ReportActionUtils.shouldReportActionBeVisible(reportAction, key) &&
Expand Down Expand Up @@ -832,7 +860,7 @@ function createOption(
* Get the option for a given report.
*/
function getReportOption(participant: Participant): ReportUtils.OptionData {
const report = ReportUtils.getReport(participant.reportID);
const report = getReportOrDraftReport(participant.reportID);
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);

const option = createOption(
Expand Down Expand Up @@ -866,7 +894,7 @@ function getReportOption(participant: Participant): ReportUtils.OptionData {
* Get the option for a policy expense report.
*/
function getPolicyExpenseReportOption(participant: Participant | ReportUtils.OptionData): ReportUtils.OptionData {
const expenseReport = ReportUtils.isPolicyExpenseChat(participant) ? ReportUtils.getReport(participant.reportID) : null;
const expenseReport = ReportUtils.isPolicyExpenseChat(participant) ? getReportOrDraftReport(participant.reportID) : null;

const visibleParticipantAccountIDs = Object.entries(expenseReport?.participants ?? {})
.filter(([, reportParticipant]) => reportParticipant && !reportParticipant.hidden)
Expand Down
Loading

0 comments on commit 9a6019a

Please sign in to comment.