1
1
/* eslint-disable rulesdir/no-negated-variables */
2
2
import React , { useEffect } from 'react' ;
3
- import type { OnyxEntry } from 'react-native-onyx' ;
3
+ import type { OnyxCollection , OnyxEntry } from 'react-native-onyx' ;
4
4
import { withOnyx } from 'react-native-onyx' ;
5
5
import type { FullPageNotFoundViewProps } from '@components/BlockingViews/FullPageNotFoundView' ;
6
6
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView' ;
7
7
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator' ;
8
+ import * as IOUUtils from '@libs/IOUUtils' ;
8
9
import Navigation from '@libs/Navigation/Navigation' ;
9
10
import * as PolicyUtils from '@libs/PolicyUtils' ;
11
+ import * as ReportUtils from '@libs/ReportUtils' ;
10
12
import NotFoundPage from '@pages/ErrorPage/NotFoundPage' ;
11
13
import * as Policy from '@userActions/Policy/Policy' ;
14
+ import type { IOUType } from '@src/CONST' ;
12
15
import CONST from '@src/CONST' ;
13
16
import ONYXKEYS from '@src/ONYXKEYS' ;
14
17
import ROUTES from '@src/ROUTES' ;
@@ -17,13 +20,22 @@ import type {PolicyFeatureName} from '@src/types/onyx/Policy';
17
20
import callOrReturn from '@src/types/utils/callOrReturn' ;
18
21
import { isEmptyObject } from '@src/types/utils/EmptyObject' ;
19
22
20
- const POLICY_ACCESS_VARIANTS = {
23
+ const ACCESS_VARIANTS = {
21
24
[ CONST . POLICY . ACCESS_VARIANTS . PAID ] : ( policy : OnyxEntry < OnyxTypes . Policy > ) => PolicyUtils . isPaidGroupPolicy ( policy ) && ! ! policy ?. isPolicyExpenseChatEnabled ,
22
25
[ CONST . POLICY . ACCESS_VARIANTS . ADMIN ] : ( policy : OnyxEntry < OnyxTypes . Policy > ) => PolicyUtils . isPolicyAdmin ( policy ) ,
23
- } as const satisfies Record < string , ( policy : OnyxTypes . Policy ) => boolean > ;
24
-
25
- type PolicyAccessVariant = keyof typeof POLICY_ACCESS_VARIANTS ;
26
+ [ CONST . IOU . ACCESS_VARIANTS . CREATE ] : ( policy : OnyxEntry < OnyxTypes . Policy > , report : OnyxEntry < OnyxTypes . Report > , allPolicies : OnyxCollection < OnyxTypes . Policy > , iouType ?: IOUType ) =>
27
+ ! ! iouType &&
28
+ IOUUtils . isValidMoneyRequestType ( iouType ) &&
29
+ // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense
30
+ ( isEmptyObject ( report ?. reportID ) || ReportUtils . canCreateRequest ( report , policy , iouType ) ) &&
31
+ ( iouType !== CONST . IOU . TYPE . INVOICE || PolicyUtils . canSendInvoice ( allPolicies ) ) ,
32
+ } as const satisfies Record < string , ( policy : OnyxTypes . Policy , report : OnyxTypes . Report , allPolicies : OnyxCollection < OnyxTypes . Policy > , iouType ?: IOUType ) => boolean > ;
33
+
34
+ type AccessVariant = keyof typeof ACCESS_VARIANTS ;
26
35
type AccessOrNotFoundWrapperOnyxProps = {
36
+ /** The report that holds the transaction */
37
+ report : OnyxEntry < OnyxTypes . Report > ;
38
+
27
39
/** The report currently being looked at */
28
40
policy : OnyxEntry < OnyxTypes . Policy > ;
29
41
@@ -35,11 +47,14 @@ type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
35
47
/** The children to render */
36
48
children : ( ( props : AccessOrNotFoundWrapperOnyxProps ) => React . ReactNode ) | React . ReactNode ;
37
49
50
+ /** The id of the report that holds the transaction */
51
+ reportID ?: string ;
52
+
38
53
/** The report currently being looked at */
39
- policyID : string ;
54
+ policyID ? : string ;
40
55
41
56
/** Defines which types of access should be verified */
42
- accessVariants ?: PolicyAccessVariant [ ] ;
57
+ accessVariants ?: AccessVariant [ ] ;
43
58
44
59
/** The current feature name that the user tries to get access to */
45
60
featureName ?: PolicyFeatureName ;
@@ -49,6 +64,12 @@ type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
49
64
50
65
/** Whether or not to block user from accessing the page */
51
66
shouldBeBlocked ?: boolean ;
67
+
68
+ /** The type of the transaction */
69
+ iouType ?: IOUType ;
70
+
71
+ /** The list of all policies */
72
+ allPolicies ?: OnyxCollection < OnyxTypes . Policy > ;
52
73
} & Pick < FullPageNotFoundViewProps , 'subtitleKey' | 'onLinkPress' > ;
53
74
54
75
type PageNotFoundFallbackProps = Pick < AccessOrNotFoundWrapperProps , 'policyID' | 'fullPageNotFoundViewProps' > & { shouldShowFullScreenFallback : boolean } ;
@@ -64,17 +85,19 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN
64
85
/>
65
86
) : (
66
87
< NotFoundPage
67
- onBackButtonPress = { ( ) => Navigation . goBack ( ROUTES . WORKSPACE_PROFILE . getRoute ( policyID ) ) }
88
+ onBackButtonPress = { ( ) => Navigation . goBack ( policyID ? ROUTES . WORKSPACE_PROFILE . getRoute ( policyID ) : ROUTES . HOME ) }
68
89
// eslint-disable-next-line react/jsx-props-no-spreading
69
90
{ ...fullPageNotFoundViewProps }
70
91
/>
71
92
) ;
72
93
}
73
94
74
95
function AccessOrNotFoundWrapper ( { accessVariants = [ ] , fullPageNotFoundViewProps, shouldBeBlocked, ...props } : AccessOrNotFoundWrapperProps ) {
75
- const { policy, policyID, featureName, isLoadingReportData} = props ;
96
+ const { policy, policyID, report , iouType , allPolicies , featureName, isLoadingReportData} = props ;
76
97
77
98
const isPolicyIDInRoute = ! ! policyID ?. length ;
99
+ const isMoneyRequest = ! ! iouType && IOUUtils . isValidMoneyRequestType ( iouType ) ;
100
+ const isFromGlobalCreate = isEmptyObject ( report ?. reportID ) ;
78
101
79
102
useEffect ( ( ) => {
80
103
if ( ! isPolicyIDInRoute || ! isEmptyObject ( policy ) ) {
@@ -86,17 +109,17 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
86
109
// eslint-disable-next-line react-hooks/exhaustive-deps
87
110
} , [ isPolicyIDInRoute , policyID ] ) ;
88
111
89
- const shouldShowFullScreenLoadingIndicator = isLoadingReportData !== false && ( ! Object . entries ( policy ?? { } ) . length || ! policy ?. id ) ;
112
+ const shouldShowFullScreenLoadingIndicator = ! isMoneyRequest && isLoadingReportData !== false && ( ! Object . entries ( policy ?? { } ) . length || ! policy ?. id ) ;
90
113
91
114
const isFeatureEnabled = featureName ? PolicyUtils . isPolicyFeatureEnabled ( policy , featureName ) : true ;
92
115
93
116
const isPageAccessible = accessVariants . reduce ( ( acc , variant ) => {
94
- const accessFunction = POLICY_ACCESS_VARIANTS [ variant ] ;
95
- return acc && accessFunction ( policy ) ;
117
+ const accessFunction = ACCESS_VARIANTS [ variant ] ;
118
+ return acc && accessFunction ( policy , report , allPolicies ?? null , iouType ) ;
96
119
} , true ) ;
97
120
98
- const shouldShowNotFoundPage =
99
- isEmptyObject ( policy ) || ( Object . keys ( policy ) . length === 1 && ! isEmptyObject ( policy . errors ) ) || ! policy ?. id || ! isPageAccessible || ! isFeatureEnabled || shouldBeBlocked ;
121
+ const isPolicyNotAccessible = isEmptyObject ( policy ) || ( Object . keys ( policy ) . length === 1 && ! isEmptyObject ( policy . errors ) ) || ! policy ?. id ;
122
+ const shouldShowNotFoundPage = ( ! isMoneyRequest && ! isFromGlobalCreate && isPolicyNotAccessible ) || ! isPageAccessible || ! isFeatureEnabled || shouldBeBlocked ;
100
123
101
124
if ( shouldShowFullScreenLoadingIndicator ) {
102
125
return < FullscreenLoadingIndicator /> ;
@@ -115,11 +138,14 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps
115
138
return callOrReturn ( props . children , props ) ;
116
139
}
117
140
118
- export type { PolicyAccessVariant } ;
141
+ export type { AccessVariant } ;
119
142
120
143
export default withOnyx < AccessOrNotFoundWrapperProps , AccessOrNotFoundWrapperOnyxProps > ( {
144
+ report : {
145
+ key : ( { reportID} ) => `${ ONYXKEYS . COLLECTION . REPORT } ${ reportID } ` ,
146
+ } ,
121
147
policy : {
122
- key : ( { policyID} ) => `${ ONYXKEYS . COLLECTION . POLICY } ${ policyID ?? '' } ` ,
148
+ key : ( { policyID} ) => `${ ONYXKEYS . COLLECTION . POLICY } ${ policyID } ` ,
123
149
} ,
124
150
isLoadingReportData : {
125
151
key : ONYXKEYS . IS_LOADING_REPORT_DATA ,
0 commit comments