1 import type { ForwardedRef } from 'react';
2 import { Fragment, forwardRef } from 'react';
4 import { c } from 'ttag';
6 import { useUser } from '@proton/account/user/hooks';
7 import SimpleDropdown from '@proton/components/components/dropdown/SimpleDropdown';
8 import Icon from '@proton/components/components/icon/Icon';
9 import type { AppLinkProps } from '@proton/components/components/link/AppLink';
10 import useConfig from '@proton/components/hooks/useConfig';
11 import { getAvailableApps } from '@proton/shared/lib/apps/apps';
12 import type { APP_NAMES } from '@proton/shared/lib/constants';
13 import { BRAND_NAME } from '@proton/shared/lib/constants';
14 import { isElectronMail, isElectronOnInboxApps, isElectronOnMac } from '@proton/shared/lib/helpers/desktop';
15 import type { UserModel } from '@proton/shared/lib/interfaces';
16 import { useFlag } from '@proton/unleash';
18 import { InboxDesktopAppSwitcher } from '../desktop/InboxDesktopAppSwitcher';
19 import ProductIcon from './ProductIcon';
20 import ProductLink from './ProductLink';
22 interface AppsDropdownProps {
23 onDropdownClick?: () => void;
27 reloadDocument?: AppLinkProps['reloadDocument'];
30 const AppsDropdown = forwardRef<HTMLButtonElement, AppsDropdownProps>(
32 { onDropdownClick, app, user, title, reloadDocument, ...rest }: AppsDropdownProps,
33 ref: ForwardedRef<HTMLButtonElement>
35 const { APP_NAME } = useConfig();
37 const availableApps = getAvailableApps({ user, context: 'dropdown' });
39 if (availableApps.length <= 1) {
47 content={<Icon name="app-switch" size={6} className="apps-dropdown-button-icon shrink-0 no-print" />}
48 className="apps-dropdown-button shrink-0"
49 dropdownClassName="apps-dropdown rounded-lg"
50 originalPlacement="bottom-start"
51 title={title ? title : c('Apps dropdown').t`${BRAND_NAME} applications`}
52 onClick={onDropdownClick}
53 disableDefaultArrowNavigation
58 <ul className="unstyled my-0 p-4" style={{ '--apps-dropdown-repeat': isElectronMail ? '2' : '3' }}>
59 {availableApps.map((appToLinkTo) => {
60 const current = app && appToLinkTo === app;
63 <Fragment key={appToLinkTo}>
64 <li className="dropdown-item apps-dropdown-item" data-testid="apps-dropdown-item">
69 appToLinkTo={appToLinkTo}
70 className="text-center text-no-decoration outline-none--at-all apps-dropdown-link flex flex-column items-center"
72 reloadDocument={reloadDocument}
73 // The same app opens in the same window, other apps in new windows
74 target={APP_NAME === appToLinkTo ? '_self' : '_blank'}
76 <ProductIcon appToLinkTo={appToLinkTo} current={current} />
88 export const UnAuthenticatedAppsDropdown = AppsDropdown;
90 const AuthenticatedAppsDropdown = forwardRef<HTMLButtonElement, AppsDropdownProps>(
91 (props: AppsDropdownProps, ref: ForwardedRef<HTMLButtonElement>) => {
92 const [user] = useUser();
93 const { APP_NAME } = useConfig();
94 const isInboxCustomAppSwitcher = useFlag('InboxDesktopWinLinNewAppSwitcher');
96 // The app swicher on Mail, Calendar and account desktop application is different
97 if (isElectronOnInboxApps(APP_NAME) && (isElectronOnMac || (isInboxCustomAppSwitcher && isElectronMail))) {
98 return <InboxDesktopAppSwitcher appToLinkTo={props.app} />;
101 return <AppsDropdown ref={ref} {...props} user={user} />;
105 export default AuthenticatedAppsDropdown;