Skip to content

Commit

Permalink
Merge pull request #36397 from software-mansion-labs/ideal-nav/go-bac…
Browse files Browse the repository at this point in the history
…k-to-settings-page

Add helper functions in getMatchingCentralPaneRouteForState
  • Loading branch information
Hayata Suenaga authored Feb 22, 2024
2 parents 6754f15 + b21f8d7 commit 687bac0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/libs/Navigation/linkTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export default function linkTo(navigation: NavigationContainerRef<RootStackParam
if (!getIsNarrowLayout()) {
// stateFromPath should always include bottom tab navigator state, so getMatchingCentralPaneRouteForState will be always defined.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(stateFromPath)!;
const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(stateFromPath, rootState)!;
if (matchingCentralPaneRoute && 'name' in matchingCentralPaneRoute) {
root.dispatch({
type: CONST.NAVIGATION.ACTION_TYPE.PUSH,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute';
import type {CentralPaneName, NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types';
import type {CentralPaneName, CentralPaneNavigatorParamList, NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import TAB_TO_CENTRAL_PANE_MAPPING from './TAB_TO_CENTRAL_PANE_MAPPING';

const WORKSPACES_SCREENS = TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.WORKSPACE.INITIAL].concat(TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.ALL_SETTINGS]);

/**
* @param state - react-navigation state
*/
Expand Down Expand Up @@ -31,8 +33,47 @@ const getTopMostReportIDFromRHP = (state: State): string => {
return '';
};

// Check if the given route has a policyID equal to the id provided in the function params
function hasRouteMatchingPolicyID(route: NavigationPartialRoute<CentralPaneName>, policyID?: string) {
if (!route.params) {
return false;
}

const params = `params` in route?.params ? (route.params.params as Record<string, string | undefined>) : undefined;

// If params are not defined, then we need to check if the policyID exists
if (!params) {
return !policyID;
}

return 'policyID' in params && params.policyID === policyID;
}

// Get already opened settings screen within the policy
function getAlreadyOpenedSettingsScreen(rootState?: State, policyID?: string): keyof CentralPaneNavigatorParamList | undefined {
if (!rootState) {
return undefined;
}

// If one of the screen from WORKSPACES_SCREENS is now in the navigation state, we can decide which screen we should display.
// A screen from the navigation state can be pushed to the navigation state again only if it has a matching policyID with the currently selected workspace.
// Otherwise, when we switch the workspace, we want to display the initial screen in the settings tab.
const alreadyOpenedSettingsTab = rootState.routes
.filter((item) => item.params && 'screen' in item.params && WORKSPACES_SCREENS.includes(item.params.screen as keyof CentralPaneNavigatorParamList))
.at(-1);

if (!hasRouteMatchingPolicyID(alreadyOpenedSettingsTab as NavigationPartialRoute<CentralPaneName>, policyID)) {
return undefined;
}

const settingsScreen =
alreadyOpenedSettingsTab?.params && 'screen' in alreadyOpenedSettingsTab?.params ? (alreadyOpenedSettingsTab?.params?.screen as keyof CentralPaneNavigatorParamList) : undefined;

return settingsScreen;
}

// Get matching central pane route for bottom tab navigator. e.g HOME -> REPORT
function getMatchingCentralPaneRouteForState(state: State<RootStackParamList>): NavigationPartialRoute<CentralPaneName> | undefined {
function getMatchingCentralPaneRouteForState(state: State<RootStackParamList>, rootState?: State): NavigationPartialRoute<CentralPaneName> | undefined {
const topmostBottomTabRoute = getTopmostBottomTabRoute(state);

if (!topmostBottomTabRoute) {
Expand All @@ -42,7 +83,10 @@ function getMatchingCentralPaneRouteForState(state: State<RootStackParamList>):
const centralPaneName = TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name][0];

if (topmostBottomTabRoute.name === SCREENS.WORKSPACE.INITIAL) {
return {name: centralPaneName, params: topmostBottomTabRoute.params};
// When we go back to the settings tab without switching the workspace id, we want to return to the previously opened screen
const policyID = topmostBottomTabRoute?.params && 'policyID' in topmostBottomTabRoute?.params ? (topmostBottomTabRoute.params.policyID as string) : undefined;
const screen = getAlreadyOpenedSettingsScreen(rootState, policyID) ?? centralPaneName;
return {name: screen, params: topmostBottomTabRoute.params};
}

if (topmostBottomTabRoute.name === SCREENS.HOME) {
Expand Down

0 comments on commit 687bac0

Please sign in to comment.