Skip to content

Commit

Permalink
Merge pull request #37421 from software-mansion-labs/ideal-nav-v2-wor…
Browse files Browse the repository at this point in the history
…kspaces

Ideal nav v2 workspaces
  • Loading branch information
mountiny authored Mar 12, 2024
2 parents 87fb21e + b85bee8 commit 5d16b4f
Show file tree
Hide file tree
Showing 60 changed files with 806 additions and 696 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ index 7558eb3..b7bb75e 100644
}) : STATE_TRANSITIONING_OR_BELOW_TOP;
}
+
+ const isHomeScreenAndNotOnTop = (route.name === 'BottomTabNavigator' || route.name === 'Settings_Root') && isScreenActive !== STATE_ON_TOP;
+ const isHomeScreenAndNotOnTop = (route.name === 'BottomTabNavigator' || route.name === 'Workspace_Initial') && isScreenActive !== STATE_ON_TOP;
+
const {
headerShown = true,
Expand Down
124 changes: 62 additions & 62 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,128 +450,128 @@ const ROUTES = {
WORKSPACE_NEW: 'workspace/new',
WORKSPACE_NEW_ROOM: 'workspace/new-room',
WORKSPACE_INITIAL: {
route: 'workspace/:policyID',
getRoute: (policyID: string) => `workspace/${policyID}` as const,
route: 'settings/workspaces/:policyID',
getRoute: (policyID: string) => `settings/workspaces/${policyID}` as const,
},
WORKSPACE_INVITE: {
route: 'workspace/:policyID/invite',
getRoute: (policyID: string) => `workspace/${policyID}/invite` as const,
route: 'settings/workspaces/:policyID/invite',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/invite` as const,
},
WORKSPACE_INVITE_MESSAGE: {
route: 'workspace/:policyID/invite-message',
getRoute: (policyID: string) => `workspace/${policyID}/invite-message` as const,
route: 'settings/workspaces/:policyID/invite-message',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/invite-message` as const,
},
WORKSPACE_PROFILE: {
route: 'workspace/:policyID/profile',
getRoute: (policyID: string) => `workspace/${policyID}/profile` as const,
route: 'settings/workspaces/:policyID/profile',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile` as const,
},
WORKSPACE_PROFILE_CURRENCY: {
route: 'workspace/:policyID/profile/currency',
getRoute: (policyID: string) => `workspace/${policyID}/profile/currency` as const,
route: 'settings/workspaces/:policyID/profile/currency',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile/currency` as const,
},
WORKSPACE_PROFILE_NAME: {
route: 'workspace/:policyID/profile/name',
getRoute: (policyID: string) => `workspace/${policyID}/profile/name` as const,
route: 'settings/workspaces/:policyID/profile/name',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile/name` as const,
},
WORKSPACE_PROFILE_DESCRIPTION: {
route: 'workspace/:policyID/profile/description',
getRoute: (policyID: string) => `workspace/${policyID}/profile/description` as const,
route: 'settings/workspaces/:policyID/profile/description',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile/description` as const,
},
WORKSPACE_PROFILE_SHARE: {
route: 'workspace/:policyID/profile/share',
getRoute: (policyID: string) => `workspace/${policyID}/profile/share` as const,
route: 'settings/workspaces/:policyID/profile/share',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile/share` as const,
},
WORKSPACE_AVATAR: {
route: 'workspace/:policyID/avatar',
getRoute: (policyID: string) => `workspace/${policyID}/avatar` as const,
route: 'settings/workspaces/:policyID/avatar',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/avatar` as const,
},
WORKSPACE_JOIN_USER: {
route: 'workspace/:policyID/join',
getRoute: (policyID: string, inviterEmail: string) => `workspace/${policyID}/join?email=${inviterEmail}` as const,
route: 'settings/workspaces/:policyID/join',
getRoute: (policyID: string, inviterEmail: string) => `settings/workspaces/${policyID}/join?email=${inviterEmail}` as const,
},
WORKSPACE_SETTINGS_CURRENCY: {
route: 'workspace/:policyID/settings/currency',
getRoute: (policyID: string) => `workspace/${policyID}/settings/currency` as const,
route: 'settings/workspaces/:policyID/settings/currency',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/currency` as const,
},
WORKSPACE_WORKFLOWS: {
route: 'workspace/:policyID/workflows',
getRoute: (policyID: string) => `workspace/${policyID}/workflows` as const,
route: 'settings/workspaces/:policyID/workflows',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows` as const,
},
WORKSPACE_WORKFLOWS_PAYER: {
route: 'workspace/:policyID/settings/workflows/payer',
getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/payer` as const,
},
WORKSPACE_WORKFLOWS_APPROVER: {
route: 'workspace/:policyID/settings/workflows/approver',
getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/approver` as const,
route: 'settings/workspaces/:policyID/settings/workflows/approver',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/approver` as const,
},
WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY: {
route: 'workspace/:policyID/settings/workflows/auto-reporting-frequency',
getRoute: (policyID: string) => `workspace/${policyID}/settings/workflows/auto-reporting-frequency` as const,
route: 'settings/workspaces/:policyID/settings/workflows/auto-reporting-frequency',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/auto-reporting-frequency` as const,
},
WORKSPACE_WORKFLOWS_AUTOREPORTING_MONTHLY_OFFSET: {
route: 'workspace/:policyID/settings/workflows/auto-reporting-frequency/monthly-offset',
getRoute: (policyID: string) => `workspace/${policyID}/settings/workflows/auto-reporting-frequency/monthly-offset` as const,
route: 'settings/workspaces/:policyID/settings/workflows/auto-reporting-frequency/monthly-offset',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/auto-reporting-frequency/monthly-offset` as const,
},
WORKSPACE_CARD: {
route: 'workspace/:policyID/card',
getRoute: (policyID: string) => `workspace/${policyID}/card` as const,
route: 'settings/workspaces/:policyID/card',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/card` as const,
},
WORKSPACE_REIMBURSE: {
route: 'workspace/:policyID/reimburse',
getRoute: (policyID: string) => `workspace/${policyID}/reimburse` as const,
route: 'settings/workspaces/:policyID/reimburse',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/reimburse` as const,
},
WORKSPACE_RATE_AND_UNIT: {
route: 'workspace/:policyID/rateandunit',
getRoute: (policyID: string) => `workspace/${policyID}/rateandunit` as const,
route: 'settings/workspaces/:policyID/rateandunit',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/rateandunit` as const,
},
WORKSPACE_RATE_AND_UNIT_RATE: {
route: 'workspace/:policyID/rateandunit/rate',
getRoute: (policyID: string) => `workspace/${policyID}/rateandunit/rate` as const,
route: 'settings/workspaces/:policyID/rateandunit/rate',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/rateandunit/rate` as const,
},
WORKSPACE_RATE_AND_UNIT_UNIT: {
route: 'workspace/:policyID/rateandunit/unit',
getRoute: (policyID: string) => `workspace/${policyID}/rateandunit/unit` as const,
route: 'settings/workspaces/:policyID/rateandunit/unit',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/rateandunit/unit` as const,
},
WORKSPACE_BILLS: {
route: 'workspace/:policyID/bills',
getRoute: (policyID: string) => `workspace/${policyID}/bills` as const,
route: 'settings/workspaces/:policyID/bills',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/bills` as const,
},
WORKSPACE_INVOICES: {
route: 'workspace/:policyID/invoices',
getRoute: (policyID: string) => `workspace/${policyID}/invoices` as const,
route: 'settings/workspaces/:policyID/invoices',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/invoices` as const,
},
WORKSPACE_TRAVEL: {
route: 'workspace/:policyID/travel',
getRoute: (policyID: string) => `workspace/${policyID}/travel` as const,
route: 'settings/workspaces/:policyID/travel',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/travel` as const,
},
WORKSPACE_MEMBERS: {
route: 'workspace/:policyID/members',
getRoute: (policyID: string) => `workspace/${policyID}/members` as const,
route: 'settings/workspaces/:policyID/members',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/members` as const,
},
WORKSPACE_CATEGORIES: {
route: 'workspace/:policyID/categories',
getRoute: (policyID: string) => `workspace/${policyID}/categories` as const,
route: 'settings/workspaces/:policyID/categories',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/categories` as const,
},
WORKSPACE_CATEGORY_SETTINGS: {
route: 'workspace/:policyID/categories/:categoryName',
getRoute: (policyID: string, categoryName: string) => `workspace/${policyID}/categories/${encodeURI(categoryName)}` as const,
route: 'settings/workspaces/:policyID/categories/:categoryName',
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURI(categoryName)}` as const,
},
WORKSPACE_CATEGORIES_SETTINGS: {
route: 'workspace/:policyID/categories/settings',
getRoute: (policyID: string) => `workspace/${policyID}/categories/settings` as const,
route: 'settings/workspaces/:policyID/categories/settings',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/categories/settings` as const,
},
WORKSPACE_MORE_FEATURES: {
route: 'workspace/:policyID/more-features',
getRoute: (policyID: string) => `workspace/${policyID}/more-features` as const,
},
WORKSPACE_CATEGORY_CREATE: {
route: 'workspace/:policyID/categories/new',
getRoute: (policyID: string) => `workspace/${policyID}/categories/new` as const,
route: 'settings/workspaces/:policyID/categories/new',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/categories/new` as const,
},
WORKSPACE_TAGS: {
route: 'workspace/:policyID/tags',
getRoute: (policyID: string) => `workspace/${policyID}/tags` as const,
route: 'settings/workspaces/:policyID/tags',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/tags` as const,
},
WORKSPACE_TAGS_SETTINGS: {
route: 'workspace/:policyID/tags/settings',
Expand All @@ -582,12 +582,12 @@ const ROUTES = {
getRoute: (policyID: string) => `workspace/${policyID}/tags/edit` as const,
},
WORKSPACE_MEMBER_DETAILS: {
route: 'workspace/:policyID/members/:accountID',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`workspace/${policyID}/members/${accountID}`, backTo),
route: 'settings/workspaces/:policyID/members/:accountID',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/members/${accountID}`, backTo),
},
WORKSPACE_MEMBER_ROLE_SELECTION: {
route: 'workspace/:policyID/members/:accountID/role-selection',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`workspace/${policyID}/members/${accountID}/role-selection`, backTo),
route: 'settings/workspaces/:policyID/members/:accountID/role-selection',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/members/${accountID}/role-selection`, backTo),
},
WORKSPACE_DISTANCE_RATES: {
route: 'workspace/:policyID/distance-rates',
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const SCREENS = {
VALIDATE_LOGIN: 'ValidateLogin',
UNLINK_LOGIN: 'UnlinkLogin',
SETTINGS_CENTRAL_PANE: 'SettingsCentralPane',
WORKSPACES_CENTRAL_PANE: 'WorkspacesCentralPane',
SETTINGS: {
ROOT: 'Settings_Root',
SHARE_CODE: 'Settings_Share_Code',
Expand Down
11 changes: 7 additions & 4 deletions src/components/AvatarSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import React from 'react';
import {Circle} from 'react-native-svg';
import useTheme from '@hooks/useTheme';
import variables from '@styles/variables';
import SkeletonViewContentLoader from './SkeletonViewContentLoader';

function AvatarSkeleton() {
const theme = useTheme();
const skeletonCircleRadius = variables.componentSizeSmall / 2;

return (
<SkeletonViewContentLoader
animate
height={40}
height={variables.componentSizeSmall}
backgroundColor={theme.skeletonLHNIn}
foregroundColor={theme.skeletonLHNOut}
>
<Circle
cx={20}
cy={20}
r={20}
cx={skeletonCircleRadius}
cy={skeletonCircleRadius}
r={skeletonCircleRadius}
/>
</SkeletonViewContentLoader>
);
Expand Down
2 changes: 2 additions & 0 deletions src/components/AvatarWithIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import * as UserUtils from '@libs/UserUtils';
import CONST from '@src/CONST';
import Avatar from './Avatar';
import AvatarSkeleton from './AvatarSkeleton';
import * as Expensicons from './Icon/Expensicons';
Expand Down Expand Up @@ -33,6 +34,7 @@ function AvatarWithIndicator({source, tooltipText = '', fallbackIcon = Expensico
) : (
<>
<Avatar
size={CONST.AVATAR_SIZE.SMALL}
source={UserUtils.getSmallSizeAvatar(source)}
fallbackIcon={fallbackIcon}
/>
Expand Down
20 changes: 10 additions & 10 deletions src/components/FloatingActionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: Flo
};

return (
<Tooltip text={translate('common.create')}>
<PressableWithoutFeedback
style={styles.h100}
accessibilityLabel={accessibilityLabel}
onPress={toggleFabAction}
>
<View style={styles.bottomTabBarItem}>
<PressableWithoutFeedback
style={styles.h100}
accessibilityLabel={accessibilityLabel}
onPress={toggleFabAction}
>
<View style={styles.bottomTabBarItem}>
<Tooltip text={translate('common.create')}>
<AnimatedPressable
ref={(el) => {
fabPressable.current = el ?? null;
Expand All @@ -136,9 +136,9 @@ function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: Flo
/>
</Svg>
</AnimatedPressable>
</View>
</PressableWithoutFeedback>
</Tooltip>
</Tooltip>
</View>
</PressableWithoutFeedback>
);
}

Expand Down
16 changes: 14 additions & 2 deletions src/components/HeaderWithBackButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import {Keyboard, StyleSheet, View} from 'react-native';
import Avatar from '@components/Avatar';
import AvatarWithDisplayName from '@components/AvatarWithDisplayName';
import Header from '@components/Header';
import Icon from '@components/Icon';
Expand Down Expand Up @@ -32,7 +33,8 @@ function HeaderWithBackButton({
onThreeDotsButtonPress = () => {},
report = null,
policy,
shouldShowAvatarWithDisplay = false,
policyAvatar,
shouldShowReportAvatarWithDisplay = false,
shouldShowBackButton = true,
shouldShowBorderBottom = false,
shouldShowCloseButton = false,
Expand All @@ -58,6 +60,7 @@ function HeaderWithBackButton({
shouldOverlay = false,
singleExecution = (func) => func,
shouldNavigateToTopMostReport = false,
style,
}: HeaderWithBackButtonProps) {
const theme = useTheme();
const styles = useThemeStyles();
Expand All @@ -81,6 +84,7 @@ function HeaderWithBackButton({
shouldShowBorderBottom && styles.borderBottom,
shouldShowBackButton && styles.pl2,
shouldOverlay && StyleSheet.absoluteFillObject,
style,
]}
>
<View style={[styles.dFlex, styles.flexRow, styles.alignItemsCenter, styles.flexGrow1, styles.justifyContentBetween, styles.overflowHidden]}>
Expand Down Expand Up @@ -118,7 +122,15 @@ function HeaderWithBackButton({
additionalStyles={[styles.mr2]}
/>
)}
{shouldShowAvatarWithDisplay ? (
{policyAvatar && (
<Avatar
containerStyles={[StyleUtils.getWidthAndHeightStyle(StyleUtils.getAvatarSize(CONST.AVATAR_SIZE.DEFAULT)), styles.mr3]}
source={policyAvatar?.source}
name={policyAvatar?.name}
type={policyAvatar?.type}
/>
)}
{shouldShowReportAvatarWithDisplay ? (
<AvatarWithDisplayName
report={report}
policy={policy}
Expand Down
12 changes: 10 additions & 2 deletions src/components/HeaderWithBackButton/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type {ReactNode} from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import type {Action} from '@hooks/useSingleExecution';
import type {StepCounterParams} from '@src/languages/types';
import type {AnchorPosition} from '@src/styles';
import type {PersonalDetails, Policy, Report} from '@src/types/onyx';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import type IconAsset from '@src/types/utils/IconAsset';

Expand Down Expand Up @@ -89,8 +91,8 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {
/** Data to display a step counter in the header */
stepCounter?: StepCounterParams;

/** Whether we should show an avatar */
shouldShowAvatarWithDisplay?: boolean;
/** Whether we should show a report avatar */
shouldShowReportAvatarWithDisplay?: boolean;

/** Parent report, if provided it will override props.report for AvatarWithDisplay */
parentReport?: OnyxEntry<Report>;
Expand Down Expand Up @@ -121,6 +123,12 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {

/** Whether we should overlay the 3 dots menu */
shouldOverlayDots?: boolean;

/** Policy avatar to display in the header */
policyAvatar?: Icon;

/** Additional styles to add to the component */
style?: StyleProp<ViewStyle>;
};

export type {ThreeDotsMenuItem};
Expand Down
Loading

0 comments on commit 5d16b4f

Please sign in to comment.