Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate withReportOrNotFound from withOnyx to useOnyx #49444

Merged
merged 10 commits into from
Oct 7, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type {WithReportOrNotFoundOnyxProps, WithReportOrNotFoundProps} from './withReportOrNotFound';
import type {WithReportOrNotFoundProps} from './withReportOrNotFound';
import withReportOrNotFound from './withReportOrNotFound';

type WithReportAndPrivateNotesOrNotFoundOnyxProps = {
Expand All @@ -28,7 +28,7 @@ export default function (pageTitle: TranslationPaths) {
// eslint-disable-next-line rulesdir/no-negated-variables
return <TProps extends WithReportAndPrivateNotesOrNotFoundProps, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): React.ComponentType<Omit<Omit<TProps, keyof WithReportAndPrivateNotesOrNotFoundOnyxProps> & RefAttributes<TRef>, keyof WithReportOrNotFoundOnyxProps>> => {
): React.ComponentType<Omit<TProps, keyof WithReportAndPrivateNotesOrNotFoundOnyxProps> & RefAttributes<TRef>> => {
// eslint-disable-next-line rulesdir/no-negated-variables
function WithReportAndPrivateNotesOrNotFound(props: TProps, ref: ForwardedRef<TRef>) {
const {translate} = useLocalize();
Expand Down
75 changes: 31 additions & 44 deletions src/pages/home/report/withReportOrNotFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import type {RouteProp} from '@react-navigation/native';
import type {ComponentType, ForwardedRef, RefAttributes} from 'react';
import React, {useEffect} from 'react';
import {useOnyx} from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import * as ReportUtils from '@libs/ReportUtils';
Expand All @@ -22,24 +22,7 @@ import type SCREENS from '@src/SCREENS';
import type * as OnyxTypes from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type WithReportOrNotFoundOnyxProps = {
/** The report currently being looked at */
report: OnyxEntry<OnyxTypes.Report>;

/** Metadata of the report currently being looked at */
reportMetadata: OnyxEntry<OnyxTypes.ReportMetadata>;

/** The policies which the user has access to */
policies: OnyxCollection<OnyxTypes.Policy>;

/** Beta features list */
betas: OnyxEntry<OnyxTypes.Beta[]>;

/** Indicated whether the report data is loading */
isLoadingReportData: OnyxEntry<boolean>;
Tony-MK marked this conversation as resolved.
Show resolved Hide resolved
};

type WithReportOrNotFoundProps = WithReportOrNotFoundOnyxProps & {
type WithReportOrNotFoundProps = {
route:
| RouteProp<PrivateNotesNavigatorParamList, typeof SCREENS.PRIVATE_NOTES.EDIT>
| RouteProp<ReportDescriptionNavigatorParamList, typeof SCREENS.REPORT_DESCRIPTION_ROOT>
Expand All @@ -53,21 +36,36 @@ type WithReportOrNotFoundProps = WithReportOrNotFoundOnyxProps & {

/** The report currently being looked at */
report: OnyxTypes.Report;

/** Metadata of the report currently being looked at */
reportMetadata: OnyxEntry<OnyxTypes.ReportMetadata>;

/** The policies which the user has access to */
policies: OnyxCollection<OnyxTypes.Policy>;

/** Beta features list */
betas: OnyxEntry<OnyxTypes.Beta[]>;

/** Indicated whether the report data is loading */
isLoadingReportData: OnyxEntry<boolean>;
};

export default function (
shouldRequireReportID = true,
): <TProps extends WithReportOrNotFoundProps, TRef>(
WrappedComponent: React.ComponentType<TProps & React.RefAttributes<TRef>>,
) => React.ComponentType<Omit<TProps & React.RefAttributes<TRef>, keyof WithReportOrNotFoundOnyxProps>> {
): <TProps extends WithReportOrNotFoundProps, TRef>(WrappedComponent: React.ComponentType<TProps & React.RefAttributes<TRef>>) => React.ComponentType<TProps & React.RefAttributes<TRef>> {
return function <TProps extends WithReportOrNotFoundProps, TRef>(WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>) {
function WithReportOrNotFound(props: TProps, ref: ForwardedRef<TRef>) {
const [betas] = useOnyx(ONYXKEYS.BETAS);
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
const [reportMetadata] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${props.route.params.reportID}`);
const [isLoadingReportData] = useOnyx(ONYXKEYS.IS_LOADING_REPORT_DATA);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${props.route.params.reportID}`);
const contentShown = React.useRef(false);
const isReportIdInRoute = !!props.route.params.reportID?.length;
const isReportLoaded = !isEmptyObject(props.report) && !!props.report?.reportID;
const isReportLoaded = !isEmptyObject(report) && !!report?.reportID;

// The `isLoadingInitialReportActions` value will become `false` only after the first OpenReport API call is finished (either succeeded or failed)
const shouldFetchReport = isReportIdInRoute && props.reportMetadata?.isLoadingInitialReportActions !== false;
const shouldFetchReport = isReportIdInRoute && reportMetadata?.isLoadingInitialReportActions !== false;

// When accessing certain report-dependant pages (e.g. Task Title) by deeplink, the OpenReport API is not called,
// So we need to call OpenReport API here to make sure the report data is loaded if it exists on the Server
Expand All @@ -82,8 +80,8 @@ export default function (
}, [shouldFetchReport, isReportLoaded, props.route.params.reportID]);

if (shouldRequireReportID || isReportIdInRoute) {
const shouldShowFullScreenLoadingIndicator = !isReportLoaded && (props.isLoadingReportData !== false || shouldFetchReport);
const shouldShowNotFoundPage = !isReportLoaded || !ReportUtils.canAccessReport(props.report, props.policies, props.betas);
const shouldShowFullScreenLoadingIndicator = !isReportLoaded && (isLoadingReportData !== false || shouldFetchReport);
const shouldShowNotFoundPage = !isReportLoaded || !ReportUtils.canAccessReport(report, policies, betas);

// If the content was shown, but it's not anymore, that means the report was deleted, and we are probably navigating out of this screen.
// Return null for this case to avoid rendering FullScreenLoadingIndicator or NotFoundPage when animating transition.
Expand All @@ -108,31 +106,20 @@ export default function (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
report={report}
betas={betas}
policies={policies}
reportMetadata={reportMetadata}
isLoadingReportData={isLoadingReportData}
ref={ref}
/>
);
}

WithReportOrNotFound.displayName = `withReportOrNotFound(${getComponentDisplayName(WrappedComponent)})`;

return withOnyx<TProps & RefAttributes<TRef>, WithReportOrNotFoundOnyxProps>({
report: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`,
},
reportMetadata: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_METADATA}${route.params.reportID}`,
},
isLoadingReportData: {
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
},
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
})(React.forwardRef(WithReportOrNotFound));
return React.forwardRef(WithReportOrNotFound);
};
}

export type {WithReportOrNotFoundProps, WithReportOrNotFoundOnyxProps};
export type {WithReportOrNotFoundProps};
Loading