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

[Simplified Collect][CLEAN UP][LOW] Standardize on Workspace wrapper #40598

Merged
Merged
4 changes: 4 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,10 @@ const CONST = {
JOB_DONE: 'jobDone',
},
},
ACCESS_VARIANTS: {
PAID: 'paid',
ADMIN: 'admin',
},
},

CUSTOM_UNITS: {
Expand Down
1 change: 1 addition & 0 deletions src/components/BlockingViews/FullPageNotFoundView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ function FullPageNotFoundView({

FullPageNotFoundView.displayName = 'FullPageNotFoundView';

export type {FullPageNotFoundViewProps};
export default FullPageNotFoundView;
7 changes: 5 additions & 2 deletions src/pages/ErrorPage/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import React from 'react';
import type {FullPageNotFoundViewProps} from '@components/BlockingViews/FullPageNotFoundView';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ScreenWrapper from '@components/ScreenWrapper';

type NotFoundPageProps = {
onBackButtonPress?: () => void;
};
} & FullPageNotFoundViewProps;

// eslint-disable-next-line rulesdir/no-negated-variables
function NotFoundPage({onBackButtonPress}: NotFoundPageProps) {
function NotFoundPage({onBackButtonPress, ...fullPageNotFoundViewProps}: NotFoundPageProps) {
return (
<ScreenWrapper testID={NotFoundPage.displayName}>
<FullPageNotFoundView
shouldShow
onBackButtonPress={onBackButtonPress}
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
</ScreenWrapper>
);
Expand Down
121 changes: 121 additions & 0 deletions src/pages/workspace/AccessOrNotFoundWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/* eslint-disable rulesdir/no-negated-variables */
import React, {useEffect} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {FullPageNotFoundViewProps} from '@components/BlockingViews/FullPageNotFoundView';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';
import type {PolicyFeatureName} from '@src/types/onyx/Policy';
import callOrReturn from '@src/types/utils/callOrReturn';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

const POLICY_ACCESS_VARIANTS = {
[CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry<OnyxTypes.Policy>) => PolicyUtils.isPaidGroupPolicy(policy) && !!policy?.isPolicyExpenseChatEnabled,
[CONST.POLICY.ACCESS_VARIANTS.ADMIN]: (policy: OnyxEntry<OnyxTypes.Policy>) => PolicyUtils.isPolicyAdmin(policy),
} as const satisfies Record<string, (policy: OnyxTypes.Policy) => boolean>;

type PolicyAccessVariant = keyof typeof POLICY_ACCESS_VARIANTS;
type AccessOrNotFoundWrapperOnyxProps = {
/** The report currently being looked at */
policy: OnyxEntry<OnyxTypes.Policy>;

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

type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & {
/** The children to render */
children: ((props: AccessOrNotFoundWrapperOnyxProps) => React.ReactNode) | React.ReactNode;

/** The report currently being looked at */
policyID: string;

/** Defines which types of access should be verified */
accessVariants?: PolicyAccessVariant[];

/** The current feature name that the user tries to get access to */
featureName?: PolicyFeatureName;

/** Props for customizing fallback pages */
fullPageNotFoundViewProps?: FullPageNotFoundViewProps;
} & Pick<FullPageNotFoundViewProps, 'subtitleKey' | 'onLinkPress'>;

type PageNotFoundFallbackProps = Pick<AccessOrNotFoundWrapperProps, 'policyID' | 'fullPageNotFoundViewProps'> & {shouldShowFullScreenFallback: boolean};

function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageNotFoundViewProps}: PageNotFoundFallbackProps) {
return shouldShowFullScreenFallback ? (
<FullPageNotFoundView
shouldShow
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
shouldForceFullScreen
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
) : (
<NotFoundPage
onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_PROFILE.getRoute(policyID))}
// eslint-disable-next-line react/jsx-props-no-spreading
{...fullPageNotFoundViewProps}
/>
);
}

function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps, ...props}: AccessOrNotFoundWrapperProps) {
const {policy, policyID, featureName, isLoadingReportData} = props;

const isPolicyIDInRoute = !!policyID?.length;

useEffect(() => {
if (!isPolicyIDInRoute || !isEmptyObject(policy)) {
// If the workspace is not required or is already loaded, we don't need to call the API
return;
}

Policy.openWorkspace(policyID, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPolicyIDInRoute, policyID]);

const shouldShowFullScreenLoadingIndicator = isLoadingReportData !== false && (!Object.entries(policy ?? {}).length || !policy?.id);

const isFeatureEnabled = featureName ? PolicyUtils.isPolicyFeatureEnabled(policy, featureName) : true;

const isPageAccessible = accessVariants.reduce((acc, variant) => {
const accessFunction = POLICY_ACCESS_VARIANTS[variant];
return acc && accessFunction(policy);
}, true);

const shouldShowNotFoundPage = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id || !isPageAccessible || !isFeatureEnabled;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from #44206:
Please be careful when fix conflict.
Recent code in FeatureEnabledAccessOrWrapper was not applied to this file so the fix of #39443 was partially reverted.
More details: #44206 (comment)


if (shouldShowFullScreenLoadingIndicator) {
return <FullscreenLoadingIndicator />;
}

if (shouldShowNotFoundPage) {
return (
<PageNotFoundFallback
policyID={policyID}
shouldShowFullScreenFallback={!isFeatureEnabled}
fullPageNotFoundViewProps={fullPageNotFoundViewProps}
/>
);
}

return callOrReturn(props.children, props);
}

export default withOnyx<AccessOrNotFoundWrapperProps, AccessOrNotFoundWrapperOnyxProps>({
policy: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? ''}`,
},
isLoadingReportData: {
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
},
})(AccessOrNotFoundWrapper);
91 changes: 0 additions & 91 deletions src/pages/workspace/AdminPolicyAccessOrNotFoundWrapper.tsx

This file was deleted.

91 changes: 0 additions & 91 deletions src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx

This file was deleted.

Loading
Loading