From a29d34e8188f1d1f349dde3b6ba51b4fe61ac8be Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:58:09 +0200 Subject: [PATCH 01/16] Revert "[Revert] #36409 "Fix: three not found view"" This reverts commit 0237f277c0d3c363ee1b20115df440f63da0b538. --- src/libs/Navigation/Navigation.ts | 7 + src/libs/Navigation/dismissRHP.ts | 25 ++++ src/pages/workspace/WorkspaceInitialPage.tsx | 14 ++ .../workspace/WorkspaceInviteMessagePage.tsx | 3 + src/pages/workspace/WorkspaceMembersPage.tsx | 121 ++++++++---------- .../workspace/WorkspacePageWithSections.tsx | 14 +- 6 files changed, 116 insertions(+), 68 deletions(-) create mode 100644 src/libs/Navigation/dismissRHP.ts diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 6f5e86f057d8..de45f27022d2 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -14,6 +14,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject'; import originalCloseRHPFlow from './closeRHPFlow'; import originalDismissModal from './dismissModal'; import originalDismissModalWithReport from './dismissModalWithReport'; +import originalDismissRHP from './dismissRHP'; import originalGetTopmostReportActionId from './getTopmostReportActionID'; import originalGetTopmostReportId from './getTopmostReportId'; import linkingConfig from './linkingConfig'; @@ -64,6 +65,11 @@ const dismissModal = (reportID?: string, ref = navigationRef) => { // Re-exporting the closeRHPFlow here to fill in default value for navigationRef. The closeRHPFlow isn't defined in this file to avoid cyclic dependencies. const closeRHPFlow = (ref = navigationRef) => originalCloseRHPFlow(ref); +// Re-exporting the dismissRHP here to fill in default value for navigationRef. The dismissRHP isn't defined in this file to avoid cyclic dependencies. +const dismissRHP = (ref = navigationRef) => { + originalDismissRHP(ref); +}; + // Re-exporting the dismissModalWithReport here to fill in default value for navigationRef. The dismissModalWithReport isn't defined in this file to avoid cyclic dependencies. // This method is needed because it allows to dismiss the modal and then open the report. Within this method is checked whether the report belongs to a specific workspace. Sometimes the report we want to check, hasn't been added to the Onyx yet. // Then we can pass the report as a param without getting it from the Onyx. @@ -367,6 +373,7 @@ export default { setShouldPopAllStateOnUP, navigate, setParams, + dismissRHP, dismissModal, dismissModalWithReport, isActiveRoute, diff --git a/src/libs/Navigation/dismissRHP.ts b/src/libs/Navigation/dismissRHP.ts new file mode 100644 index 000000000000..1c497a79600c --- /dev/null +++ b/src/libs/Navigation/dismissRHP.ts @@ -0,0 +1,25 @@ +import type {NavigationContainerRef} from '@react-navigation/native'; +import {StackActions} from '@react-navigation/native'; +import NAVIGATORS from '@src/NAVIGATORS'; +import type {RootStackParamList} from './types'; + +// This function is in a separate file than Navigation.ts to avoid cyclic dependency. + +/** + * Dismisses the RHP modal stack if there is any + * + * @param targetReportID - The reportID to navigate to after dismissing the modal + */ +function dismissRHP(navigationRef: NavigationContainerRef) { + if (!navigationRef.isReady()) { + return; + } + + const state = navigationRef.getState(); + const lastRoute = state.routes.at(-1); + if (lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) { + navigationRef.dispatch({...StackActions.pop(), target: state.key}); + } +} + +export default dismissRHP; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 1c861d510a85..bea849954631 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -305,6 +305,20 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc PolicyUtils.goBackFromInvalidPolicy(); }, [policy, prevPolicy]); + // We are checking if the user can access the route. + // If user can't access the route, we are dismissing any modals that are open when the NotFound view is shown + const canAccessRoute = activeRoute && menuItems.some((item) => item.routeName === activeRoute); + + useEffect(() => { + if (!shouldShowNotFoundPage && canAccessRoute) { + return; + } + // We are dismissing any modals that are open when the NotFound view is shown + Navigation.isNavigationReady().then(() => { + Navigation.dismissRHP(); + }); + }, [canAccessRoute, policy, shouldShowNotFoundPage]); + const policyAvatar = useMemo(() => { if (!policy) { return {source: Expensicons.ExpensifyAppIcon, name: CONST.WORKSPACE_SWITCHER.NAME, type: CONST.ICON_TYPE_AVATAR}; diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index 2eaa38b865e6..a5c39cd92fe5 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -97,6 +97,9 @@ function WorkspaceInviteMessagePage({ setWelcomeNote(parser.htmlToMarkdown(getDefaultWelcomeNote())); return; } + if (isEmptyObject(policy)) { + return; + } Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID), true); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 0d723961a29e..ff47af2a0dde 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -7,16 +7,13 @@ import {InteractionManager, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; -import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import Button from '@components/Button'; import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu'; import type {DropdownOption, WorkspaceMemberBulkActionType} from '@components/ButtonWithDropdownMenu/types'; import ConfirmModal from '@components/ConfirmModal'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; import MessagesRow from '@components/MessagesRow'; -import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import TableListItem from '@components/SelectionList/TableListItem'; import type {ListItem, SelectionListHandle} from '@components/SelectionList/types'; @@ -47,6 +44,7 @@ import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; +import WorkspacePageWithSections from './WorkspacePageWithSections'; type WorkspaceMembersPageOnyxProps = { /** Session info for the currently logged in user. */ @@ -59,7 +57,6 @@ type WorkspaceMembersPageProps = WithPolicyAndFullscreenLoadingProps & WithCurrentUserPersonalDetailsProps & WorkspaceMembersPageOnyxProps & StackScreenProps; - /** * Inverts an object, equivalent of _.invert */ @@ -71,7 +68,7 @@ function invertObject(object: Record): Record { type MemberOption = Omit & {accountID: number}; -function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft, route, policy, session, currentUserPersonalDetails, isLoadingReportData = true}: WorkspaceMembersPageProps) { +function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft, route, policy, session, currentUserPersonalDetails}: WorkspaceMembersPageProps) { const policyMemberEmailsToAccountIDs = useMemo(() => PolicyUtils.getMemberAccountIDsForWorkspace(policy?.employeeList), [policy?.employeeList]); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -524,71 +521,63 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft, }; return ( - - - { - Navigation.goBack(); - }} - shouldShowBackButton={isSmallScreenWidth} - guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_MEMBERS} - > - {!isSmallScreenWidth && getHeaderButtons()} - - {isSmallScreenWidth && {getHeaderButtons()}} - setRemoveMembersConfirmModalVisible(false)} - prompt={translate('workspace.people.removeMembersPrompt')} - confirmText={translate('common.remove')} - cancelText={translate('common.cancel')} - onModalHide={() => { - InteractionManager.runAfterInteractions(() => { - if (!textInputRef.current) { - return; - } - textInputRef.current.focus(); - }); - }} - /> - - toggleUser(item.accountID)} - onSelectAll={() => toggleAllUsers(data)} - onDismissError={dismissError} - showLoadingPlaceholder={isLoading} - showScrollIndicator - shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} - textInputRef={textInputRef} - customListHeader={getCustomListHeader()} - listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]} + {() => ( + <> + {isSmallScreenWidth && {getHeaderButtons()}} + setRemoveMembersConfirmModalVisible(false)} + prompt={translate('workspace.people.removeMembersPrompt')} + confirmText={translate('common.remove')} + cancelText={translate('common.cancel')} + onModalHide={() => { + InteractionManager.runAfterInteractions(() => { + if (!textInputRef.current) { + return; + } + textInputRef.current.focus(); + }); + }} /> - - - + + + toggleUser(item.accountID)} + onSelectAll={() => toggleAllUsers(data)} + onDismissError={dismissError} + showLoadingPlaceholder={isLoading} + showScrollIndicator + shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} + textInputRef={textInputRef} + customListHeader={getCustomListHeader()} + listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]} + /> + + + )} + ); } diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 58288f213818..b1ecc8124488 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -82,6 +82,12 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & * */ icon?: IconAsset; + /** Content to be added to the header */ + headerContent?: ReactNode; + + /** TestID of the component */ + testID?: string; + /** Whether the page is loading, example any other API call in progres */ isLoading?: boolean; }; @@ -112,6 +118,8 @@ function WorkspacePageWithSections({ shouldShowLoading = true, shouldShowOfflineIndicatorInWideScreen = false, shouldShowNonAdmin = false, + headerContent, + testID, shouldShowNotFoundPage = false, isLoading: isPageLoading = false, }: WorkspacePageWithSectionsProps) { @@ -160,7 +168,7 @@ function WorkspacePageWithSections({ includeSafeAreaPaddingBottom={false} shouldEnablePickerAvoiding={false} shouldEnableMaxHeight - testID={WorkspacePageWithSections.displayName} + testID={testID ?? WorkspacePageWithSections.displayName} shouldShowOfflineIndicatorInWideScreen={shouldShowOfflineIndicatorInWideScreen && !shouldShow} > Navigation.goBack(backButtonRoute)} icon={icon ?? undefined} style={styles.headerBarDesktopHeight} - /> + > + {headerContent} + {(isLoading || firstRender.current) && shouldShowLoading && isFocused ? ( ) : ( From a535acb4bf0bc29346097e1ea784a0846cb4337f Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 6 May 2024 10:32:37 +0200 Subject: [PATCH 02/16] fix #40509 --- src/pages/workspace/WorkspaceInitialPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index bea849954631..a97b66cf9bc6 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -317,7 +317,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc Navigation.isNavigationReady().then(() => { Navigation.dismissRHP(); }); - }, [canAccessRoute, policy, shouldShowNotFoundPage]); + }, [canAccessRoute, shouldShowNotFoundPage]); const policyAvatar = useMemo(() => { if (!policy) { From adf1ca458ad1a368a84b9f7a4ba2ffcb9c0e3089 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 6 May 2024 14:09:12 +0200 Subject: [PATCH 03/16] fix one more issue on android --- .../Navigation/linkingConfig/getAdaptedStateFromPath.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index d89c6c5a1751..67fb816eb272 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -6,6 +6,7 @@ import getTopmostNestedRHPRoute from '@libs/Navigation/getTopmostNestedRHPRoute' import type {BottomTabName, CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils'; import NAVIGATORS from '@src/NAVIGATORS'; +import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config from './config'; @@ -14,7 +15,7 @@ import getMatchingBottomTabRouteForState from './getMatchingBottomTabRouteForSta import getMatchingCentralPaneRouteForState from './getMatchingCentralPaneRouteForState'; import replacePathInNestedState from './replacePathInNestedState'; -const RHP_SCREENS_OPENED_FROM_LHN = [SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS] as const; +const RHP_SCREENS_OPENED_FROM_LHN: Screen[] = [SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE]; type RHPScreenOpenedFromLHN = (typeof RHP_SCREENS_OPENED_FROM_LHN)[number]; @@ -166,11 +167,6 @@ function getAdaptedState(state: PartialState const featureTrainingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.FEATURE_TRANING_MODAL_NAVIGATOR); const reportAttachmentsScreen = state.routes.find((route) => route.name === SCREENS.REPORT_ATTACHMENTS); - if (isNarrowLayout) { - metainfo.isFullScreenNavigatorMandatory = false; - metainfo.isCentralPaneAndBottomTabMandatory = false; - } - if (rhpNavigator) { // Routes // - matching bottom tab From b513239d07e6eed0d65e7be55d8686bbde0bbdf1 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 8 May 2024 11:37:04 +0200 Subject: [PATCH 04/16] fix comment --- src/libs/Navigation/dismissRHP.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/Navigation/dismissRHP.ts b/src/libs/Navigation/dismissRHP.ts index 1c497a79600c..4b4260b22f3f 100644 --- a/src/libs/Navigation/dismissRHP.ts +++ b/src/libs/Navigation/dismissRHP.ts @@ -7,8 +7,6 @@ import type {RootStackParamList} from './types'; /** * Dismisses the RHP modal stack if there is any - * - * @param targetReportID - The reportID to navigate to after dismissing the modal */ function dismissRHP(navigationRef: NavigationContainerRef) { if (!navigationRef.isReady()) { From ce12e86a19f7122f51f46fc71c58787efb8f63c6 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 8 May 2024 11:43:45 +0200 Subject: [PATCH 05/16] change type --- src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 67fb816eb272..f82ce95a7dea 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -15,7 +15,7 @@ import getMatchingBottomTabRouteForState from './getMatchingBottomTabRouteForSta import getMatchingCentralPaneRouteForState from './getMatchingCentralPaneRouteForState'; import replacePathInNestedState from './replacePathInNestedState'; -const RHP_SCREENS_OPENED_FROM_LHN: Screen[] = [SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE]; +const RHP_SCREENS_OPENED_FROM_LHN = [SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.PROFILE.STATUS, SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE] satisfies Screen[]; type RHPScreenOpenedFromLHN = (typeof RHP_SCREENS_OPENED_FROM_LHN)[number]; From 92015a60a28d3fb507245b1296c6cd1bcaa9d1a7 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 14 Jun 2024 10:44:19 +0200 Subject: [PATCH 06/16] fix: empty ProfilePage --- src/pages/workspace/WorkspaceProfilePage.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/WorkspaceProfilePage.tsx b/src/pages/workspace/WorkspaceProfilePage.tsx index ea7616fb28f4..cdf975e3d2c0 100644 --- a/src/pages/workspace/WorkspaceProfilePage.tsx +++ b/src/pages/workspace/WorkspaceProfilePage.tsx @@ -116,22 +116,19 @@ function WorkspaceProfilePage({policy, currencyList = {}, route}: WorkSpaceProfi } }, [policy?.id, policyName, activeWorkspaceID, setActiveWorkspaceID]); - // When we create a new workspaces, the policy prop will not be set on the first render. Therefore, we have to delay rendering until it has been set in Onyx. - if (policy === undefined) { - return null; - } - return ( {(hasVBA?: boolean) => ( From 001a36b75a42b3ff9282be0900395f50f91a97e8 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:28:30 +0200 Subject: [PATCH 07/16] fix: add concurrent mode support --- src/libs/Navigation/Navigation.ts | 7 ------ src/libs/Navigation/dismissRHP.ts | 23 -------------------- src/pages/workspace/WorkspaceInitialPage.tsx | 10 +++++++-- 3 files changed, 8 insertions(+), 32 deletions(-) delete mode 100644 src/libs/Navigation/dismissRHP.ts diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 34831c5781cf..5a7182405681 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -16,7 +16,6 @@ import type {Report} from '@src/types/onyx'; import originalCloseRHPFlow from './closeRHPFlow'; import originalDismissModal from './dismissModal'; import originalDismissModalWithReport from './dismissModalWithReport'; -import originalDismissRHP from './dismissRHP'; import getTopmostCentralPaneRoute from './getTopmostCentralPaneRoute'; import originalGetTopmostReportActionId from './getTopmostReportActionID'; import originalGetTopmostReportId from './getTopmostReportId'; @@ -76,11 +75,6 @@ const dismissModal = (reportID?: string, ref = navigationRef) => { // Re-exporting the closeRHPFlow here to fill in default value for navigationRef. The closeRHPFlow isn't defined in this file to avoid cyclic dependencies. const closeRHPFlow = (ref = navigationRef) => originalCloseRHPFlow(ref); -// Re-exporting the dismissRHP here to fill in default value for navigationRef. The dismissRHP isn't defined in this file to avoid cyclic dependencies. -const dismissRHP = (ref = navigationRef) => { - originalDismissRHP(ref); -}; - // Re-exporting the dismissModalWithReport here to fill in default value for navigationRef. The dismissModalWithReport isn't defined in this file to avoid cyclic dependencies. // This method is needed because it allows to dismiss the modal and then open the report. Within this method is checked whether the report belongs to a specific workspace. Sometimes the report we want to check, hasn't been added to the Onyx yet. // Then we can pass the report as a param without getting it from the Onyx. @@ -380,7 +374,6 @@ export default { setShouldPopAllStateOnUP, navigate, setParams, - dismissRHP, dismissModal, dismissModalWithReport, isActiveRoute, diff --git a/src/libs/Navigation/dismissRHP.ts b/src/libs/Navigation/dismissRHP.ts deleted file mode 100644 index 4b4260b22f3f..000000000000 --- a/src/libs/Navigation/dismissRHP.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type {NavigationContainerRef} from '@react-navigation/native'; -import {StackActions} from '@react-navigation/native'; -import NAVIGATORS from '@src/NAVIGATORS'; -import type {RootStackParamList} from './types'; - -// This function is in a separate file than Navigation.ts to avoid cyclic dependency. - -/** - * Dismisses the RHP modal stack if there is any - */ -function dismissRHP(navigationRef: NavigationContainerRef) { - if (!navigationRef.isReady()) { - return; - } - - const state = navigationRef.getState(); - const lastRoute = state.routes.at(-1); - if (lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) { - navigationRef.dispatch({...StackActions.pop(), target: state.key}); - } -} - -export default dismissRHP; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 41751b3f2289..c729a17df10e 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -1,6 +1,6 @@ import {useFocusEffect, useNavigationState} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; @@ -28,6 +28,7 @@ import type {FullScreenNavigatorParamList} from '@navigation/types'; import * as App from '@userActions/App'; import * as Policy from '@userActions/Policy/Policy'; import * as ReimbursementAccount from '@userActions/ReimbursementAccount'; +import CONFIG from '@src/CONFIG'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -96,6 +97,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const activeRoute = useNavigationState(getTopmostRouteName); const {translate} = useLocalize(); const {isOffline} = useNetwork(); + const wasRendered = useRef(false); const prevPendingFields = usePrevious(policy?.pendingFields); const policyFeatureStates = useMemo( @@ -341,9 +343,13 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc if (!shouldShowNotFoundPage && canAccessRoute) { return; } + if (CONFIG.USE_REACT_STRICT_MODE && wasRendered.current) { + return; + } + wasRendered.current = true; // We are dismissing any modals that are open when the NotFound view is shown Navigation.isNavigationReady().then(() => { - Navigation.dismissRHP(); + Navigation.closeRHPFlow(); }); }, [canAccessRoute, shouldShowNotFoundPage]); From e76dd16847026cdcb1d4bc9f17f87a416ac63387 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:17:16 +0200 Subject: [PATCH 08/16] fix: double navigation --- src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 107b39fdb612..aeff43f902ff 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -160,6 +160,11 @@ function getAdaptedState(state: PartialState const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS); const featureTrainingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.FEATURE_TRANING_MODAL_NAVIGATOR); + if (isNarrowLayout) { + metainfo.isFullScreenNavigatorMandatory = false; + metainfo.isCentralPaneAndBottomTabMandatory = false; + } + if (rhpNavigator) { // Routes // - matching bottom tab From 6cca6dfb0427a650428a9e5d97ebe824ede8ec36 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:16:18 +0200 Subject: [PATCH 09/16] fix: double navigation when selecting workspace in settings --- src/libs/Navigation/linkTo/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkTo/index.ts b/src/libs/Navigation/linkTo/index.ts index 3c4608d6b5de..6bac621e2936 100644 --- a/src/libs/Navigation/linkTo/index.ts +++ b/src/libs/Navigation/linkTo/index.ts @@ -139,7 +139,7 @@ export default function linkTo(navigation: NavigationContainerRef Date: Tue, 2 Jul 2024 15:21:34 +0200 Subject: [PATCH 10/16] continue previous commit --- src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index aeff43f902ff..107b39fdb612 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -160,11 +160,6 @@ function getAdaptedState(state: PartialState const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS); const featureTrainingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.FEATURE_TRANING_MODAL_NAVIGATOR); - if (isNarrowLayout) { - metainfo.isFullScreenNavigatorMandatory = false; - metainfo.isCentralPaneAndBottomTabMandatory = false; - } - if (rhpNavigator) { // Routes // - matching bottom tab From 9ec03336ac2db25dabc9f9e059e551f5af422b8c Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:54:43 +0200 Subject: [PATCH 11/16] refactor: WorkspaceMoreFeaturesPage and WorkspaceReportFieldsPage --- src/CONST.ts | 1 + .../workspace/WorkspaceMoreFeaturesPage.tsx | 22 +++++--------- .../WorkspaceReportFieldsPage.tsx | 29 +++++++------------ src/pages/workspace/withPolicy.tsx | 1 + 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index d5502841c7d1..de46e864a9b5 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2061,6 +2061,7 @@ const CONST = { WORKSPACE_WORKFLOWS: 'WorkspaceWorkflows', WORKSPACE_BANK_ACCOUNT: 'WorkspaceBankAccount', WORKSPACE_SETTINGS: 'WorkspaceSettings', + WORKSPACE_FEATURES: 'WorkspaceFeatures', }, get EXPENSIFY_EMAILS() { return [ diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index 1499f3a0c0b3..bfe13c1bd634 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -3,10 +3,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useState} from 'react'; import {View} from 'react-native'; import ConfirmModal from '@components/ConfirmModal'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; -import ScreenWrapper from '@components/ScreenWrapper'; -import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -31,6 +28,7 @@ import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import ToggleSettingOptionRow from './workflows/ToggleSettingsOptionRow'; +import WorkspacePageWithSections from './WorkspacePageWithSections'; type WorkspaceMoreFeaturesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps; @@ -257,19 +255,15 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} policyID={route.params.policyID} > - - - - {sections.map(renderSection)} + {sections.map(renderSection)} - + ); } diff --git a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx index 346038238561..6031eebbe3c4 100644 --- a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx +++ b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx @@ -5,10 +5,8 @@ import React, {useEffect, useMemo, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; -import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import ListItemRightCaretWithLabel from '@components/SelectionList/ListItemRightCaretWithLabel'; import TableListItem from '@components/SelectionList/TableListItem'; @@ -23,6 +21,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import type {FullScreenNavigatorParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; @@ -32,11 +31,8 @@ type ReportFieldForList = ListItem & {value: string; fieldID: string}; type WorkspaceReportFieldsPageProps = StackScreenProps; -function WorkspaceReportFieldsPage({ - route: { - params: {policyID}, - }, -}: WorkspaceReportFieldsPageProps) { +function WorkspaceReportFieldsPage({route}: WorkspaceReportFieldsPageProps) { + const policyID = route.params.policyID; const {isSmallScreenWidth} = useWindowDimensions(); const styles = useThemeStyles(); const theme = useTheme(); @@ -116,20 +112,15 @@ function WorkspaceReportFieldsPage({ accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} featureName={CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED} > - - - {!isSmallScreenWidth && getHeaderButtons()} - {isSmallScreenWidth && {getHeaderButtons()}} {(!isSmallScreenWidth || reportFieldsList.length === 0 || isLoading) && getHeaderText()} {isLoading && ( @@ -161,7 +152,7 @@ function WorkspaceReportFieldsPage({ showScrollIndicator={false} /> )} - + ); } diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 6305509e9589..7db5e25d3154 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -36,6 +36,7 @@ type PolicyRoute = RouteProp< | typeof SCREENS.WORKSPACE.ADDRESS | typeof SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT | typeof SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT + | typeof SCREENS.WORKSPACE.REPORT_FIELDS >; function getPolicyIDFromRoute(route: PolicyRoute): string { From ad96e9efa8b76a44fe3e88041dab1f575ca61f0c Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 3 Jul 2024 08:42:37 +0200 Subject: [PATCH 12/16] fix --- src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index bfe13c1bd634..829dd37cb5f0 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -4,6 +4,7 @@ import React, {useCallback, useState} from 'react'; import {View} from 'react-native'; import ConfirmModal from '@components/ConfirmModal'; import * as Illustrations from '@components/Icon/Illustrations'; +import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -263,7 +264,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro testID={WorkspaceMoreFeaturesPage.displayName} shouldShowOfflineIndicatorInWideScreen > - {sections.map(renderSection)} + {sections.map(renderSection)} Date: Wed, 3 Jul 2024 09:44:18 +0200 Subject: [PATCH 13/16] modify AccessOrNotFoundWrapper --- .../workspace/AccessOrNotFoundWrapper.tsx | 4 +-- .../workspace/WorkspaceMoreFeaturesPage.tsx | 19 +++++++----- .../WorkspaceReportFieldsPage.tsx | 29 ++++++++++++------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 02e5ab13fd86..02ddd6b24f95 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -88,7 +88,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN return shouldShowFullScreenFallback ? ( Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} + onBackButtonPress={() => Navigation.dismissModal()} shouldForceFullScreen // eslint-disable-next-line react/jsx-props-no-spreading {...fullPageNotFoundViewProps} @@ -139,7 +139,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps return ( ); diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index 2659d9841a0f..84bdab0af82b 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -4,7 +4,9 @@ import React, {useCallback, useState} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; +import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import useLocalize from '@hooks/useLocalize'; @@ -32,7 +34,6 @@ import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import ToggleSettingOptionRow from './workflows/ToggleSettingsOptionRow'; -import WorkspacePageWithSections from './WorkspacePageWithSections'; type WorkspaceMoreFeaturesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps; @@ -312,14 +313,18 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} policyID={route.params.policyID} > - + + {sections.map(renderSection)} - + ); } diff --git a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx index 6031eebbe3c4..346038238561 100644 --- a/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx +++ b/src/pages/workspace/reportFields/WorkspaceReportFieldsPage.tsx @@ -5,8 +5,10 @@ import React, {useEffect, useMemo, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; +import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import ListItemRightCaretWithLabel from '@components/SelectionList/ListItemRightCaretWithLabel'; import TableListItem from '@components/SelectionList/TableListItem'; @@ -21,7 +23,6 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import type {FullScreenNavigatorParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; -import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; @@ -31,8 +32,11 @@ type ReportFieldForList = ListItem & {value: string; fieldID: string}; type WorkspaceReportFieldsPageProps = StackScreenProps; -function WorkspaceReportFieldsPage({route}: WorkspaceReportFieldsPageProps) { - const policyID = route.params.policyID; +function WorkspaceReportFieldsPage({ + route: { + params: {policyID}, + }, +}: WorkspaceReportFieldsPageProps) { const {isSmallScreenWidth} = useWindowDimensions(); const styles = useThemeStyles(); const theme = useTheme(); @@ -112,15 +116,20 @@ function WorkspaceReportFieldsPage({route}: WorkspaceReportFieldsPageProps) { accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} featureName={CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED} > - + + {!isSmallScreenWidth && getHeaderButtons()} + {isSmallScreenWidth && {getHeaderButtons()}} {(!isSmallScreenWidth || reportFieldsList.length === 0 || isLoading) && getHeaderText()} {isLoading && ( @@ -152,7 +161,7 @@ function WorkspaceReportFieldsPage({route}: WorkspaceReportFieldsPageProps) { showScrollIndicator={false} /> )} - + ); } From 4c50c13f45a8072ca37d2b5d3bd4798cd8697f7b Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 3 Jul 2024 09:58:54 +0200 Subject: [PATCH 14/16] small fix --- src/pages/workspace/withPolicy.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 2e0701c5fbec..6300d3fcf280 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -36,7 +36,6 @@ type PolicyRoute = RouteProp< | typeof SCREENS.WORKSPACE.ADDRESS | typeof SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT | typeof SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT - | typeof SCREENS.WORKSPACE.REPORT_FIELDS >; function getPolicyIDFromRoute(route: PolicyRoute): string { From 2a00bb97dae01dc2f97d753239179aa8f6e053d9 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Tue, 16 Jul 2024 23:34:26 +0200 Subject: [PATCH 15/16] remove flag --- src/pages/workspace/WorkspaceInitialPage.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 952a84b445fb..ca8364b81ec2 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -28,7 +28,6 @@ import type {FullScreenNavigatorParamList} from '@navigation/types'; import * as App from '@userActions/App'; import * as Policy from '@userActions/Policy/Policy'; import * as ReimbursementAccount from '@userActions/ReimbursementAccount'; -import CONFIG from '@src/CONFIG'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -357,7 +356,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc if (!shouldShowNotFoundPage && canAccessRoute) { return; } - if (CONFIG.USE_REACT_STRICT_MODE && wasRendered.current) { + if (wasRendered.current) { return; } wasRendered.current = true; From e60668b985536a86473d2cf37d471d726beb0717 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 17 Jul 2024 08:02:53 +0200 Subject: [PATCH 16/16] prettier --- src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 3cdb12ce405d..16dc9ef1c016 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -9,8 +9,8 @@ import {extractPolicyIDFromPath, getPathWithoutPolicyID} from '@libs/PolicyUtils import * as ReportConnection from '@libs/ReportConnection'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; -import type {Screen} from '@src/SCREENS'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; import CENTRAL_PANE_TO_RHP_MAPPING from './CENTRAL_PANE_TO_RHP_MAPPING'; import config from './config';