From 6a542af1fbc0a4f855ea5f29d08bc465427fbf2f Mon Sep 17 00:00:00 2001 From: "truph01 (via MelvinBot)" Date: Thu, 13 Aug 2026 07:14:25 +0000 Subject: [PATCH 1/4] Prevent flash of disabled feature page before redirect to More features Co-authored-by: truph01 --- src/pages/workspace/AccessOrNotFoundWrapper.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 6bf1dd54c980..0b6067ab591c 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -227,8 +227,11 @@ function AccessOrNotFoundWrapper({ // 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 be unexpectedly navigated to the More Features page. + const shouldRedirectToMoreFeatures = + isFocused && !isEmptyObject(policy) && !isFeatureEnabled && !(pendingField && !isOffline) && !shouldShowNotFoundPage; + useEffect(() => { - if (!isFocused || isEmptyObject(policy) || isFeatureEnabled || (pendingField && !isOffline && !isFeatureEnabled) || shouldShowNotFoundPage) { + if (!shouldRedirectToMoreFeatures) { return; } @@ -238,7 +241,7 @@ function AccessOrNotFoundWrapper({ }); // We don't need to run the effect on policyID change as we only use it to get the route to navigate to. // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pendingField, isOffline, isFeatureEnabled, shouldShowNotFoundPage, isFocused]); + }, [shouldRedirectToMoreFeatures]); useEffect(() => { if (isLoadingReportData || !isPolicyNotAccessible) { @@ -250,6 +253,11 @@ function AccessOrNotFoundWrapper({ if (shouldShowFullScreenLoadingIndicator) { return ; } + // The feature linked to this page is disabled, so the redirect effect above will navigate to the More Features page. + // Render a loader instead of the page's children so the disabled page is never shown for a frame (avoids a visible flash). + if (shouldRedirectToMoreFeatures) { + return ; + } if (shouldShowNotFoundPage) { return ( Date: Thu, 13 Aug 2026 07:26:39 +0000 Subject: [PATCH 2/4] Fix Oxfmt formatting in AccessOrNotFoundWrapper Co-authored-by: truph01 --- src/pages/workspace/AccessOrNotFoundWrapper.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 0b6067ab591c..95a5e3c5e8ba 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -227,8 +227,7 @@ function AccessOrNotFoundWrapper({ // 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 be unexpectedly navigated to the More Features page. - const shouldRedirectToMoreFeatures = - isFocused && !isEmptyObject(policy) && !isFeatureEnabled && !(pendingField && !isOffline) && !shouldShowNotFoundPage; + const shouldRedirectToMoreFeatures = isFocused && !isEmptyObject(policy) && !isFeatureEnabled && !(pendingField && !isOffline) && !shouldShowNotFoundPage; useEffect(() => { if (!shouldRedirectToMoreFeatures) { From 1bb089b60c369ce9fd5c075181987620f0d5e9e5 Mon Sep 17 00:00:00 2001 From: "truph01 (via MelvinBot)" Date: Thu, 13 Aug 2026 07:38:42 +0000 Subject: [PATCH 3/4] Enable company cards feature in AssignCardFeed test policies Co-authored-by: truph01 --- tests/ui/AssignCardFeed.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/ui/AssignCardFeed.tsx b/tests/ui/AssignCardFeed.tsx index 64ee86c1ecdc..08c6df335606 100644 --- a/tests/ui/AssignCardFeed.tsx +++ b/tests/ui/AssignCardFeed.tsx @@ -225,6 +225,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, employeeList: { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -265,6 +266,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, employeeList: { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -303,6 +305,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, employeeList: { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -347,6 +350,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -380,6 +384,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -417,6 +422,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -445,6 +451,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -478,6 +485,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -514,6 +522,7 @@ describe('AssignCardFeed', () => { await TestHelper.signInWithTestUser(); const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -551,6 +560,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, employeeList: { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -591,6 +601,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, employeeList: { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -634,6 +645,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -670,6 +682,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -719,6 +732,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -766,6 +780,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -829,6 +844,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -909,6 +925,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -946,6 +963,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; @@ -996,6 +1014,7 @@ describe('AssignCardFeed', () => { const policy = { ...LHNTestUtils.getFakePolicy(), + areCompanyCardsEnabled: true, role: CONST.POLICY.ROLE.ADMIN, policyAccountID: WORKSPACE_ACCOUNT_ID, }; From 2afe34837d0034fb90bf913299e56c856a631163 Mon Sep 17 00:00:00 2001 From: "truph01 (via MelvinBot)" Date: Thu, 13 Aug 2026 17:10:27 +0000 Subject: [PATCH 4/4] Add shouldUseGoBackButton to disabled-feature redirect loader (UI-1) Co-authored-by: truph01 --- src/pages/workspace/AccessOrNotFoundWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 95a5e3c5e8ba..6977857cf2ea 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -255,7 +255,7 @@ function AccessOrNotFoundWrapper({ // The feature linked to this page is disabled, so the redirect effect above will navigate to the More Features page. // Render a loader instead of the page's children so the disabled page is never shown for a frame (avoids a visible flash). if (shouldRedirectToMoreFeatures) { - return ; + return ; } if (shouldShowNotFoundPage) { return (