Skip to content

[Desktop Navigation] Add a tooltip to the account switcher on the accounts page #59713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 68 additions & 61 deletions src/components/AccountSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {clearDelegatorErrors, connect, disconnect} from '@libs/actions/Delegate';
import * as EmojiUtils from '@libs/EmojiUtils';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
import {close} from '@libs/actions/Modal';
import {getProcessedText, splitTextWithEmojis} from '@libs/EmojiUtils';
import {getLatestError} from '@libs/ErrorUtils';
import {getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils';
import variables from '@styles/variables';
import * as Modal from '@userActions/Modal';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails} from '@src/types/onyx';
Expand All @@ -27,6 +27,7 @@ import type {PopoverMenuItem} from './PopoverMenu';
import PopoverMenu from './PopoverMenu';
import {PressableWithFeedback} from './Pressable';
import Text from './Text';
import Tooltip from './Tooltip';

function AccountSwitcher() {
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
Expand All @@ -47,7 +48,7 @@ function AccountSwitcher() {

const isActingAsDelegate = !!account?.delegatedAccess?.delegate ?? false;
const canSwitchAccounts = delegators.length > 0 || isActingAsDelegate;
const processedTextArray = EmojiUtils.splitTextWithEmojis(currentUserPersonalDetails?.displayName);
const processedTextArray = splitTextWithEmojis(currentUserPersonalDetails?.displayName);

const createBaseMenuItem = (
personalDetails: PersonalDetails | undefined,
Expand All @@ -58,7 +59,7 @@ function AccountSwitcher() {
return {
text: personalDetails?.displayName ?? personalDetails?.login ?? '',
description: Str.removeSMSDomain(personalDetails?.login ?? ''),
avatarID: personalDetails?.accountID ?? -1,
avatarID: personalDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID,
icon: personalDetails?.avatar ?? '',
iconType: CONST.ICON_TYPE_AVATAR,
outerWrapperStyle: shouldUseNarrowLayout ? {} : styles.accountSwitcherPopover,
Expand Down Expand Up @@ -86,14 +87,14 @@ function AccountSwitcher() {
return [currentUserMenuItem];
}

const delegatePersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(delegateEmail);
const error = ErrorUtils.getLatestError(account?.delegatedAccess?.errorFields?.disconnect);
const delegatePersonalDetails = getPersonalDetailByEmail(delegateEmail);
const error = getLatestError(account?.delegatedAccess?.errorFields?.disconnect);

return [
createBaseMenuItem(delegatePersonalDetails, error, {
onSelected: () => {
if (isOffline) {
Modal.close(() => setShouldShowOfflineModal(true));
close(() => setShouldShowOfflineModal(true));
return;
}
disconnect();
Expand All @@ -107,13 +108,13 @@ function AccountSwitcher() {
.filter(({email}) => email !== currentUserPersonalDetails.login)
.map(({email, role}) => {
const errorFields = account?.delegatedAccess?.errorFields ?? {};
const error = ErrorUtils.getLatestError(errorFields?.connect?.[email]);
const personalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email);
const error = getLatestError(errorFields?.connect?.[email]);
const personalDetails = getPersonalDetailByEmail(email);
return createBaseMenuItem(personalDetails, error, {
badgeText: translate('delegate.role', {role}),
onSelected: () => {
if (isOffline) {
Modal.close(() => setShouldShowOfflineModal(true));
close(() => setShouldShowOfflineModal(true));
return;
}
connect(email);
Expand All @@ -126,63 +127,69 @@ function AccountSwitcher() {

return (
<>
<PressableWithFeedback
accessible
accessibilityLabel={translate('common.profile')}
onPress={() => {
setShouldShowDelegatorMenu(!shouldShowDelegatorMenu);
}}
ref={buttonRef}
interactive={canSwitchAccounts}
pressDimmingValue={canSwitchAccounts ? undefined : 1}
wrapperStyle={[styles.flexGrow1, styles.flex1, styles.mnw0, styles.justifyContentCenter]}
<Tooltip
text={translate('delegate.copilotAccess')}
shiftVertical={8}
shiftHorizontal={8}
anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM}}
shouldRender={canSwitchAccounts}
>
<View style={[styles.flexRow, styles.gap3]}>
<Avatar
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.DEFAULT}
avatarID={currentUserPersonalDetails?.accountID}
source={currentUserPersonalDetails?.avatar}
fallbackIcon={currentUserPersonalDetails.fallbackIcon}
/>
<View style={[styles.flex1, styles.flexShrink1, styles.flexBasis0, styles.justifyContentCenter, styles.gap1]}>
<View style={[styles.flexRow, styles.gap1]}>
<PressableWithFeedback
accessible
accessibilityLabel={translate('common.profile')}
onPress={() => {
setShouldShowDelegatorMenu(!shouldShowDelegatorMenu);
}}
ref={buttonRef}
interactive={canSwitchAccounts}
pressDimmingValue={canSwitchAccounts ? undefined : 1}
wrapperStyle={[styles.flexGrow1, styles.flex1, styles.mnw0, styles.justifyContentCenter]}
>
<View style={[styles.flexRow, styles.gap3]}>
<Avatar
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.DEFAULT}
avatarID={currentUserPersonalDetails?.accountID}
source={currentUserPersonalDetails?.avatar}
fallbackIcon={currentUserPersonalDetails.fallbackIcon}
/>
<View style={[styles.flex1, styles.flexShrink1, styles.flexBasis0, styles.justifyContentCenter, styles.gap1]}>
<View style={[styles.flexRow, styles.gap1]}>
<Text
numberOfLines={1}
style={[styles.textBold, styles.textLarge, styles.flexShrink1]}
>
{processedTextArray.length !== 0 ? getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji) : currentUserPersonalDetails?.displayName}
</Text>
{!!canSwitchAccounts && (
<View style={styles.justifyContentCenter}>
<Icon
fill={theme.icon}
src={Expensicons.CaretUpDown}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
/>
</View>
)}
</View>
<Text
numberOfLines={1}
style={[styles.textBold, styles.textLarge, styles.flexShrink1]}
style={[styles.colorMuted, styles.fontSizeLabel]}
>
{processedTextArray.length !== 0
? EmojiUtils.getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji)
: currentUserPersonalDetails?.displayName}
{Str.removeSMSDomain(currentUserPersonalDetails?.login ?? '')}
</Text>
{!!canSwitchAccounts && (
<View style={styles.justifyContentCenter}>
<Icon
fill={theme.icon}
src={Expensicons.CaretUpDown}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
/>
</View>
{!!user?.isDebugModeEnabled && (
<Text
style={[styles.textLabelSupporting, styles.mt1, styles.w100]}
numberOfLines={1}
>
AccountID: {session?.accountID}
</Text>
)}
</View>
<Text
numberOfLines={1}
style={[styles.colorMuted, styles.fontSizeLabel]}
>
{Str.removeSMSDomain(currentUserPersonalDetails?.login ?? '')}
</Text>
{!!user?.isDebugModeEnabled && (
<Text
style={[styles.textLabelSupporting, styles.mt1, styles.w100]}
numberOfLines={1}
>
AccountID: {session?.accountID}
</Text>
)}
</View>
</View>
</PressableWithFeedback>
</PressableWithFeedback>
</Tooltip>
{!!canSwitchAccounts && (
<PopoverMenu
isVisible={shouldShowDelegatorMenu}
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5957,6 +5957,7 @@ const translations = {
notAllowedMessageStart: `As a`,
notAllowedMessageHyperLinked: ' copilot',
notAllowedMessageEnd: ({accountOwnerEmail}: AccountOwnerParams) => ` for ${accountOwnerEmail}, you don't have permission to take this action. Sorry!`,
copilotAccess: 'Copilot access',
},
debug: {
debug: 'Debug',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6478,6 +6478,7 @@ const translations = {
notAllowedMessageStart: `Como`,
notAllowedMessageHyperLinked: ' copiloto',
notAllowedMessageEnd: ({accountOwnerEmail}: AccountOwnerParams) => ` de ${accountOwnerEmail}, no tienes permiso para realizar esta acción. ¡Lo siento!`,
copilotAccess: 'Acceso a Copilot',
},
debug: {
debug: 'Depuración',
Expand Down