diff --git a/src/CONST.ts b/src/CONST.ts index a9ef91c4c71f..3affd7c01559 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3064,6 +3064,11 @@ const CONST = { EMAIL: 'EMAIL', REPORT: 'REPORT', }, + + WORKSPACE_SWITCHER: { + NAME: 'Expensify', + SUBSCRIPT_ICON_SIZE: 8, + }, } as const; export default CONST; diff --git a/src/components/HeaderPageLayout.js b/src/components/HeaderPageLayout.js index 9ef5d4f83a06..88ce5a00cc86 100644 --- a/src/components/HeaderPageLayout.js +++ b/src/components/HeaderPageLayout.js @@ -39,6 +39,8 @@ const propTypes = { /** Style to apply to the children container */ // eslint-disable-next-line react/forbid-prop-types childrenContainerStyles: PropTypes.arrayOf(PropTypes.object), + + shouldShowOfflineIndicator: PropTypes.bool, }; const defaultProps = { @@ -48,9 +50,21 @@ const defaultProps = { scrollViewContainerStyles: [], childrenContainerStyles: [], footer: null, + shouldShowOfflineIndicator: false, }; -function HeaderPageLayout({backgroundColor, children, footer, headerContainerStyles, scrollViewContainerStyles, childrenContainerStyles, style, headerContent, ...propsToPassToHeader}) { +function HeaderPageLayout({ + backgroundColor, + children, + footer, + headerContainerStyles, + scrollViewContainerStyles, + childrenContainerStyles, + style, + headerContent, + shouldShowOfflineIndicator, + ...propsToPassToHeader +}) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -72,6 +86,7 @@ function HeaderPageLayout({backgroundColor, children, footer, headerContainerSty includeSafeAreaPaddingBottom={false} offlineIndicatorStyle={[appBGColor]} testID={HeaderPageLayout.displayName} + shouldShowOfflineIndicator={shouldShowOfflineIndicator} > {({safeAreaPaddingBottomStyle}) => ( <> diff --git a/src/components/IllustratedHeaderPageLayout.js b/src/components/IllustratedHeaderPageLayout.js index fd571f2968df..65a037213b49 100644 --- a/src/components/IllustratedHeaderPageLayout.js +++ b/src/components/IllustratedHeaderPageLayout.js @@ -23,29 +23,33 @@ const propTypes = { /** Overlay content to display on top of animation */ overlayContent: PropTypes.func, + + shouldShowOfflineIndicator: PropTypes.bool, }; const defaultProps = { backgroundColor: undefined, footer: null, overlayContent: null, + shouldShowOfflineIndicator: false, }; -function IllustratedHeaderPageLayout({backgroundColor, children, illustration, footer, overlayContent, ...propsToPassToHeader}) { +function IllustratedHeaderPageLayout({backgroundColor, children, illustration, footer, overlayContent, shouldShowOfflineIndicator, ...propsToPassToHeader}) { const theme = useTheme(); const styles = useThemeStyles(); - const shouldUseMaxHeight = !propsToPassToHeader.shouldShowBackButton; + const shouldLimitHeight = !propsToPassToHeader.shouldShowBackButton; return ( @@ -53,7 +57,7 @@ function IllustratedHeaderPageLayout({backgroundColor, children, illustration, f } // TODO: move to variables - headerContainerStyles={[styles.justifyContentCenter, styles.w100, shouldUseMaxHeight && styles.centralPaneAnimation]} + headerContainerStyles={[styles.justifyContentCenter, styles.w100, shouldLimitHeight && styles.centralPaneAnimation]} footer={footer} // eslint-disable-next-line react/jsx-props-no-spreading {...propsToPassToHeader} diff --git a/src/components/ReimbursementAccountLoadingIndicator.js b/src/components/ReimbursementAccountLoadingIndicator.js index bc0e70e64419..5dbace45966f 100644 --- a/src/components/ReimbursementAccountLoadingIndicator.js +++ b/src/components/ReimbursementAccountLoadingIndicator.js @@ -24,7 +24,7 @@ function ReimbursementAccountLoadingIndicator(props) { const {translate} = useLocalize(); return ( diff --git a/src/components/ScreenWrapper.tsx b/src/components/ScreenWrapper.tsx index 0653e2ff8577..5c96b4ad6168 100644 --- a/src/components/ScreenWrapper.tsx +++ b/src/components/ScreenWrapper.tsx @@ -77,7 +77,7 @@ type ScreenWrapperProps = { shouldEnableMinHeight?: boolean; /** Whether to show offline indicator */ - shouldShowOfflineIndicator?: boolean; + shouldShowOfflineIndicatorSmallWidth?: boolean; /** * The navigation prop is passed by the navigator. It is used to trigger the onEntryTransitionEnd callback @@ -86,6 +86,9 @@ type ScreenWrapperProps = { * This is required because transitionEnd event doesn't trigger in the testing environment. */ navigation?: StackNavigationProp; + + /** Is central pane */ + shouldShowOfflineIndicator?: boolean; }; function ScreenWrapper( @@ -99,13 +102,14 @@ function ScreenWrapper( shouldEnablePickerAvoiding = true, headerGapStyles, children, - shouldShowOfflineIndicator = true, + shouldShowOfflineIndicatorSmallWidth = true, offlineIndicatorStyle, style, shouldDismissKeyboardBeforeClose = true, onEntryTransitionEnd, testID, navigation: navigationProp, + shouldShowOfflineIndicator = false, }: ScreenWrapperProps, ref: ForwardedRef, ) { @@ -198,7 +202,7 @@ function ScreenWrapper( } // We always need the safe area padding bottom if we're showing the offline indicator since it is bottom-docked. - if (includeSafeAreaPaddingBottom || (isOffline && shouldShowOfflineIndicator)) { + if (includeSafeAreaPaddingBottom || (isOffline && shouldShowOfflineIndicatorSmallWidth)) { paddingStyle.paddingBottom = paddingBottom; } @@ -237,7 +241,13 @@ function ScreenWrapper( }) : children } - {isSmallScreenWidth && shouldShowOfflineIndicator && } + {isSmallScreenWidth && shouldShowOfflineIndicatorSmallWidth && } + {!isSmallScreenWidth && shouldShowOfflineIndicator && ( + + )} diff --git a/src/components/Section/index.js b/src/components/Section/index.js index 412ccdfd6542..3e3d792d12be 100644 --- a/src/components/Section/index.js +++ b/src/components/Section/index.js @@ -78,11 +78,11 @@ const defaultProps = { function Section({children, childrenStyles, containerStyles, icon, IconComponent, cardLayout, iconContainerStyles, menuItems, subtitle, subtitleStyles, subtitleMuted, title, titleStyles}) { const styles = useThemeStyles(); - const {isMobileScreenWidth} = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); return ( <> - + {cardLayout === CARD_LAYOUT.ICON_ON_TOP && ( {}} > diff --git a/src/hooks/useWindowDimensions/index.native.ts b/src/hooks/useWindowDimensions/index.native.ts index 3bb361ec5dc3..5d556234aeb9 100644 --- a/src/hooks/useWindowDimensions/index.native.ts +++ b/src/hooks/useWindowDimensions/index.native.ts @@ -12,7 +12,6 @@ export default function (): WindowDimensions { const isSmallScreenWidth = true; const isMediumScreenWidth = false; const isLargeScreenWidth = false; - const isMobileScreenWidth = true; return { windowWidth, @@ -21,6 +20,5 @@ export default function (): WindowDimensions { isSmallScreenWidth, isMediumScreenWidth, isLargeScreenWidth, - isMobileScreenWidth, }; } diff --git a/src/hooks/useWindowDimensions/index.ts b/src/hooks/useWindowDimensions/index.ts index e4c261e59f18..b0a29e9f901b 100644 --- a/src/hooks/useWindowDimensions/index.ts +++ b/src/hooks/useWindowDimensions/index.ts @@ -14,7 +14,6 @@ export default function (): WindowDimensions { const isSmallScreenWidth = windowWidth <= variables.mobileResponsiveWidthBreakpoint; const isMediumScreenWidth = windowWidth > variables.mobileResponsiveWidthBreakpoint && windowWidth <= variables.tabletResponsiveWidthBreakpoint; const isLargeScreenWidth = windowWidth > variables.tabletResponsiveWidthBreakpoint; - const isMobileScreenWidth = isExtraSmallScreenHeight || isSmallScreenWidth; return { windowWidth, @@ -23,6 +22,5 @@ export default function (): WindowDimensions { isSmallScreenWidth, isMediumScreenWidth, isLargeScreenWidth, - isMobileScreenWidth, }; } diff --git a/src/hooks/useWindowDimensions/types.ts b/src/hooks/useWindowDimensions/types.ts index 7411c845c70a..9b59d4968935 100644 --- a/src/hooks/useWindowDimensions/types.ts +++ b/src/hooks/useWindowDimensions/types.ts @@ -5,7 +5,6 @@ type WindowDimensions = { isSmallScreenWidth: boolean; isMediumScreenWidth: boolean; isLargeScreenWidth: boolean; - isMobileScreenWidth: boolean; }; export default WindowDimensions; diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx index 6e89568347db..c71178f2969d 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx @@ -25,9 +25,7 @@ function BottomTabBar() { // Parent navigator of the bottom tab bar is the root navigator. const currentTabName = useNavigationState((state) => { const topmostBottomTabRoute = getTopmostBottomTabRoute(state); - if (topmostBottomTabRoute) { - return topmostBottomTabRoute.name; - } + return topmostBottomTabRoute?.name; }); return ( diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx similarity index 57% rename from src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js rename to src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx index acffb59f0fb5..43e466bdbec0 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx @@ -1,20 +1,19 @@ -import PropTypes from 'prop-types'; import React, {useCallback} from 'react'; import {View} from 'react-native'; -import * as Expensicons from '@components/Icon/Expensicons'; -import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Search from '@components/Search'; -import SubscriptAvatar from '@components/SubscriptAvatar'; +import WorkspaceSwitcherButton from '@components/WorkspaceSwitcherButton'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import SignInOrAvatarWithOptionalStatus from '@pages/home/sidebar/SignInOrAvatarWithOptionalStatus'; import * as Session from '@userActions/Session'; -import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; -// TODO-IDEAL: isCreateMenuOpen wasn't used before -function TopBar({isCreateMenuOpen = false}) { +type Props = { + isCreateMenuOpen?: boolean; +}; + +function TopBar({isCreateMenuOpen = false}: Props) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -32,30 +31,20 @@ function TopBar({isCreateMenuOpen = false}) { style={[styles.gap4, styles.flexRow, styles.ph5, styles.pv5, styles.justifyContentBetween, styles.alignItemsCenter]} dataSet={{dragArea: true}} > - - - + - + ); } TopBar.displayName = 'TopBar'; -TopBar.propTypes = { - isCreateMenuOpen: PropTypes.bool, -}; -TopBar.defaultProps = { - isCreateMenuOpen: false, -}; export default TopBar; diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx index af7e9c64d952..dd6f112928a7 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import ScreenWrapper from '@components/ScreenWrapper'; +import useThemeStyles from '@hooks/useThemeStyles'; import type {NavigationStateRoute} from '@libs/Navigation/types'; import SCREENS from '@src/SCREENS'; import BottomTabBar from './BottomTabBar'; @@ -58,11 +59,15 @@ function CustomBottomTabNavigator({initialRouteName, children, screenOptions, .. initialRouteName, }); + const styles = useThemeStyles(); const stateToRender = getStateToRender(state); return ( - - + + ; @@ -29,7 +29,7 @@ const addCentralPaneNavigatorRoute = (state: State) => { (state.index as number) = state.routes.length - 1; }; -function CustomFullScreenRouter(options: ResponsiveStackNavigatorRouterOptions) { +function CustomFullScreenRouter(options: FullScreenNavigatorRouterOptions) { const stackRouter = StackRouter(options); return { @@ -44,7 +44,6 @@ function CustomFullScreenRouter(options: ResponsiveStackNavigatorRouterOptions) }, getRehydratedState(partialState: StackNavigationState, {routeNames, routeParamList, routeGetIdList}: RouterConfigOptions): StackNavigationState { const isSmallScreenWidth = getIsSmallScreenWidth(); - // Make sure that there is at least one CentralPaneNavigator (ReportScreen by default) in the state if this is a wide layout if (!isAtLeastOneInState(partialState, SCREENS.SETTINGS_CENTRAL_PANE) && !isSmallScreenWidth) { // If we added a route we need to make sure that the state.stale is true to generate new key for this route diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx index db3ad138618f..808f06c61278 100644 --- a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx @@ -2,21 +2,13 @@ import type {ParamListBase, StackActionHelpers, StackNavigationState} from '@rea import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native'; import type {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; import {StackView} from '@react-navigation/stack'; -import React, {useRef} from 'react'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import CustomFullScreenRouter from './CustomFullScreenRouter'; -import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; - -function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { - const {isSmallScreenWidth} = useWindowDimensions(); - - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); - - isSmallScreenWidthRef.current = isSmallScreenWidth; +import type {FullScreenNavigatorProps, FullScreenNavigatorRouterOptions} from './types'; +function FullScreenNavigator(props: FullScreenNavigatorProps) { const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< StackNavigationState, - ResponsiveStackNavigatorRouterOptions, + FullScreenNavigatorRouterOptions, StackActionHelpers, StackNavigationOptions, StackNavigationEventMap @@ -39,6 +31,6 @@ function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { ); } -ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; +FullScreenNavigator.displayName = 'FullScreenNavigator'; -export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof FullScreenNavigator>(FullScreenNavigator); diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx index 0099d4ea1631..228fe7010de4 100644 --- a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx @@ -2,13 +2,12 @@ import type {ParamListBase, StackActionHelpers, StackNavigationState} from '@rea import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native'; import type {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; import {StackView} from '@react-navigation/stack'; -import React, {useMemo, useRef} from 'react'; -import useWindowDimensions from '@hooks/useWindowDimensions'; +import React, {useMemo} from 'react'; import SCREENS from '@src/SCREENS'; import CustomFullScreenRouter from './CustomFullScreenRouter'; -import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; +import type {FullScreenNavigatorProps, FullScreenNavigatorRouterOptions} from './types'; -// TODO: Extract to utils with ./createCustomStackNavigator/index.tsx +// TODO-IDEAL: Extract to utils with ./createCustomStackNavigator/index.tsx type Routes = StackNavigationState['routes']; function reduceReportRoutes(routes: Routes): Routes { const result: Routes = []; @@ -30,16 +29,10 @@ function reduceReportRoutes(routes: Routes): Routes { return result.reverse(); } -function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { - const {isSmallScreenWidth} = useWindowDimensions(); - - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); - - isSmallScreenWidthRef.current = isSmallScreenWidth; - +function FullScreenNavigator(props: FullScreenNavigatorProps) { const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< StackNavigationState, - ResponsiveStackNavigatorRouterOptions, + FullScreenNavigatorRouterOptions, StackActionHelpers, StackNavigationOptions, StackNavigationEventMap @@ -72,6 +65,6 @@ function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { ); } -ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; +FullScreenNavigator.displayName = 'FullScreenNavigator'; -export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof FullScreenNavigator>(FullScreenNavigator); diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts index d13393b191c8..1ea0765d15d4 100644 --- a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts @@ -1,13 +1,12 @@ import type {DefaultNavigatorOptions, ParamListBase, StackNavigationState, StackRouterOptions} from '@react-navigation/native'; import type {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; -type ResponsiveStackNavigatorConfig = { +type FullScreenNavigatorConfig = { isSmallScreenWidth: boolean; }; -type ResponsiveStackNavigatorRouterOptions = StackRouterOptions; +type FullScreenNavigatorRouterOptions = StackRouterOptions; -type ResponsiveStackNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & - ResponsiveStackNavigatorConfig; +type FullScreenNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & FullScreenNavigatorConfig; -export type {ResponsiveStackNavigatorConfig, ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions}; +export type {FullScreenNavigatorConfig, FullScreenNavigatorProps, FullScreenNavigatorRouterOptions}; diff --git a/src/pages/AddPersonalBankAccountPage.js b/src/pages/AddPersonalBankAccountPage.js index 09b73ea158f9..182ef2ba4eac 100644 --- a/src/pages/AddPersonalBankAccountPage.js +++ b/src/pages/AddPersonalBankAccountPage.js @@ -97,7 +97,7 @@ function AddPersonalBankAccountPage({personalBankAccount, plaidData}) { diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index d7abbab6e93f..80849fbb13b3 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -220,7 +220,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i diff --git a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js index c235a31f626f..b32d211a8a3d 100644 --- a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js +++ b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js @@ -90,7 +90,7 @@ function BankAccountPlaidStep(props) { + Navigation.goBack(isReport ? ROUTES.REPORT_WITH_ID_DETAILS.getRoute(this.props.report.reportID) : ROUTES.SETTINGS.ROOT)} @@ -88,7 +91,7 @@ class ShareCodePage extends React.Component { /> - + ({ - sectionStyle: styles.accountSettingsSectionContainer, - sectionTranslationKey: 'initialSettingsPage.account', - items: [ - { - translationKey: 'common.workspaces', - icon: Expensicons.Building, - routeName: ROUTES.SETTINGS_WORKSPACES, + const menuItems = useMemo(() => { + const baseMenuItems = [ + { + translationKey: 'common.workspaces', + icon: Expensicons.Building, + action: () => { + waitForNavigate(() => { + Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); + })(); }, - { - translationKey: 'allSettingsScreen.subscriptions', - icon: Expensicons.MoneyBag, - action: () => { - Link.openOldDotLink(CONST.ADMIN_POLICIES_URL); - }, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, - link: CONST.ADMIN_POLICIES_URL, + focused: true, + }, + { + translationKey: 'allSettingsScreen.subscriptions', + icon: Expensicons.MoneyBag, + action: () => { + Link.openOldDotLink(CONST.ADMIN_POLICIES_URL); }, - { - translationKey: 'allSettingsScreen.cardsAndDomains', - icon: Expensicons.CardsAndDomains, - action: () => { - Link.openOldDotLink(CONST.ADMIN_DOMAINS_URL); - }, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, - link: CONST.ADMIN_DOMAINS_URL, + shouldShowRightIcon: true, + iconRight: Expensicons.NewWindow, + link: CONST.ADMIN_POLICIES_URL, + }, + { + translationKey: 'allSettingsScreen.cardsAndDomains', + icon: Expensicons.CardsAndDomains, + action: () => { + Link.openOldDotLink(CONST.ADMIN_DOMAINS_URL); }, - ], - }), - [styles.accountSettingsSectionContainer], - ); - - /** - * Retuns JSX.Element with menu items - * @param {Object} data list with menu items data - * @returns {JSX.Element} the menu items for passed data - */ - const getMenuItemsSection = useCallback( - (data) => ( - - {_.map(data.items, (item, index) => { - const keyTitle = item.translationKey ? translate(item.translationKey) : item.title; - - return ( - { - if (item.action) { - item.action(); - } else { - waitForNavigate(() => { - Navigation.navigate(item.routeName); - })(); - } - })} - shouldBlockSelection={Boolean(item.link)} - focused={activeRoute && item.routeName && activeRoute.toLowerCase().replaceAll('_', '') === item.routeName.replaceAll('/', '')} - isPaneMenu - /> - ); - })} - - ), - [activeRoute, isExecuting, singleExecution, styles.mh3, styles.pb4, styles.sectionMenuItem, translate, waitForNavigate], - ); - - const accountMenuItems = useMemo(() => getMenuItemsSection(menuItemsData), [menuItemsData, getMenuItemsSection]); + shouldShowRightIcon: true, + iconRight: Expensicons.NewWindow, + link: CONST.ADMIN_DOMAINS_URL, + }, + ]; + return _.map(baseMenuItems, (item) => ({ + key: item.translationKey, + title: translate(item.translationKey), + icon: item.icon, + iconRight: item.iconRight, + onPress: item.action, + shouldShowRightIcon: item.shouldShowRightIcon, + shouldBlockSelection: Boolean(item.link), + wrapperStyle: styles.sectionMenuItem, + isPaneMenu: true, + focused: item.focused, + })); + }, [styles, translate, waitForNavigate]); return ( - <> + - {accountMenuItems} - + + + + ); } diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index 5c1819bedbc6..5c3582343458 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -33,16 +33,13 @@ function BaseSidebarScreen(props) { includePaddingTop={false} > {({insets}) => ( - <> - - - - {props.children} - + + + )} ); diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js index 532bd1d2ad48..705c22aaaefb 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js @@ -6,7 +6,7 @@ import {withOnyx} from 'react-native-onyx'; import FloatingActionButton from '@components/FloatingActionButton'; import * as Expensicons from '@components/Icon/Expensicons'; import PopoverMenu from '@components/PopoverMenu'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import {withLocalizePropTypes} from '@components/withLocalize'; import withNavigation from '@components/withNavigation'; import withNavigationFocus from '@components/withNavigationFocus'; import withWindowDimensions from '@components/withWindowDimensions'; @@ -190,12 +190,12 @@ function FloatingActionButtonAndPopover(props) { menuItems={[ { icon: Expensicons.ChatBubble, - text: props.translate('sidebarScreen.fabNewChat'), + text: translate('sidebarScreen.fabNewChat'), onSelected: () => interceptAnonymousUser(() => Navigation.navigate(ROUTES.NEW)), }, { icon: Expensicons.MoneyCircle, - text: props.translate('iou.requestMoney'), + text: translate('iou.requestMoney'), onSelected: () => interceptAnonymousUser(() => Navigation.navigate( @@ -207,19 +207,19 @@ function FloatingActionButtonAndPopover(props) { }, { icon: Expensicons.Send, - text: props.translate('iou.sendMoney'), + text: translate('iou.sendMoney'), onSelected: () => interceptAnonymousUser(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SEND)), }, ...[ { icon: Expensicons.Task, - text: props.translate('newTaskPage.assignTask'), + text: translate('newTaskPage.assignTask'), onSelected: () => interceptAnonymousUser(() => Task.clearOutTaskInfoAndNavigate()), }, ], { icon: Expensicons.Heart, - text: props.translate('sidebarScreen.saveTheWorld'), + text: translate('sidebarScreen.saveTheWorld'), onSelected: () => interceptAnonymousUser(() => Navigation.navigate(ROUTES.TEACHERS_UNITE)), }, ...(!props.isLoading && !Policy.hasActiveFreePolicy(props.allPolicies) @@ -230,8 +230,8 @@ function FloatingActionButtonAndPopover(props) { icon: Expensicons.NewWorkspace, iconWidth: 46, iconHeight: 40, - text: props.translate('workspace.new.newWorkspace'), - description: props.translate('workspace.new.getTheExpensifyCardAndMore'), + text: translate('workspace.new.newWorkspace'), + description: translate('workspace.new.getTheExpensifyCardAndMore'), onSelected: () => interceptAnonymousUser(() => App.createWorkspaceWithPolicyDraftAndNavigateToIt()), }, ] @@ -266,7 +266,6 @@ const FloatingActionButtonAndPopoverWithRef = forwardRef((props, ref) => ( FloatingActionButtonAndPopoverWithRef.displayName = 'FloatingActionButtonAndPopoverWithRef'; export default compose( - withLocalize, withNavigation, withNavigationFocus, withWindowDimensions, diff --git a/src/pages/settings/AboutPage/AboutPage.js b/src/pages/settings/AboutPage/AboutPage.js index 95de29d3af97..0b23aba87b0c 100644 --- a/src/pages/settings/AboutPage/AboutPage.js +++ b/src/pages/settings/AboutPage/AboutPage.js @@ -101,6 +101,7 @@ function AboutPage(props) { {({safeAreaPaddingBottomStyle}) => ( <> diff --git a/src/pages/settings/Preferences/PreferencesPage.js b/src/pages/settings/Preferences/PreferencesPage.js index 1e72456e4f58..f914129ff5e9 100755 --- a/src/pages/settings/Preferences/PreferencesPage.js +++ b/src/pages/settings/Preferences/PreferencesPage.js @@ -54,6 +54,7 @@ function PreferencesPage(props) { backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.PREFERENCES.ROOT].backgroundColor} illustration={LottieAnimations.PreferencesDJ} shouldShowBackButton={isSmallScreenWidth} + shouldShowOfflineIndicator > diff --git a/src/pages/settings/Security/TwoFactorAuth/StepWrapper/StepWrapper.js b/src/pages/settings/Security/TwoFactorAuth/StepWrapper/StepWrapper.js index ba899a0e2d20..9460a20e8fea 100644 --- a/src/pages/settings/Security/TwoFactorAuth/StepWrapper/StepWrapper.js +++ b/src/pages/settings/Security/TwoFactorAuth/StepWrapper/StepWrapper.js @@ -23,7 +23,7 @@ function StepWrapper({ return ( diff --git a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js index 1d1ce906189b..b8cbf9324cfa 100644 --- a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js +++ b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.js @@ -201,7 +201,7 @@ function BaseGetPhysicalCard({ return ( ) : ( - + Navigation.goBack(ROUTES.SETTINGS.ROOT)} shouldShowBackButton={isSmallScreenWidth} /> - + diff --git a/src/pages/wallet/WalletStatementPage.js b/src/pages/wallet/WalletStatementPage.js index e79a2add5213..20c903830a5a 100644 --- a/src/pages/wallet/WalletStatementPage.js +++ b/src/pages/wallet/WalletStatementPage.js @@ -93,7 +93,7 @@ function WalletStatementPage(props) { return ( diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 4e3db08d6c6e..26c248efb6a9 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -10,6 +10,7 @@ import ConfirmModal from '@components/ConfirmModal'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import ScreenWrapper from '@components/ScreenWrapper'; import useActiveRoute from '@hooks/useActiveRoute'; import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; @@ -204,7 +205,7 @@ function WorkspaceInitialPage(props) { (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); return ( - <> + Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} shouldShow={shouldShowNotFoundPage} @@ -272,7 +273,7 @@ function WorkspaceInitialPage(props) { danger /> - + ); } diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 664e82d7307b..3e50fc0ca8e4 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -420,6 +420,7 @@ function WorkspaceMembersPage(props) { includeSafeAreaPaddingBottom={false} style={[styles.defaultModalContainer]} testID={WorkspaceMembersPage.displayName} + shouldShowOfflineIndicator > {(hasVBA) => ( <> @@ -141,5 +142,4 @@ export default compose( withOnyx({ currencyList: {key: ONYXKEYS.CURRENCY_LIST}, }), - withNetwork(), )(WorkspaceOverviewPage); diff --git a/src/pages/workspace/WorkspacePageWithSections.js b/src/pages/workspace/WorkspacePageWithSections.js index d3daa785e350..c67e2adca625 100644 --- a/src/pages/workspace/WorkspacePageWithSections.js +++ b/src/pages/workspace/WorkspacePageWithSections.js @@ -67,6 +67,8 @@ const propTypes = { /** Option to show the loading page while the API is calling */ shouldShowLoading: PropTypes.bool, + + shouldShowOfflineIndicator: PropTypes.bool, }; const defaultProps = { @@ -79,6 +81,7 @@ const defaultProps = { shouldSkipVBBACall: false, backButtonRoute: '', shouldShowLoading: true, + shouldShowOfflineIndicator: false, }; function fetchData(skipVBBACal) { @@ -102,6 +105,7 @@ function WorkspacePageWithSections({ shouldSkipVBBACall, user, shouldShowLoading, + shouldShowOfflineIndicator, }) { const styles = useThemeStyles(); useNetwork({onReconnect: () => fetchData(shouldSkipVBBACall)}); @@ -130,6 +134,7 @@ function WorkspacePageWithSections({ shouldEnablePickerAvoiding={false} shouldEnableMaxHeight testID={WorkspacePageWithSections.displayName} + shouldShowOfflineIndicator={shouldShowOfflineIndicator} > Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} diff --git a/src/pages/workspace/WorkspacesListPage.js b/src/pages/workspace/WorkspacesListPage.js index 9b9f7680e68f..dd5359a39a7c 100755 --- a/src/pages/workspace/WorkspacesListPage.js +++ b/src/pages/workspace/WorkspacesListPage.js @@ -15,7 +15,6 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import {PressableWithoutFeedback} from '@components/Pressable'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; @@ -66,15 +65,13 @@ const propTypes = { /** All reports shared with the user (coming from Onyx) */ reports: PropTypes.objectOf(reportPropTypes), - - ...withCurrentUserPersonalDetailsPropTypes, }; const defaultProps = { policies: {}, allPolicyMembers: {}, reimbursementAccount: {}, - ...withCurrentUserPersonalDetailsDefaultProps, + reports: {}, }; const workspaceFeatures = [ @@ -111,7 +108,7 @@ function dismissWorkspaceError(policyID, pendingAction) { throw new Error('Not implemented'); } -function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, currentUserPersonalDetails, reports}) { +function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, reports}) { const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -179,16 +176,15 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, c title={keyTitle} menuItems={threeDotsMenuItems} workspaceIcon={item.icon} - ownerAccountID={currentUserPersonalDetails.accountID} + ownerAccountID={item.ownerAccountID} workspaceType={item.type} - currentUserPersonalDetails={currentUserPersonalDetails} layoutWidth={isSmallScreenWidth ? CONST.LAYOUT_WIDTH.NARROW : CONST.LAYOUT_WIDTH.WIDE} /> ); }, - [currentUserPersonalDetails, isSmallScreenWidth, styles.mb3, styles.mh5, styles.ph5, translate], + [isSmallScreenWidth, styles.mb3, styles.mh5, styles.ph5, translate], ); const listHeaderComponent = useCallback(() => { @@ -285,6 +281,7 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, c reports: policy.reports, adminRoom: policyRooms[policy.id] ? policyRooms[policy.id].adminRoom : null, announceRoom: policyRooms[policy.id] ? policyRooms[policy.id].announceRoom : null, + ownerAccountID: policy.ownerAccountID, })) .sortBy((policy) => policy.title.toLowerCase()) .value(); @@ -332,8 +329,11 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, c } return ( - - + + {(hasVBA, policyID) => ( - + {!hasVBA && } {hasVBA && } diff --git a/src/pages/workspace/card/WorkspaceCardPage.js b/src/pages/workspace/card/WorkspaceCardPage.js index 3285d1a69770..b2dfad8ee51b 100644 --- a/src/pages/workspace/card/WorkspaceCardPage.js +++ b/src/pages/workspace/card/WorkspaceCardPage.js @@ -25,7 +25,7 @@ const propTypes = { function WorkspaceCardPage(props) { const styles = useThemeStyles(); - const {isMobileScreenWidth} = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); return ( {(hasVBA, policyID, isUsingECard) => ( - + {!hasVBA && } {hasVBA && !isUsingECard && } diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js index 753a49a4d6e8..6e4094cd50c3 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js @@ -24,7 +24,7 @@ const propTypes = { function WorkspaceInvoicesPage(props) { const styles = useThemeStyles(); - const {isMobileScreenWidth} = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); return ( {(hasVBA, policyID) => ( - + {!hasVBA && } {hasVBA && } diff --git a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js index fa3849abc941..020614dd0bee 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js +++ b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js @@ -30,6 +30,7 @@ function WorkspaceReimbursePage(props) { guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_REIMBURSE} shouldSkipVBBACall shouldShowLoading={false} + shouldShowOfflineIndicator > {() => } diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 718cc5bebdfb..c4858989696b 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -69,7 +69,7 @@ const defaultProps = { function WorkspaceReimburseView(props) { const styles = useThemeStyles(); const [currentRatePerUnit, setCurrentRatePerUnit] = useState(''); - const {isMobileScreenWidth} = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); const viewAllReceiptsUrl = `expenses?policyIDList=${props.policy.id}&billableReimbursable=reimbursable&submitterEmail=%2B%2B`; const distanceCustomUnit = _.find(lodashGet(props.policy, 'customUnits', {}), (unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE); const distanceCustomRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), (rate) => rate.name === CONST.CUSTOM_UNITS.DEFAULT_RATE); @@ -105,7 +105,7 @@ function WorkspaceReimburseView(props) { }, [props.policy.customUnits, getCurrentRatePerUnitLabel]); return ( - +
{(hasVBA, policyID) => ( - + {!hasVBA && } {hasVBA && } diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 2d5e1bb6cbbb..1af88401bff2 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1300,6 +1300,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ * * @param buttonState - One of {'default', 'hovered', 'pressed'} * @param isMenuIcon - whether this icon is apart of a list + * @param isPane - whether this icon is in a pane, e.g. Account or Workspace Settings */ getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false, isPane = false): string => { switch (buttonState) {