Skip to content

Commit

Permalink
Merge pull request #34 from software-mansion-labs/wave8/switch-report…
Browse files Browse the repository at this point in the history
…-with-workspace

Wave8/switch report with workspace
  • Loading branch information
WojtekBoman authored Jan 23, 2024
2 parents 7827673 + 33d6ca3 commit 2e4f00f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 9 deletions.
6 changes: 3 additions & 3 deletions src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import linkingConfig from './linkingConfig';
import linkTo from './linkTo';
import navigationRef from './navigationRef';
import switchPolicyID from './switchPolicyID';
import type {State, StateOrRoute} from './types';
import type {State, StateOrRoute, switchPolicyIDParams} from './types';

let resolveNavigationIsReadyPromise: () => void;
const navigationIsReadyPromise = new Promise<void>((resolve) => {
Expand Down Expand Up @@ -310,12 +310,12 @@ function waitForProtectedRoutes() {
});
}

function navigateWithSwitchPolicyID(policyID: string) {
function navigateWithSwitchPolicyID(params: switchPolicyIDParams) {
if (!canNavigate('navigateWithSwitchPolicyID')) {
return;
}

return switchPolicyID(navigationRef.current, policyID);
return switchPolicyID(navigationRef.current, params);
}

export default {
Expand Down
17 changes: 16 additions & 1 deletion src/libs/Navigation/dismissModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import type {NavigationContainerRef} from '@react-navigation/native';
import {StackActions} from '@react-navigation/native';
import {findLastIndex} from 'lodash';
import Log from '@libs/Log';
import getPolicyMemberAccountIDs from '@libs/PolicyMembersUtils';
import {doesReportBelongToWorkspace, getReport} from '@libs/ReportUtils';
import NAVIGATORS from '@src/NAVIGATORS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import getPolicyIdFromState from './getPolicyIdFromState';
import getStateFromPath from './getStateFromPath';
import getTopmostReportId from './getTopmostReportId';
import linkingConfig from './linkingConfig';
import type {RootStackParamList, StackNavigationAction} from './types';
import switchPolicyID from './switchPolicyID';
import type {RootStackParamList, StackNavigationAction, State} from './types';

// This function is in a separate file than Navigation.js to avoid cyclic dependency.

Expand All @@ -34,6 +39,16 @@ function dismissModal(targetReportID: string, navigationRef: NavigationContainer
// if we are not in the target report, we need to navigate to it after dismissing the modal
if (targetReportID && targetReportID !== getTopmostReportId(state)) {
const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReportID));
const policyID = getPolicyIdFromState(state as State<RootStackParamList>);
const policyMemberAccountIDs = getPolicyMemberAccountIDs(policyID);
const targetReport = getReport(targetReportID);
// If targetReport is an empty object, it means that it's a new report, so it can't belong to any workspace
const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyID, policyMemberAccountIDs);
if (shouldOpenAllWorkspace) {
switchPolicyID(navigationRef, {route: ROUTES.HOME});
} else {
switchPolicyID(navigationRef, {policyID, route: ROUTES.HOME});
}

const action: StackNavigationAction = getActionFromState(reportState, linkingConfig.config);
if (action) {
Expand Down
14 changes: 10 additions & 4 deletions src/libs/Navigation/switchPolicyID.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import getStateFromPath from './getStateFromPath';
import getTopmostCentralPaneRoute from './getTopmostCentralPaneRoute';
import linkingConfig from './linkingConfig';
import TAB_TO_CENTRAL_PANE_MAPPING from './linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING';
import type {NavigationRoot, RootStackParamList, StackNavigationAction, State} from './types';
import type {NavigationRoot, RootStackParamList, StackNavigationAction, State, switchPolicyIDParams} from './types';

type ActionPayloadParams = {
screen?: string;
Expand Down Expand Up @@ -60,7 +60,7 @@ function getActionForBottomTabNavigator(action: StackNavigationAction, state: Na
};
}

export default function switchPolicyID(navigation: NavigationContainerRef<RootStackParamList> | null, policyID: string) {
export default function switchPolicyID(navigation: NavigationContainerRef<RootStackParamList> | null, {policyID, route}: switchPolicyIDParams) {
if (!navigation) {
throw new Error("Couldn't find a navigation object. Is your component inside a screen in a navigator?");
}
Expand All @@ -75,7 +75,7 @@ export default function switchPolicyID(navigation: NavigationContainerRef<RootSt
}

const rootState = navigation.getRootState() as NavigationState<RootStackParamList>;
const newPath = getPathFromState({routes: rootState.routes} as State, linkingConfig.config);
const newPath = route ?? getPathFromState({routes: rootState.routes} as State, linkingConfig.config);
const stateFromPath = getStateFromPath(newPath as Route) as PartialState<NavigationState<RootStackParamList>>;
const action: StackNavigationAction = getActionFromState(stateFromPath, linkingConfig.config);

Expand All @@ -86,6 +86,12 @@ export default function switchPolicyID(navigation: NavigationContainerRef<RootSt
}

root.dispatch(actionForBottomTabNavigator);

// If path is passed to this method, it means that screen is pushed to the Central Pane from another place in code
if (route) {
return;
}

// If the layout is wide we need to push matching central pane route to the stack.
if (!getIsSmallScreenWidth()) {
// Case when the user selects "All" workspace from the specific workspace settings
Expand Down Expand Up @@ -137,7 +143,7 @@ export default function switchPolicyID(navigation: NavigationContainerRef<RootSt
});
}
} else {
// // If the layout is small we need to pop everything from the central pane so the bottom tab navigator is visible.
// If the layout is small we need to pop everything from the central pane so the bottom tab navigator is visible.
root.dispatch({
type: 'POP_TO_TOP',
target: rootState.key,
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,11 @@ type CentralPaneName = keyof CentralPaneNavigatorParamList;

type FullScreenName = keyof SettingsCentralPaneNavigatorParamList;

type switchPolicyIDParams = {
policyID?: string;
route?: Routes;
};

export type {
NavigationRef,
StackNavigationAction,
Expand Down Expand Up @@ -510,4 +515,5 @@ export type {
ReimbursementAccountNavigatorParamList,
State,
WorkspaceSwitcherNavigatorParamList,
switchPolicyIDParams,
};
23 changes: 23 additions & 0 deletions src/libs/PolicyMembersUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {OnyxCollection} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PolicyMembers} from '@src/types/onyx';
import {getCurrentUserAccountID} from './actions/Report';

let policyMembers: OnyxCollection<PolicyMembers>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
waitForCollectionCallback: true,
callback: (value) => (policyMembers = value),
});

function getPolicyMemberAccountIDs(policyID: string) {
const currentUserAccountID = getCurrentUserAccountID();
return policyMembers
? Object.keys(policyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}`] ?? {})
.map((policyMemberAccountID) => Number(policyMemberAccountID))
.filter((policyMemberAccountID) => policyMemberAccountID !== currentUserAccountID)
: [];
}

export default getPolicyMemberAccountIDs;
1 change: 1 addition & 0 deletions src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ function navigateToAndOpenReport(userLogins: string[], shouldDismissModal = true
if (shouldDismissModal) {
Navigation.dismissModal(reportID);
} else {
Navigation.navigateWithSwitchPolicyID({route: ROUTES.HOME});
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/WorkspaceSwitcherPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function WorkspaceSwitcherPage({policies}) {
setActiveWorkspaceID(policyID);
Navigation.goBack();
if (policyID !== activeWorkspaceID) {
Navigation.navigateWithSwitchPolicyID(policyID);
Navigation.navigateWithSwitchPolicyID({policyID});
}
}, []);

Expand Down

0 comments on commit 2e4f00f

Please sign in to comment.