diff --git a/config/eslint/eslint.seatbelt.tsv b/config/eslint/eslint.seatbelt.tsv index 7e1ced82a4d2..6f1977912a2c 100644 --- a/config/eslint/eslint.seatbelt.tsv +++ b/config/eslint/eslint.seatbelt.tsv @@ -1092,8 +1092,8 @@ "../../src/pages/ReimbursementAccount/utils/getSubStepValues.ts" "@typescript-eslint/no-unsafe-type-assertion" 4 "../../src/pages/ReportDescriptionPage.tsx" "no-restricted-imports" 1 "../../src/pages/ReportDescriptionPage.tsx" "no-restricted-syntax" 1 -"../../src/pages/ReportParticipantDetailsPage.tsx" "@typescript-eslint/no-deprecated/ConfirmModal" 1 -"../../src/pages/ReportParticipantDetailsPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 +"../../src/pages/DynamicReportParticipantDetailsPage.tsx" "@typescript-eslint/no-deprecated/ConfirmModal" 1 +"../../src/pages/DynamicReportParticipantDetailsPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 "../../src/pages/ScheduleCall/ScheduleCallPage.tsx" "react-hooks/preserve-manual-memoization" 1 "../../src/pages/Search/AdvancedSearchFilters.tsx" "@typescript-eslint/no-unsafe-type-assertion" 17 "../../src/pages/Search/EmptySearchView.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 03d6054d2a70..cc1c2b7f193f 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -131,6 +131,10 @@ const DYNAMIC_ROUTES = { path: 'imported-members-role', entryScreens: [SCREENS.WORKSPACE.MEMBERS_IMPORTED_CONFIRMATION], }, + REPORT_SETTINGS: { + path: 'report-settings', + entryScreens: [SCREENS.REPORT_DETAILS.DYNAMIC_ROOT], + }, PAYMENT_CARD_CURRENCY_SELECTOR: { path: 'payment-card-currency', entryScreens: [SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_BILLING_CURRENCY, SCREENS.SETTINGS.SUBSCRIPTION.ADD_PAYMENT_CARD, SCREENS.WORKSPACE.OWNER_CHANGE_CHECK], @@ -141,11 +145,11 @@ const DYNAMIC_ROUTES = { }, REPORT_SETTINGS_WRITE_CAPABILITY: { path: 'who-can-post', - entryScreens: [SCREENS.REPORT_SETTINGS.ROOT], + entryScreens: [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT], }, REPORT_SETTINGS_VISIBILITY: { path: 'visibility', - entryScreens: [SCREENS.REPORT_SETTINGS.ROOT], + entryScreens: [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT], }, CHANGE_POLICY_EDUCATIONAL: { path: 'change-workspace-educational', @@ -523,7 +527,7 @@ const DYNAMIC_ROUTES = { }, NOTIFICATION_PREFERENCES: { path: 'notification-preferences', - entryScreens: [SCREENS.REPORT_SETTINGS.ROOT, SCREENS.DYNAMIC_PROFILE], + entryScreens: [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT, SCREENS.DYNAMIC_PROFILE], getRoute: (reportID: string) => getUrlWithParams('notification-preferences', {reportID}), queryParams: ['reportID'], }, @@ -724,6 +728,30 @@ const DYNAMIC_ROUTES = { getRoute: (reportID: string) => getUrlWithParams('details', {reportID}), queryParams: ['reportID'], }, + REPORT_PARTICIPANTS: { + path: 'participants', + entryScreens: [ + SCREENS.REPORT, + SCREENS.RIGHT_MODAL.SEARCH_REPORT, + SCREENS.RIGHT_MODAL.EXPENSE_REPORT, + SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT, + SCREENS.SEARCH.ROOT, + SCREENS.REPORT_DETAILS.DYNAMIC_ROOT, + ], + }, + REPORT_PARTICIPANTS_INVITE: { + path: 'participants-invite', + entryScreens: [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROOT], + }, + REPORT_PARTICIPANTS_DETAILS: { + path: 'participants-details/:accountID', + entryScreens: [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROOT], + getRoute: (accountID: number) => `participants-details/${accountID}` as const, + }, + REPORT_PARTICIPANTS_ROLE: { + path: 'participants-role', + entryScreens: [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_DETAILS], + }, REPORT_DETAILS_SHARE_CODE: { path: 'share-code', entryScreens: [ @@ -1491,31 +1519,6 @@ const ROUTES = { route: `e/:reportID/${VERIFY_ACCOUNT}`, getRoute: (reportID: string) => `e/${reportID}/${VERIFY_ACCOUNT}` as const, }, - REPORT_PARTICIPANTS: { - route: 'r/:reportID/participants', - - getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants` as const, backTo), - }, - REPORT_PARTICIPANTS_INVITE: { - route: 'r/:reportID/participants/invite', - - getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants/invite` as const, backTo), - }, - REPORT_PARTICIPANTS_DETAILS: { - route: 'r/:reportID/participants/:accountID', - - getRoute: (reportID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants/${accountID}` as const, backTo), - }, - REPORT_PARTICIPANTS_ROLE_SELECTION: { - route: 'r/:reportID/participants/:accountID/role', - - getRoute: (reportID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants/${accountID}/role` as const, backTo), - }, - REPORT_SETTINGS: { - route: 'r/:reportID/settings', - - getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/settings` as const, backTo), - }, REPORT_CHANGE_APPROVER_ADD_APPROVER: { route: 'r/:reportID/change-approver/add', getRoute: (reportID: string) => `r/${reportID}/change-approver/add` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index cc9c10d594ad..6ece80eac539 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -488,7 +488,7 @@ const SCREENS = { }, REPORT_SETTINGS: { - ROOT: 'Report_Settings_Root', + DYNAMIC_ROOT: 'Dynamic_Report_Settings_Root', DYNAMIC_NOTIFICATION_PREFERENCES: 'Dynamic_Report_Settings_Notification_Preferences', DYNAMIC_SETTINGS_NAME: 'Dynamic_Report_Settings_Name', DYNAMIC_SETTINGS_WRITE_CAPABILITY: 'Dynamic_Report_Settings_Write_Capability', @@ -1001,10 +1001,10 @@ const SCREENS = { REPORT_DESCRIPTION_ROOT: 'Report_Description_Root', CHRONOS_SCHEDULE_OOO_ROOT: 'Chronos_Schedule_OOO_Root', REPORT_PARTICIPANTS: { - ROOT: 'ReportParticipants_Root', - INVITE: 'ReportParticipants_Invite', - DETAILS: 'ReportParticipants_Details', - ROLE: 'ReportParticipants_Role', + DYNAMIC_ROOT: 'Dynamic_ReportParticipants_Root', + DYNAMIC_INVITE: 'Dynamic_ReportParticipants_Invite', + DYNAMIC_DETAILS: 'Dynamic_ReportParticipants_Details', + DYNAMIC_ROLE: 'Dynamic_ReportParticipants_Role', }, ROOM_MEMBERS: { DYNAMIC_ROOT: 'Dynamic_RoomMembers_Root', diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index dff68880f779..cc88299d72fe 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -39,7 +39,7 @@ import { import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import {getButtonRole} from './Button/utils'; import DisplayNames from './DisplayNames'; @@ -251,7 +251,7 @@ function AvatarWithDisplayName({ } if (isIOUReport(report) && report?.reportID) { - Navigation.navigate(ROUTES.REPORT_PARTICIPANTS.getRoute(report.reportID)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS.path)); return; } diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 668a25069717..40ea5087b3b1 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -274,7 +274,7 @@ const ReportChangeApproverModalStackNavigator = createModalStackNavigator({ - [SCREENS.REPORT_SETTINGS.ROOT]: () => require('../../../../pages/settings/Report/ReportSettingsPage').default, + [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT]: () => require('../../../../pages/settings/Report/DynamicReportSettingsPage').default, [SCREENS.REPORT_SETTINGS.DYNAMIC_NOTIFICATION_PREFERENCES]: () => require('../../../../pages/settings/Report/DynamicNotificationPreferencePage').default, [SCREENS.REPORT_SETTINGS.DYNAMIC_SETTINGS_NAME]: () => require('../../../../pages/settings/Report/DynamicNamePage').default, [SCREENS.REPORT_SETTINGS.DYNAMIC_SETTINGS_WRITE_CAPABILITY]: () => require('../../../../pages/settings/Report/DynamicWriteCapabilityPage').default, @@ -360,10 +360,10 @@ const DomainCardModalStackNavigator = createModalStackNavigator({ }); const ReportParticipantsModalStackNavigator = createModalStackNavigator({ - [SCREENS.REPORT_PARTICIPANTS.ROOT]: () => require('../../../../pages/ReportParticipantsPage').default, - [SCREENS.REPORT_PARTICIPANTS.INVITE]: () => require('../../../../pages/InviteReportParticipantsPage').default, - [SCREENS.REPORT_PARTICIPANTS.DETAILS]: () => require('../../../../pages/ReportParticipantDetailsPage').default, - [SCREENS.REPORT_PARTICIPANTS.ROLE]: () => require('../../../../pages/ReportParticipantRoleSelectionPage').default, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROOT]: () => require('../../../../pages/DynamicReportParticipantsPage').default, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_INVITE]: () => require('../../../../pages/DynamicReportParticipantsInvitePage').default, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_DETAILS]: () => require('../../../../pages/DynamicReportParticipantDetailsPage').default, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROLE]: () => require('../../../../pages/DynamicReportParticipantRoleSelectionPage').default, }); const RoomMembersModalStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/OldRoutes.ts b/src/libs/Navigation/linkingConfig/OldRoutes.ts index 67e9769fdb02..c2f6fae87a33 100644 --- a/src/libs/Navigation/linkingConfig/OldRoutes.ts +++ b/src/libs/Navigation/linkingConfig/OldRoutes.ts @@ -12,7 +12,10 @@ const oldRoutes: Record = { '/workspaces/*/category/*': '/workspaces/$1/categories/category/$2', '/settings/workspaces/*': '/workspaces/$1', '/settings/workspaces': '/workspaces', + '/r/*/settings': '/r/$1/details/report-settings', '/r/*/settings/name': '/r/$1/details/settings/name', + '/r/*/participants/invite': '/r/$1/participants/participants-invite', + '/r/*/participants/*/role': '/r/$1/participants/participants-details/$2/participants-role', '/r/*/title': '/r/$1/title', '/r/*/description': '/r/$1/description', '/r/*/assignee': '/r/$1/assignee', diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 470bfeec483e..c1184aea904c 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1523,9 +1523,7 @@ const config: LinkingOptions['config'] = { }, [SCREENS.RIGHT_MODAL.REPORT_SETTINGS]: { screens: { - [SCREENS.REPORT_SETTINGS.ROOT]: { - path: ROUTES.REPORT_SETTINGS.route, - }, + [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT]: DYNAMIC_ROUTES.REPORT_SETTINGS.path, [SCREENS.REPORT_SETTINGS.DYNAMIC_NOTIFICATION_PREFERENCES]: DYNAMIC_ROUTES.NOTIFICATION_PREFERENCES.path, [SCREENS.REPORT_SETTINGS.DYNAMIC_SETTINGS_NAME]: DYNAMIC_ROUTES.REPORT_SETTINGS_NAME.path, [SCREENS.REPORT_SETTINGS.DYNAMIC_SETTINGS_WRITE_CAPABILITY]: DYNAMIC_ROUTES.REPORT_SETTINGS_WRITE_CAPABILITY.path, @@ -1683,10 +1681,10 @@ const config: LinkingOptions['config'] = { }, [SCREENS.RIGHT_MODAL.PARTICIPANTS]: { screens: { - [SCREENS.REPORT_PARTICIPANTS.ROOT]: ROUTES.REPORT_PARTICIPANTS.route, - [SCREENS.REPORT_PARTICIPANTS.INVITE]: ROUTES.REPORT_PARTICIPANTS_INVITE.route, - [SCREENS.REPORT_PARTICIPANTS.DETAILS]: ROUTES.REPORT_PARTICIPANTS_DETAILS.route, - [SCREENS.REPORT_PARTICIPANTS.ROLE]: ROUTES.REPORT_PARTICIPANTS_ROLE_SELECTION.route, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROOT]: DYNAMIC_ROUTES.REPORT_PARTICIPANTS.path, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_INVITE]: DYNAMIC_ROUTES.REPORT_PARTICIPANTS_INVITE.path, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_DETAILS]: DYNAMIC_ROUTES.REPORT_PARTICIPANTS_DETAILS.path, + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROLE]: DYNAMIC_ROUTES.REPORT_PARTICIPANTS_ROLE.path, }, }, [SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 6bd1d14f56dd..3a8c6f32ac86 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1780,10 +1780,8 @@ type ReportChangeWorkspaceNavigatorParamList = { }; type ReportSettingsNavigatorParamList = { - [SCREENS.REPORT_SETTINGS.ROOT]: { + [SCREENS.REPORT_SETTINGS.DYNAMIC_ROOT]: { reportID: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; [SCREENS.REPORT_SETTINGS.DYNAMIC_SETTINGS_NAME]: { reportID: string; @@ -1815,27 +1813,19 @@ type ChronosScheduleOOONavigatorParamList = { }; type ParticipantsNavigatorParamList = { - [SCREENS.REPORT_PARTICIPANTS.ROOT]: { + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROOT]: { reportID: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; - [SCREENS.REPORT_PARTICIPANTS.INVITE]: { + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_INVITE]: { reportID: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; - [SCREENS.REPORT_PARTICIPANTS.DETAILS]: { + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_DETAILS]: { reportID: string; accountID: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; - [SCREENS.REPORT_PARTICIPANTS.ROLE]: { + [SCREENS.REPORT_PARTICIPANTS.DYNAMIC_ROLE]: { reportID: string; accountID: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; }; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ab1aca3a4e5e..dd06aa1db7d7 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5913,7 +5913,8 @@ function goBackToDetailsPage(report: OnyxEntry, backTo?: Route, shouldGo if (shouldGoBackToDetailsPage) { Navigation.goBack(backTo ?? createDynamicRoute(DYNAMIC_ROUTES.REPORT_DETAILS.path, ROUTES.REPORT_WITH_ID.getRoute(report.reportID))); } else { - Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(report.reportID, backTo)); + const reportDetailsPath = createDynamicRoute(DYNAMIC_ROUTES.REPORT_DETAILS.path, ROUTES.REPORT_WITH_ID.getRoute(report.reportID)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.REPORT_SETTINGS.path, reportDetailsPath)); } } else { Log.warn('Missing reportID during navigation back to the details page'); diff --git a/src/pages/DynamicReportDetailsPage.tsx b/src/pages/DynamicReportDetailsPage.tsx index be8239c32a55..55296b2e4790 100644 --- a/src/pages/DynamicReportDetailsPage.tsx +++ b/src/pages/DynamicReportDetailsPage.tsx @@ -455,7 +455,7 @@ function DynamicReportDetailsPage({policy, report, route, reportMetadata, report if (shouldOpenRoomMembersPage) { Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.ROOM_MEMBERS.path)); } else { - Navigation.navigate(ROUTES.REPORT_PARTICIPANTS.getRoute(report?.reportID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS.path)); } }, }); @@ -480,7 +480,7 @@ function DynamicReportDetailsPage({policy, report, route, reportMetadata, report isAnonymousAction: false, shouldShowRightIcon: true, action: () => { - Navigation.navigate(ROUTES.REPORT_SETTINGS.getRoute(report?.reportID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_SETTINGS.path)); }, }); } diff --git a/src/pages/ReportParticipantDetailsPage.tsx b/src/pages/DynamicReportParticipantDetailsPage.tsx similarity index 89% rename from src/pages/ReportParticipantDetailsPage.tsx rename to src/pages/DynamicReportParticipantDetailsPage.tsx index d3c1cdf3dc76..4091481f3d74 100644 --- a/src/pages/ReportParticipantDetailsPage.tsx +++ b/src/pages/DynamicReportParticipantDetailsPage.tsx @@ -11,6 +11,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useIsInLandscapeMode from '@hooks/useIsInLandscapeMode'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; @@ -26,16 +27,16 @@ import Navigation from '@navigation/Navigation'; import type {ParticipantsNavigatorParamList} from '@navigation/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {PersonalDetails} from '@src/types/onyx'; import NotFoundPage from './ErrorPage/NotFoundPage'; import withReportOrNotFound from './inbox/report/withReportOrNotFound'; import type {WithReportOrNotFoundProps} from './inbox/report/withReportOrNotFound'; -type ReportParticipantDetailsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; +type DynamicReportParticipantDetailsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; -function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageProps) { +function DynamicReportParticipantDetails({report, route}: DynamicReportParticipantDetailsPageProps) { const icons = useMemoizedLazyExpensifyIcons(['RemoveMembers', 'Info']); const isInLandscapeMode = useIsInLandscapeMode(); const styles = useThemeStyles(); @@ -47,7 +48,7 @@ function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageP const [isRemoveMemberConfirmModalVisible, setIsRemoveMemberConfirmModalVisible] = React.useState(false); const accountID = Number(route.params.accountID); - const backTo = ROUTES.REPORT_PARTICIPANTS.getRoute(report?.reportID, route.params.backTo); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_DETAILS.path); const member = report?.participants?.[accountID]; const details = personalDetails?.[accountID] ?? ({} as PersonalDetails); @@ -58,7 +59,7 @@ function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageP const removeUser = () => { setIsRemoveMemberConfirmModalVisible(false); removeFromGroupChat(report, [accountID]); - Navigation.goBack(backTo); + Navigation.goBack(backPath); }; const navigateToProfile = () => { @@ -66,7 +67,7 @@ function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageP }; const openRoleSelectionModal = () => { - Navigation.navigate(ROUTES.REPORT_PARTICIPANTS_ROLE_SELECTION.getRoute(report.reportID, accountID, route.params.backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_ROLE.path)); }; if (!member) { @@ -74,10 +75,10 @@ function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageP } return ( - + Navigation.goBack(backTo)} + onBackButtonPress={() => Navigation.goBack(backPath)} /> @@ -145,4 +146,4 @@ function ReportParticipantDetails({report, route}: ReportParticipantDetailsPageP ); } -export default withReportOrNotFound()(ReportParticipantDetails); +export default withReportOrNotFound()(DynamicReportParticipantDetails); diff --git a/src/pages/ReportParticipantRoleSelectionPage.tsx b/src/pages/DynamicReportParticipantRoleSelectionPage.tsx similarity index 77% rename from src/pages/ReportParticipantRoleSelectionPage.tsx rename to src/pages/DynamicReportParticipantRoleSelectionPage.tsx index e855a76d4e09..c5c7f4021dbb 100644 --- a/src/pages/ReportParticipantRoleSelectionPage.tsx +++ b/src/pages/DynamicReportParticipantRoleSelectionPage.tsx @@ -6,6 +6,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem'; import type {ListItem} from '@components/SelectionList/ListItem/types'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import {updateGroupChatMemberRoles} from '@libs/actions/Report'; @@ -13,24 +14,24 @@ import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavig import Navigation from '@navigation/Navigation'; import type {ParticipantsNavigatorParamList} from '@navigation/types'; import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import NotFoundPage from './ErrorPage/NotFoundPage'; import withReportOrNotFound from './inbox/report/withReportOrNotFound'; import type {WithReportOrNotFoundProps} from './inbox/report/withReportOrNotFound'; -type ReportParticipantRoleSelectionPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; +type DynamicReportParticipantRoleSelectionPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; type ListItemType = ListItem & { value: ValueOf; }; -function ReportParticipantRoleSelectionPage({report, route}: ReportParticipantRoleSelectionPageProps) { +function DynamicReportParticipantRoleSelectionPage({report, route}: DynamicReportParticipantRoleSelectionPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const accountID = Number(route?.params?.accountID) ?? -1; - const backTo = ROUTES.REPORT_PARTICIPANTS_DETAILS.getRoute(report.reportID, accountID, route.params.backTo); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_ROLE.path); const member = report.participants?.[accountID]; if (!member) { @@ -54,14 +55,14 @@ function ReportParticipantRoleSelectionPage({report, route}: ReportParticipantRo const changeRole = ({value}: ListItemType) => { updateGroupChatMemberRoles(report.reportID, [accountID], value); - Navigation.goBack(backTo); + Navigation.goBack(backPath); }; return ( - + Navigation.goBack(backTo)} + onBackButtonPress={() => Navigation.goBack(backPath)} /> >; -function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProps) { - const route = useRoute>(); +function DynamicReportParticipantsInvitePage({report}: DynamicReportParticipantsInvitePageProps) { const styles = useThemeStyles(); const {translate, formatPhoneNumber} = useLocalize(); const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE); const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_INVITE.path); // Any existing participants and Expensify emails should not be eligible for invitation const excludedUsers: Record = { @@ -110,11 +107,10 @@ function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProp toggleSelection(option); }; - const reportID = report.reportID; const reportName = getGroupChatName(formatPhoneNumber, undefined, true, report); const goBack = () => { - Navigation.goBack(ROUTES.REPORT_PARTICIPANTS.getRoute(reportID, route.params.backTo)); + Navigation.goBack(backPath); }; const inviteUsers = () => { @@ -175,7 +171,7 @@ function InviteReportParticipantsPage({report}: InviteReportParticipantsPageProp return ( setDidScreenTransitionEnd(true)} > & {accountID: number}; -type ReportParticipantsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; -function ReportParticipantsPage({report, route}: ReportParticipantsPageProps) { - const backTo = route.params.backTo; +type DynamicReportParticipantsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; +function DynamicReportParticipantsPage({report}: DynamicReportParticipantsPageProps) { + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_PARTICIPANTS.path); const navigateBackToReportDetails = useCallback(() => { - if (!report) { - return; - } - Navigation.goBack(backTo ?? createDynamicRoute(DYNAMIC_ROUTES.REPORT_DETAILS.path, ROUTES.REPORT_WITH_ID.getRoute(report.reportID))); - }, [backTo, report]); + Navigation.goBack(backPath); + }, [backPath]); const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar', 'MakeAdmin', 'Plus', 'RemoveMembers', 'User']); const {translate, formatPhoneNumber, localeCompare} = useLocalize(); const {showConfirmModal} = useConfirmModal(); @@ -222,7 +220,7 @@ function ReportParticipantsPage({report, route}: ReportParticipantsPageProps) { const openMemberDetails = (item: MemberOption) => { if (isGroupChat && isCurrentUserAdmin) { - Navigation.navigate(ROUTES.REPORT_PARTICIPANTS_DETAILS.getRoute(report.reportID, item.accountID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_DETAILS.getRoute(item.accountID))); return; } Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.PROFILE.getRoute(item.accountID))); @@ -326,7 +324,7 @@ function ReportParticipantsPage({report, route}: ReportParticipantsPageProps) { Navigation.navigate(ROUTES.REPORT_PARTICIPANTS_INVITE.getRoute(report.reportID, backTo))} + onPress={() => Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS_INVITE.path))} text={translate('workspace.invite.member')} icon={icons.Plus} innerStyles={[shouldUseNarrowLayout && styles.alignItemsCenter]} @@ -403,4 +401,4 @@ function ReportParticipantsPage({report, route}: ReportParticipantsPageProps) { ); } -export default withReportOrNotFound()(ReportParticipantsPage); +export default withReportOrNotFound()(DynamicReportParticipantsPage); diff --git a/src/pages/inbox/report/ReportActionItemSingle.tsx b/src/pages/inbox/report/ReportActionItemSingle.tsx index ad55749a8bde..af89c1df105a 100644 --- a/src/pages/inbox/report/ReportActionItemSingle.tsx +++ b/src/pages/inbox/report/ReportActionItemSingle.tsx @@ -20,7 +20,7 @@ import Navigation from '@libs/Navigation/Navigation'; import {getDelegateAccountIDFromReportAction, getHumanAgentAccountIDFromReportAction, getManagerOnVacation, getModerationFlagState, getVacationer} from '@libs/ReportActionsUtils'; import {isOptimisticPersonalDetail} from '@libs/ReportUtils'; import CONST from '@src/CONST'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Report, ReportAction} from '@src/types/onyx'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import DelegateOnBehalfOfText from './DelegateOnBehalfOfText'; @@ -112,7 +112,7 @@ function ReportActionItemSingle({ } else { // Show participants page IOU report preview if (iouReportID && details.shouldDisplayAllActors) { - Navigation.navigate(ROUTES.REPORT_PARTICIPANTS.getRoute(iouReportID, Navigation.getReportRHPActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.REPORT_PARTICIPANTS.path)); return; } showUserDetails(Number(primaryAvatar.id)); diff --git a/src/pages/inbox/report/withReportOrNotFound.tsx b/src/pages/inbox/report/withReportOrNotFound.tsx index 7c65c27518bd..e83f2f1ef259 100644 --- a/src/pages/inbox/report/withReportOrNotFound.tsx +++ b/src/pages/inbox/report/withReportOrNotFound.tsx @@ -49,12 +49,13 @@ type WithReportOrNotFoundOnyxProps = { type ScreenProps = | PlatformStackScreenProps | PlatformStackScreenProps - | PlatformStackScreenProps - | PlatformStackScreenProps - | PlatformStackScreenProps + | PlatformStackScreenProps + | PlatformStackScreenProps + | PlatformStackScreenProps + | PlatformStackScreenProps | PlatformStackScreenProps | PlatformStackScreenProps - | PlatformStackScreenProps + | PlatformStackScreenProps | PlatformStackScreenProps | PlatformStackScreenProps | PlatformStackScreenProps diff --git a/src/pages/settings/Report/ReportSettingsPage.tsx b/src/pages/settings/Report/DynamicReportSettingsPage.tsx similarity index 91% rename from src/pages/settings/Report/ReportSettingsPage.tsx rename to src/pages/settings/Report/DynamicReportSettingsPage.tsx index 39fb5ab04bea..c3c12118b751 100644 --- a/src/pages/settings/Report/ReportSettingsPage.tsx +++ b/src/pages/settings/Report/DynamicReportSettingsPage.tsx @@ -6,6 +6,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useReportIsArchived from '@hooks/useReportIsArchived'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -26,16 +27,17 @@ import type {ReportSettingsNavigatorParamList} from '@navigation/types'; import withReportOrNotFound from '@pages/inbox/report/withReportOrNotFound'; import type {WithReportOrNotFoundProps} from '@pages/inbox/report/withReportOrNotFound'; import CONST from '@src/CONST'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -type ReportSettingsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; +type DynamicReportSettingsPageProps = WithReportOrNotFoundProps & PlatformStackScreenProps; -function ReportSettingsPage({report, policy}: ReportSettingsPageProps) { +function DynamicReportSettingsPage({report, policy}: DynamicReportSettingsPageProps) { const reportID = report?.reportID; const styles = useThemeStyles(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_SETTINGS.path); const isReportArchived = useReportIsArchived(reportID); const isArchivedNonExpenseReport = isArchivedNonExpenseReportUtils(report, isReportArchived); // The workspace the report is on, null if the user isn't a member of the workspace @@ -57,11 +59,11 @@ function ReportSettingsPage({report, policy}: ReportSettingsPageProps) { const shouldShowWriteCapability = !isMoneyRequestReport; return ( - + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.REPORT_DETAILS.path, ROUTES.REPORT_WITH_ID.getRoute(reportID)))} + onBackButtonPress={() => Navigation.goBack(backPath)} /> {shouldShowNotificationPref && ( @@ -130,4 +132,4 @@ function ReportSettingsPage({report, policy}: ReportSettingsPageProps) { ); } -export default withReportOrNotFound()(ReportSettingsPage); +export default withReportOrNotFound()(DynamicReportSettingsPage); diff --git a/tests/navigation/getMatchingNewRouteTest.ts b/tests/navigation/getMatchingNewRouteTest.ts index de55c2cc8f19..a5f1c2323df7 100644 --- a/tests/navigation/getMatchingNewRouteTest.ts +++ b/tests/navigation/getMatchingNewRouteTest.ts @@ -31,6 +31,14 @@ describe('getBestMatchingPath', () => { expect(getMatchingNewRoute('/r/123/settings/name?backTo=/home')).toBe('/r/123/details/settings/name?backTo=/home'); }); + it('redirects old report settings root path to dynamic report settings', () => { + expect(getMatchingNewRoute('/r/123/settings')).toBe('/r/123/details/report-settings'); + }); + + it('preserves query params when redirecting report settings root', () => { + expect(getMatchingNewRoute('/r/123/settings?backTo=/home')).toBe('/r/123/details/report-settings?backTo=/home'); + }); + it('redirects old task title path', () => { expect(getMatchingNewRoute('/r/123/title')).toBe('/r/123/title'); }); @@ -71,6 +79,15 @@ describe('getBestMatchingPath', () => { expect(getMatchingNewRoute('/r/123/notes/456/edit')).toBe('/r/123/notes-edit/456'); }); + it('redirects old report participants invite path to the dynamic route', () => { + expect(getMatchingNewRoute('/r/123/participants/invite')).toBe('/r/123/participants/participants-invite'); + }); + + it('preserves query params when redirecting report participant routes', () => { + expect(getMatchingNewRoute('/r/123/participants/invite?backTo=/home')).toBe('/r/123/participants/participants-invite?backTo=/home'); + expect(getMatchingNewRoute('/r/123/participants/456/role?backTo=/home')).toBe('/r/123/participants/participants-details/456/participants-role?backTo=/home'); + }); + it('redirects old workspace overview address path', () => { expect(getMatchingNewRoute('/workspaces/abc/overview/address')).toBe('/workspaces/abc/overview/workspace-address'); });