@@ -4,10 +4,12 @@ import interceptAnonymousUser from '@libs/interceptAnonymousUser';
44import { getPreservedNavigatorState } from '@libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState' ;
55import Navigation from '@libs/Navigation/Navigation' ;
66import navigationRef from '@libs/Navigation/navigationRef' ;
7+ import { isPendingDeletePolicy , shouldShowPolicy as shouldShowPolicyUtil } from '@libs/PolicyUtils' ;
78import NAVIGATORS from '@src/NAVIGATORS' ;
89import ROUTES from '@src/ROUTES' ;
910import type { Route } from '@src/ROUTES' ;
1011import SCREENS from '@src/SCREENS' ;
12+ import type { Domain , Policy } from '@src/types/onyx' ;
1113import getActiveTabName from './getActiveTabName' ;
1214import getPathFromState from './getPathFromState' ;
1315import { getTabState } from './tabNavigatorUtils' ;
@@ -24,9 +26,10 @@ function wrapStateInNavigators(state: PartialState<NavigationState>, navigators:
2426}
2527
2628type Params = {
29+ currentUserLogin ?: string ;
2730 shouldUseNarrowLayout : boolean ;
28- policyID ?: string ;
29- domainAccountID ?: number ;
31+ policy ?: Policy ;
32+ domain ?: Domain ;
3033 lastWorkspacesTabNavigatorRoute ?: RouteType ;
3134 topmostFullScreenRoute ?: RouteType ;
3235 /**
@@ -40,7 +43,7 @@ type Params = {
4043 workspacesTabState ?: NavigationState | PartialState < NavigationState > ;
4144} ;
4245
43- const navigateToWorkspacesPage = ( { shouldUseNarrowLayout, policyID , domainAccountID , lastWorkspacesTabNavigatorRoute, topmostFullScreenRoute, workspacesTabState} : Params ) => {
46+ const navigateToWorkspacesPage = ( { currentUserLogin , shouldUseNarrowLayout, policy , domain , lastWorkspacesTabNavigatorRoute, topmostFullScreenRoute, workspacesTabState} : Params ) => {
4447 const rootState = navigationRef . getRootState ( ) ;
4548 const focusedRoute = rootState ? findFocusedRoute ( rootState ) : undefined ;
4649 const isOnWorkspacesList = focusedRoute ?. name === SCREENS . WORKSPACES_LIST ;
@@ -90,40 +93,45 @@ const navigateToWorkspacesPage = ({shouldUseNarrowLayout, policyID, domainAccoun
9093 return ;
9194 }
9295
93- // Workspace route found: navigate to last workspace screen by ID.
94- // Validation is deferred to the destination — if the policy was deleted or access
95- // revoked, the workspace page will redirect to the list itself.
96+ // Workspace route found: try to restore last workspace screen.
9697 if ( lastWorkspacesTabNavigatorRoute . name === NAVIGATORS . WORKSPACE_SPLIT_NAVIGATOR ) {
97- if ( ! policyID ) {
98+ const shouldShowPolicy = shouldShowPolicyUtil ( policy , false , currentUserLogin ) ;
99+ const isPendingDelete = isPendingDeletePolicy ( policy ) ;
100+
101+ // Workspace is not accessible or is being deleted: go to list.
102+ if ( ! shouldShowPolicy || isPendingDelete ) {
98103 Navigation . navigate ( ROUTES . WORKSPACES_LIST . route ) ;
99104 return ;
100105 }
101- // Synthesize a URL from the captured WorkspaceSplitNavigator inner state and navigate
102- // to it. URL-based navigation goes through `getStateFromPath`, which produces a fully
103- // formed nested state and reliably handles pushing a fresh TabNavigator on top of an
104- // existing fullscreen stack. The state has to be wrapped with its full ancestor chain
105- // (TAB_NAVIGATOR > WORKSPACE_NAVIGATOR > WORKSPACE_SPLIT_NAVIGATOR) so `getPathFromState`
106- // can match the linking-config hierarchy and produce a real URL like
107- // `/workspaces/POLICY_ID/workflows`; otherwise the resolver falls back to navigator
108- // names as path segments and the result hits 404. Narrow layouts skip the deep-restore
109- // and go to the workspace's initial page (mirrors mobile behavior).
110- const wrappedState =
111- ! shouldUseNarrowLayout && workspacesTabState
112- ? wrapStateInNavigators ( workspacesTabState as PartialState < NavigationState > , [
113- NAVIGATORS . TAB_NAVIGATOR ,
114- NAVIGATORS . WORKSPACE_NAVIGATOR ,
115- NAVIGATORS . WORKSPACE_SPLIT_NAVIGATOR ,
116- ] )
117- : undefined ;
118- const targetPath = ( wrappedState ? getPathFromState ( wrappedState ) : ROUTES . WORKSPACE_INITIAL . getRoute ( policyID ) ) as Route ;
119- Navigation . navigate ( targetPath ) ;
106+
107+ if ( policy ?. id ) {
108+ // Synthesize a URL from the captured WorkspaceSplitNavigator inner state and navigate
109+ // to it. URL-based navigation goes through `getStateFromPath`, which produces a fully
110+ // formed nested state and reliably handles pushing a fresh TabNavigator on top of an
111+ // existing fullscreen stack. The state has to be wrapped with its full ancestor chain
112+ // (TAB_NAVIGATOR > WORKSPACE_NAVIGATOR > WORKSPACE_SPLIT_NAVIGATOR) so `getPathFromState`
113+ // can match the linking-config hierarchy and produce a real URL like
114+ // `/workspaces/POLICY_ID/workflows`; otherwise the resolver falls back to navigator
115+ // names as path segments and the result hits 404. Narrow layouts skip the deep-restore
116+ // and go to the workspace's initial page (mirrors mobile behavior).
117+ const wrappedState =
118+ ! shouldUseNarrowLayout && workspacesTabState
119+ ? wrapStateInNavigators ( workspacesTabState as PartialState < NavigationState > , [
120+ NAVIGATORS . TAB_NAVIGATOR ,
121+ NAVIGATORS . WORKSPACE_NAVIGATOR ,
122+ NAVIGATORS . WORKSPACE_SPLIT_NAVIGATOR ,
123+ ] )
124+ : undefined ;
125+ const targetPath = ( wrappedState ? getPathFromState ( wrappedState ) : ROUTES . WORKSPACE_INITIAL . getRoute ( policy . id ) ) as Route ;
126+ Navigation . navigate ( targetPath ) ;
127+ }
120128 return ;
121129 }
122130
123- // Domain route found: navigate to last domain screen by ID .
131+ // Domain route found: try to restore last domain screen.
124132 if ( lastWorkspacesTabNavigatorRoute . name === NAVIGATORS . DOMAIN_SPLIT_NAVIGATOR ) {
125- if ( domainAccountID !== undefined ) {
126- Navigation . navigate ( ROUTES . DOMAIN_INITIAL . getRoute ( domainAccountID ) ) ;
133+ if ( domain ?. accountID !== undefined ) {
134+ Navigation . navigate ( ROUTES . DOMAIN_INITIAL . getRoute ( domain . accountID ) ) ;
127135 return ;
128136 }
129137 }
0 commit comments