feat: move support links to workspace switcher (#16653)
## Summary Move the Support and Documentation links from the bottom left navigation drawer to the workspace switcher dropdown menu. ## Changes - **Workspace Switcher**: Added Support (conditional) and Documentation links before Log out - **Settings Navigation**: Added Support and Documentation links in the Other section - **Support visibility**: Support link only appears when FrontChat is configured (not waiting for script to load) - **FrontChat loading**: Created `SupportChatEffect` component to ensure FrontChat script loads at app startup for popup notifications - **Bug fix**: Fixed settings navigation items without a path appearing highlighted - **Cleanup**: Removed unused `SupportDropdown`, `SupportButton`, and `SupportButtonSkeletonLoader` components - **Hidden**: Temporarily commented out Integrations page ## Screenshots The Support and Documentation links now appear in: 1. Workspace switcher dropdown (top left) 2. Settings navigation (Other section)
This commit is contained in:
@@ -21,6 +21,7 @@ import { BaseThemeProvider } from '@/ui/theme/components/BaseThemeProvider';
|
||||
import { UserThemeProviderEffect } from '@/ui/theme/components/UserThemeProviderEffect';
|
||||
import { PageFavicon } from '@/ui/utilities/page-favicon/components/PageFavicon';
|
||||
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
|
||||
import { SupportChatEffect } from '@/support/components/SupportChatEffect';
|
||||
import { UserAndViewsProviderEffect } from '@/users/components/UserAndViewsProviderEffect';
|
||||
import { UserProvider } from '@/users/components/UserProvider';
|
||||
import { WorkspaceProviderEffect } from '@/workspace/components/WorkspaceProviderEffect';
|
||||
@@ -66,6 +67,7 @@ export const AppRouterProviders = () => {
|
||||
</DialogComponentInstanceContext.Provider>
|
||||
</SnackBarProvider>
|
||||
<MainContextStoreProvider />
|
||||
<SupportChatEffect />
|
||||
</PrefetchDataProvider>
|
||||
<PageChangeEffect />
|
||||
</ObjectMetadataItemsProvider>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { FavoritesFolderContent } from '@/favorites/components/FavoritesFolderCo
|
||||
import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder';
|
||||
import { MainNavigationDrawerFixedItems } from '@/navigation/components/MainNavigationDrawerFixedItems';
|
||||
import { MainNavigationDrawerScrollableItems } from '@/navigation/components/MainNavigationDrawerScrollableItems';
|
||||
import { SupportDropdown } from '@/support/components/SupportDropdown';
|
||||
import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
|
||||
import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent';
|
||||
import { NavigationDrawerScrollableContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerScrollableContent';
|
||||
@@ -39,10 +38,6 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => {
|
||||
<MainNavigationDrawerScrollableItems />
|
||||
)}
|
||||
</NavigationDrawerScrollableContent>
|
||||
|
||||
<NavigationDrawerFixedContent>
|
||||
<SupportDropdown />
|
||||
</NavigationDrawerFixedContent>
|
||||
</NavigationDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ export const SettingsNavigationDrawerItem = ({
|
||||
end: item.matchSubPages === false,
|
||||
});
|
||||
|
||||
const isActive = !!matchResult && !hasActiveSubItem;
|
||||
const isActive = !!item.path && !!matchResult && !hasActiveSubItem;
|
||||
|
||||
if (isDefined(item.isHidden) && item.isHidden) {
|
||||
return null;
|
||||
@@ -37,7 +37,7 @@ export const SettingsNavigationDrawerItem = ({
|
||||
indentationLevel={item.indentationLevel}
|
||||
subItemState={subItemState}
|
||||
label={item.label}
|
||||
to={href}
|
||||
to={href || undefined}
|
||||
Icon={item.Icon}
|
||||
active={isActive}
|
||||
soon={item.soon}
|
||||
@@ -53,7 +53,7 @@ export const SettingsNavigationDrawerItem = ({
|
||||
indentationLevel={item.indentationLevel}
|
||||
subItemState={subItemState}
|
||||
label={item.label}
|
||||
to={href}
|
||||
to={href || undefined}
|
||||
Icon={item.Icon}
|
||||
active={isActive}
|
||||
soon={item.soon}
|
||||
|
||||
@@ -2,25 +2,32 @@ import { SettingsPath } from 'twenty-shared/types';
|
||||
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap';
|
||||
import { getDocumentationUrl } from '@/support/utils/getDocumentationUrl';
|
||||
import { type NavigationDrawerItemIndentationLevel } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import {
|
||||
IconApi,
|
||||
IconApps,
|
||||
// IconApps, // TODO: Re-enable when integrations page is ready
|
||||
IconAt,
|
||||
IconCalendarEvent,
|
||||
IconColorSwatch,
|
||||
type IconComponent,
|
||||
IconCurrencyDollar,
|
||||
IconDoorEnter,
|
||||
IconHelpCircle,
|
||||
IconHierarchy2,
|
||||
IconKey,
|
||||
IconLock,
|
||||
IconMail,
|
||||
IconMessage,
|
||||
IconPlug,
|
||||
IconRocket,
|
||||
IconServer,
|
||||
IconSettings,
|
||||
@@ -28,7 +35,6 @@ import {
|
||||
IconUserCircle,
|
||||
IconUsers,
|
||||
IconWorld,
|
||||
IconPlug,
|
||||
} from 'twenty-ui/display';
|
||||
import { FeatureFlagKey, PermissionFlagType } from '~/generated/graphql';
|
||||
|
||||
@@ -55,6 +61,8 @@ export type SettingsNavigationItem = {
|
||||
const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
const billing = useRecoilValue(billingState);
|
||||
const { signOut } = useAuth();
|
||||
const supportChat = useRecoilValue(supportChatState);
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
|
||||
const isBillingEnabled = billing?.isBillingEnabled ?? false;
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
@@ -65,6 +73,9 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
const isApplicationEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_APPLICATION_ENABLED,
|
||||
);
|
||||
const isSupportChatConfigured =
|
||||
supportChat?.supportDriver === 'FRONT' &&
|
||||
isNonEmptyString(supportChat.supportFrontChatId);
|
||||
|
||||
const permissionMap = usePermissionFlagMap();
|
||||
return [
|
||||
@@ -148,12 +159,13 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
Icon: IconApi,
|
||||
isHidden: !permissionMap[PermissionFlagType.API_KEYS_AND_WEBHOOKS],
|
||||
},
|
||||
{
|
||||
label: t`Integrations`,
|
||||
path: SettingsPath.Integrations,
|
||||
Icon: IconApps,
|
||||
isHidden: !permissionMap[PermissionFlagType.API_KEYS_AND_WEBHOOKS],
|
||||
},
|
||||
// TODO: Re-enable when integrations page is ready
|
||||
// {
|
||||
// label: t`Integrations`,
|
||||
// path: SettingsPath.Integrations,
|
||||
// Icon: IconApps,
|
||||
// isHidden: !permissionMap[PermissionFlagType.API_KEYS_AND_WEBHOOKS],
|
||||
// },
|
||||
{
|
||||
label: t`Applications`,
|
||||
path: SettingsPath.Applications,
|
||||
@@ -195,6 +207,21 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
Icon: IconRocket,
|
||||
isHidden: !permissionMap[PermissionFlagType.WORKSPACE],
|
||||
},
|
||||
{
|
||||
label: t`Support`,
|
||||
onClick: () => window.FrontChat?.('show'),
|
||||
Icon: IconMessage,
|
||||
isHidden: !isSupportChatConfigured,
|
||||
},
|
||||
{
|
||||
label: t`Documentation`,
|
||||
onClick: () =>
|
||||
window.open(
|
||||
getDocumentationUrl(currentWorkspaceMember?.locale),
|
||||
'_blank',
|
||||
),
|
||||
Icon: IconHelpCircle,
|
||||
},
|
||||
{
|
||||
label: t`Logout`,
|
||||
onClick: signOut,
|
||||
|
||||
-5
@@ -1,6 +1,4 @@
|
||||
import { SupportDropdown } from '@/support/components/SupportDropdown';
|
||||
import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
|
||||
import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent';
|
||||
|
||||
import { NavigationDrawerSectionForObjectMetadataItems } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
@@ -63,9 +61,6 @@ export const SignInAppNavigationDrawerMock = ({
|
||||
WORKSPACE_FAVORITES.includes(item.nameSingular),
|
||||
)}
|
||||
/>
|
||||
<NavigationDrawerFixedContent>
|
||||
<SupportDropdown />
|
||||
</NavigationDrawerFixedContent>
|
||||
</NavigationDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { SupportButtonSkeletonLoader } from '@/support/components/SupportButtonSkeletonLoader';
|
||||
import { useSupportChat } from '@/support/hooks/useSupportChat';
|
||||
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconHelpCircle } from 'twenty-ui/display';
|
||||
import { Button, LightIconButton } from 'twenty-ui/input';
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const SupportButton = () => {
|
||||
const { loading, isFrontChatLoaded } = useSupportChat();
|
||||
|
||||
const isNavigationDrawerExpanded = useRecoilValue(
|
||||
isNavigationDrawerExpandedState,
|
||||
);
|
||||
if (loading) {
|
||||
return <SupportButtonSkeletonLoader />;
|
||||
}
|
||||
|
||||
if (!isFrontChatLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
return isNavigationDrawerExpanded ? (
|
||||
<StyledButtonContainer>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
title={t`Support`}
|
||||
Icon={IconHelpCircle}
|
||||
/>
|
||||
</StyledButtonContainer>
|
||||
) : (
|
||||
<LightIconButton Icon={IconHelpCircle} />
|
||||
);
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
export const SupportButtonSkeletonLoader = () => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton width={84} height={SKELETON_LOADER_HEIGHT_SIZES.standard.m} />
|
||||
</SkeletonTheme>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { useSupportChat } from '@/support/hooks/useSupportChat';
|
||||
|
||||
export const SupportChatEffect = () => {
|
||||
useSupportChat();
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
import { SupportButton } from '@/support/components/SupportButton';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconHelpCircle, IconMessage } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
export const SupportDropdown = () => {
|
||||
const dropdownId = `support-field-active-action-dropdown`;
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const handleTalkToUs = () => {
|
||||
window.FrontChat?.('show');
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
|
||||
const handleUserGuide = () => {
|
||||
window.open('https://docs.twenty.com/user-guide/introduction', '_blank');
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownPlacement="top-start"
|
||||
dropdownOffset={{ x: 0, y: -28 }}
|
||||
clickableComponent={<SupportButton />}
|
||||
dropdownComponents={
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.Narrow}>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
text={t`Talk to us`}
|
||||
LeftIcon={IconMessage}
|
||||
onClick={handleTalkToUs}
|
||||
/>
|
||||
<MenuItem
|
||||
text={t`Documentation`}
|
||||
LeftIcon={IconHelpCircle}
|
||||
onClick={handleUserGuide}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
import { type Meta, type StoryObj } from '@storybook/react';
|
||||
import { expect, userEvent, within } from '@storybook/test';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import {
|
||||
mockCurrentWorkspace,
|
||||
mockedUserData,
|
||||
mockedWorkspaceMemberData,
|
||||
} from '~/testing/mock-data/users';
|
||||
|
||||
import { SupportDropdown } from '@/support/components/SupportDropdown';
|
||||
import { SupportDriver } from '~/generated-metadata/graphql';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { PrefetchLoadedDecorator } from '~/testing/decorators/PrefetchLoadedDecorator';
|
||||
|
||||
const meta: Meta<typeof SupportDropdown> = {
|
||||
title: 'Modules/Support/SupportDropdown',
|
||||
component: SupportDropdown,
|
||||
decorators: [
|
||||
I18nFrontDecorator,
|
||||
(Story) => {
|
||||
const setCurrentUser = useSetRecoilState(currentUserState);
|
||||
const setSupportChat = useSetRecoilState(supportChatState);
|
||||
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
|
||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
);
|
||||
|
||||
setCurrentWorkspace(mockCurrentWorkspace);
|
||||
setCurrentWorkspaceMember(mockedWorkspaceMemberData);
|
||||
setCurrentUser(mockedUserData);
|
||||
setSupportChat({
|
||||
supportDriver: SupportDriver.FRONT,
|
||||
supportFrontChatId: '1234',
|
||||
});
|
||||
|
||||
return <Story />;
|
||||
},
|
||||
PrefetchLoadedDecorator,
|
||||
],
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof SupportDropdown>;
|
||||
|
||||
export const Default: Story = {
|
||||
play: async () => {
|
||||
const canvas = within(document.body);
|
||||
|
||||
expect(await canvas.findByText('Support')).toBeInTheDocument();
|
||||
await userEvent.click(canvas.getByText('Support'));
|
||||
|
||||
// Add delay to account for the timeout in useSupportChat
|
||||
await new Promise((resolve) => setTimeout(resolve, 600));
|
||||
|
||||
expect(await canvas.findByText('Documentation')).toBeInTheDocument();
|
||||
expect(await canvas.findByText('Talk to us')).toBeInTheDocument();
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
const DOCUMENTATION_BASE_URL = 'https://docs.twenty.com';
|
||||
const DOCUMENTATION_PATH = '/user-guide/introduction';
|
||||
|
||||
// Locales that have documentation translations available
|
||||
const SUPPORTED_DOC_LOCALES = ['fr', 'pt', 'de', 'es', 'it', 'ja', 'ko', 'zh'];
|
||||
|
||||
export const getDocumentationUrl = (locale?: string | null): string => {
|
||||
if (!locale) {
|
||||
return `${DOCUMENTATION_BASE_URL}${DOCUMENTATION_PATH}`;
|
||||
}
|
||||
|
||||
// Extract language code from locale (e.g., 'fr' from 'fr-FR')
|
||||
const langCode = locale.split('-')[0].toLowerCase();
|
||||
|
||||
if (SUPPORTED_DOC_LOCALES.includes(langCode)) {
|
||||
return `${DOCUMENTATION_BASE_URL}/l/${langCode}${DOCUMENTATION_PATH}`;
|
||||
}
|
||||
|
||||
return `${DOCUMENTATION_BASE_URL}${DOCUMENTATION_PATH}`;
|
||||
};
|
||||
+33
@@ -2,10 +2,13 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
|
||||
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { availableWorkspacesState } from '@/auth/states/availableWorkspacesState';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { countAvailableWorkspaces } from '@/auth/utils/availableWorkspacesUtils';
|
||||
import { useBuildWorkspaceUrl } from '@/domain-manager/hooks/useBuildWorkspaceUrl';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { getDocumentationUrl } from '@/support/utils/getDocumentationUrl';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
@@ -19,6 +22,7 @@ import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/s
|
||||
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
|
||||
import { type ApolloError } from '@apollo/client';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { AppPath, SettingsPath } from 'twenty-shared/types';
|
||||
@@ -26,7 +30,9 @@ import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import {
|
||||
Avatar,
|
||||
IconDotsVertical,
|
||||
IconHelpCircle,
|
||||
IconLogout,
|
||||
IconMessage,
|
||||
IconPlus,
|
||||
IconSwitchHorizontal,
|
||||
IconUserPlus,
|
||||
@@ -50,6 +56,7 @@ const StyledDescription = styled.div`
|
||||
|
||||
export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
const { t } = useLingui();
|
||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||
const availableWorkspaces = useRecoilValue(availableWorkspacesState);
|
||||
@@ -60,6 +67,10 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
const { signOut } = useAuth();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { colorScheme, colorSchemeList } = useColorScheme();
|
||||
const supportChat = useRecoilValue(supportChatState);
|
||||
const isSupportChatConfigured =
|
||||
supportChat?.supportDriver === 'FRONT' &&
|
||||
isNonEmptyString(supportChat.supportFrontChatId);
|
||||
|
||||
const [signUpInNewWorkspaceMutation] = useSignUpInNewWorkspaceMutation();
|
||||
|
||||
@@ -67,6 +78,16 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
multiWorkspaceDropdownState,
|
||||
);
|
||||
|
||||
const handleSupport = () => {
|
||||
window.FrontChat?.('show');
|
||||
closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
|
||||
};
|
||||
|
||||
const handleDocumentation = () => {
|
||||
window.open(getDocumentationUrl(currentWorkspaceMember?.locale), '_blank');
|
||||
closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
|
||||
};
|
||||
|
||||
const handleChange = async (availableWorkspace: AvailableWorkspace) => {
|
||||
redirectToWorkspaceDomain(
|
||||
getWorkspaceUrl(availableWorkspace.workspaceUrls),
|
||||
@@ -200,6 +221,18 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
>
|
||||
<MenuItem LeftIcon={IconUserPlus} text={t`Invite user`} />
|
||||
</UndecoratedLink>
|
||||
{isSupportChatConfigured && (
|
||||
<MenuItem
|
||||
LeftIcon={IconMessage}
|
||||
text={t`Support`}
|
||||
onClick={handleSupport}
|
||||
/>
|
||||
)}
|
||||
<MenuItem
|
||||
LeftIcon={IconHelpCircle}
|
||||
text={t`Documentation`}
|
||||
onClick={handleDocumentation}
|
||||
/>
|
||||
<MenuItem LeftIcon={IconLogout} text={t`Log out`} onClick={signOut} />
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
|
||||
Reference in New Issue
Block a user