-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
withReportOrNotFound.js
110 lines (93 loc) · 3.9 KB
/
withReportOrNotFound.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import PropTypes from 'prop-types';
import React from 'react';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import getComponentDisplayName from '../../../libs/getComponentDisplayName';
import NotFoundPage from '../../ErrorPage/NotFoundPage';
import ONYXKEYS from '../../../ONYXKEYS';
import reportPropTypes from '../../reportPropTypes';
import FullscreenLoadingIndicator from '../../../components/FullscreenLoadingIndicator';
import * as ReportUtils from '../../../libs/ReportUtils';
export default function (WrappedComponent) {
const propTypes = {
/** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component.
* That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */
forwardedRef: PropTypes.func,
/** The report currently being looked at */
report: reportPropTypes,
/** The policies which the user has access to */
policies: PropTypes.objectOf(
PropTypes.shape({
/** The policy name */
name: PropTypes.string,
/** The type of the policy */
type: PropTypes.string,
}),
),
/** Beta features list */
betas: PropTypes.arrayOf(PropTypes.string),
/** Indicated whether the report data is loading */
isLoadingReportData: PropTypes.bool,
};
const defaultProps = {
forwardedRef: () => {},
report: {},
policies: {},
betas: [],
isLoadingReportData: true,
};
// eslint-disable-next-line rulesdir/no-negated-variables
function WithReportOrNotFound(props) {
const contentShown = React.useRef(false);
const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData && (_.isEmpty(props.report) || !props.report.reportID);
// eslint-disable-next-line rulesdir/no-negated-variables
const shouldShowNotFoundPage = _.isEmpty(props.report) || !props.report.reportID || !ReportUtils.canAccessReport(props.report, props.policies, props.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.
if (shouldShowNotFoundPage && contentShown.current) {
return null;
}
if (shouldShowFullScreenLoadingIndicator) {
return <FullscreenLoadingIndicator />;
}
if (shouldShowNotFoundPage) {
return <NotFoundPage />;
}
if (!contentShown.current) {
contentShown.current = true;
}
const rest = _.omit(props, ['forwardedRef']);
return (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...rest}
ref={props.forwardedRef}
/>
);
}
WithReportOrNotFound.propTypes = propTypes;
WithReportOrNotFound.defaultProps = defaultProps;
WithReportOrNotFound.displayName = `withReportOrNotFound(${getComponentDisplayName(WrappedComponent)})`;
// eslint-disable-next-line rulesdir/no-negated-variables
const withReportOrNotFound = React.forwardRef((props, ref) => (
<WithReportOrNotFound
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
forwardedRef={ref}
/>
));
return withOnyx({
report: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`,
},
isLoadingReportData: {
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
},
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
})(withReportOrNotFound);
}