diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index c7f89559fdda..e1d0ec28370c 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -1,11 +1,12 @@ /* eslint-disable rulesdir/no-negated-variables */ -import React, {useEffect} from 'react'; +import React, {useEffect, useState} from 'react'; import type {OnyxCollection, 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 useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useNetwork from '@hooks/useNetwork'; import * as IOUUtils from '@libs/IOUUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -108,6 +109,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isPolicyIDInRoute = !!policyID?.length; const isMoneyRequest = !!iouType && IOUUtils.isValidMoneyRequestType(iouType); const isFromGlobalCreate = isEmptyObject(report?.reportID); + const pendingField = featureName ? props.policy?.pendingFields?.[featureName] : undefined; useEffect(() => { if (!isPolicyIDInRoute || !isEmptyObject(policy)) { @@ -123,13 +125,26 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isFeatureEnabled = featureName ? PolicyUtils.isPolicyFeatureEnabled(policy, featureName) : true; + const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); + const {isOffline} = useNetwork(); + const isPageAccessible = accessVariants.reduce((acc, variant) => { const accessFunction = ACCESS_VARIANTS[variant]; return acc && accessFunction(policy, login, report, allPolicies ?? null, iouType); }, true); const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id; - const shouldShowNotFoundPage = (!isMoneyRequest && !isFromGlobalCreate && isPolicyNotAccessible) || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked; + const shouldShowNotFoundPage = (!isMoneyRequest && !isFromGlobalCreate && isPolicyNotAccessible) || !isPageAccessible || !isPolicyFeatureEnabled || shouldBeBlocked; + + // We only update the feature state if it isn't pending. + // This is because the feature state changes several times during the creation of a workspace, while we are waiting for a response from the backend. + // Without this, we can have unexpectedly have 'Not Found' be shown. + useEffect(() => { + if (pendingField && !isOffline && !isFeatureEnabled) { + return; + } + setIsPolicyFeatureEnabled(isFeatureEnabled); + }, [pendingField, isOffline, isFeatureEnabled]); if (shouldShowFullScreenLoadingIndicator) { return ; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index a3785ccde384..d622be617f22 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -211,7 +211,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; // We only update feature states if they aren't pending. - // These changes are made to synchronously change feature states along with FeatureEnabledAccessOrNotFoundComponent. + // These changes are made to synchronously change feature states along with AccessOrNotFoundWrapperComponent. useEffect(() => { setFeatureStates((currentFeatureStates) => { const newFeatureStates = {} as PolicyFeatureStates;