From 833ea1f047e1a9d97a6610c8dac0f0e7848a87aa Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Tue, 13 Feb 2024 10:14:20 +0100 Subject: [PATCH 1/3] Add helper functions in getMatchingCentralPaneRouteForState --- src/libs/Navigation/linkTo.ts | 2 +- .../getMatchingCentralPaneRouteForState.ts | 46 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts index 5a765d9a7d37..3f0baa8d1ab9 100644 --- a/src/libs/Navigation/linkTo.ts +++ b/src/libs/Navigation/linkTo.ts @@ -215,7 +215,7 @@ export default function linkTo(navigation: NavigationContainerRef { return ''; }; +// Function that checks if the given route has a policyID equal to the id provided in the function params +function hasRouteMatchingPolicyID(route: NavigationPartialRoute, policyID?: string) { + return ( + route?.params && + 'params' in route?.params && + route.params.params && + 'policyID' in (route.params.params as Record) && + (route.params.params as Record).policyID === policyID + ); +} + +// Function that restores already open screen in the settings tab. Thanks to this function, we are able to open the already selected screen in the workspace settings when we return from another tab. +function getAlreadyOpenSettingsScreen(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 WORKSPACES_SCREENS = TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.WORKSPACE.INITIAL].concat(TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.ALL_SETTINGS]); + + const alreadyOpenedSettingsTab = rootState.routes + .filter((item) => item.params && 'screen' in item.params && WORKSPACES_SCREENS.includes(item.params.screen as keyof CentralPaneNavigatorParamList)) + .at(-1); + + if ( + alreadyOpenedSettingsTab?.params && + 'screen' in alreadyOpenedSettingsTab?.params && + hasRouteMatchingPolicyID(alreadyOpenedSettingsTab as NavigationPartialRoute, policyID) + ) { + return alreadyOpenedSettingsTab?.params?.screen as keyof CentralPaneNavigatorParamList; + } + + return undefined; +} + // Get matching central pane route for bottom tab navigator. e.g HOME -> REPORT -function getMatchingCentralPaneRouteForState(state: State): NavigationPartialRoute | undefined { +function getMatchingCentralPaneRouteForState(state: State, rootState?: State): NavigationPartialRoute | undefined { const topmostBottomTabRoute = getTopmostBottomTabRoute(state); if (!topmostBottomTabRoute) { @@ -42,7 +79,10 @@ function getMatchingCentralPaneRouteForState(state: State): 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 open screen + const policyID = topmostBottomTabRoute?.params && 'policyID' in topmostBottomTabRoute?.params ? (topmostBottomTabRoute.params.policyID as string) : undefined; + const alreadyOpenedSettingsTab = getAlreadyOpenSettingsScreen(rootState, policyID) ?? centralPaneName; + return {name: alreadyOpenedSettingsTab, params: topmostBottomTabRoute.params}; } if (topmostBottomTabRoute.name === SCREENS.HOME) { From 7d1891458e2cb2084d37df8d172c586ec011ddb2 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Tue, 13 Feb 2024 15:41:27 +0100 Subject: [PATCH 2/3] Refactor getMatchingCentralPaneRouteForState --- .../getMatchingCentralPaneRouteForState.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts index 561cb3a0d47e..73587c5af01f 100644 --- a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts +++ b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts @@ -42,8 +42,8 @@ function hasRouteMatchingPolicyID(route: NavigationPartialRoute ); } -// Function that restores already open screen in the settings tab. Thanks to this function, we are able to open the already selected screen in the workspace settings when we return from another tab. -function getAlreadyOpenSettingsScreen(rootState?: State, policyID?: string): keyof CentralPaneNavigatorParamList | undefined { +// Function that restores already opened screen in the settings tab. Thanks to this function, we are able to open the already selected screen in the workspace settings when we return from another tab. +function getAlreadyOpenedSettingsScreen(rootState?: State, policyID?: string): keyof CentralPaneNavigatorParamList | undefined { if (!rootState) { return undefined; } @@ -79,10 +79,10 @@ function getMatchingCentralPaneRouteForState(state: State, r const centralPaneName = TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name][0]; if (topmostBottomTabRoute.name === SCREENS.WORKSPACE.INITIAL) { - // When we go back to the settings tab without switching the workspace id, we want to return to the previously open screen + // 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 alreadyOpenedSettingsTab = getAlreadyOpenSettingsScreen(rootState, policyID) ?? centralPaneName; - return {name: alreadyOpenedSettingsTab, params: topmostBottomTabRoute.params}; + const screen = getAlreadyOpenedSettingsScreen(rootState, policyID) ?? centralPaneName; + return {name: screen, params: topmostBottomTabRoute.params}; } if (topmostBottomTabRoute.name === SCREENS.HOME) { From b21f8d7d0d0644dd24c400c588cd5be4a6aabc07 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 21 Feb 2024 10:23:03 +0100 Subject: [PATCH 3/3] Refactor hasRouteMatchingPolicyID and getAlreadyOpenedSettingsScreen --- .../getMatchingCentralPaneRouteForState.ts | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts index 73587c5af01f..02ad78a4c044 100644 --- a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts +++ b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts @@ -4,6 +4,8 @@ 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 */ @@ -31,18 +33,23 @@ const getTopMostReportIDFromRHP = (state: State): string => { return ''; }; -// Function that checks if the given route has a policyID equal to the id provided in the function params +// Check if the given route has a policyID equal to the id provided in the function params function hasRouteMatchingPolicyID(route: NavigationPartialRoute, policyID?: string) { - return ( - route?.params && - 'params' in route?.params && - route.params.params && - 'policyID' in (route.params.params as Record) && - (route.params.params as Record).policyID === policyID - ); + if (!route.params) { + return false; + } + + const params = `params` in route?.params ? (route.params.params as Record) : 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; } -// Function that restores already opened screen in the settings tab. Thanks to this function, we are able to open the already selected screen in the workspace settings when we return from another tab. +// Get already opened settings screen within the policy function getAlreadyOpenedSettingsScreen(rootState?: State, policyID?: string): keyof CentralPaneNavigatorParamList | undefined { if (!rootState) { return undefined; @@ -51,21 +58,18 @@ function getAlreadyOpenedSettingsScreen(rootState?: State, policyID?: string): k // 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 WORKSPACES_SCREENS = TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.WORKSPACE.INITIAL].concat(TAB_TO_CENTRAL_PANE_MAPPING[SCREENS.ALL_SETTINGS]); - const alreadyOpenedSettingsTab = rootState.routes .filter((item) => item.params && 'screen' in item.params && WORKSPACES_SCREENS.includes(item.params.screen as keyof CentralPaneNavigatorParamList)) .at(-1); - if ( - alreadyOpenedSettingsTab?.params && - 'screen' in alreadyOpenedSettingsTab?.params && - hasRouteMatchingPolicyID(alreadyOpenedSettingsTab as NavigationPartialRoute, policyID) - ) { - return alreadyOpenedSettingsTab?.params?.screen as keyof CentralPaneNavigatorParamList; + if (!hasRouteMatchingPolicyID(alreadyOpenedSettingsTab as NavigationPartialRoute, policyID)) { + return undefined; } - 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