Fix: Replace styled logo with Avatar component for workspace logo in NavigationDrawerHeader (#9093)

This PR addresses issue #9042

- Replaced the styled logo with the `Avatar` component.
- `Avatar` now handles the case when no `logo` is uploaded by using the
workspace name's first character as the `placeholder`.
- This ensures a consistent fallback when the `logo` is undefined.

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Murali Singh 2024-12-18 01:12:06 +05:30 committed by GitHub
parent 07bde4883e
commit fb8d193238
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 15 additions and 44 deletions

View File

@ -14,22 +14,12 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { getImageAbsoluteURI } from 'twenty-shared';
import {
Avatar,
IconChevronDown,
MenuItemSelectAvatar,
UndecoratedLink,
} from 'twenty-ui';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
const StyledLogo = styled.div<{ logo: string }>`
background: url(${({ logo }) => logo});
background-position: center;
background-size: cover;
border-radius: ${({ theme }) => theme.border.radius.xs};
height: 16px;
width: 16px;
`;
const StyledContainer = styled.div<{ isNavigationDrawerExpanded: boolean }>`
align-items: center;
@ -102,13 +92,9 @@ export const MultiWorkspaceDropdownButton = ({
data-testid="workspace-dropdown"
isNavigationDrawerExpanded={isNavigationDrawerExpanded}
>
<StyledLogo
logo={
getImageAbsoluteURI({
imageUrl: currentWorkspace?.logo ?? '',
baseUrl: REACT_APP_SERVER_BASE_URL,
}) ?? ''
}
<Avatar
placeholder={currentWorkspace?.displayName || ''}
avatarUrl={currentWorkspace?.logo ?? DEFAULT_WORKSPACE_LOGO}
/>
<NavigationDrawerAnimatedCollapseWrapper>
<StyledLabel>{currentWorkspace?.displayName ?? ''}</StyledLabel>
@ -135,13 +121,9 @@ export const MultiWorkspaceDropdownButton = ({
<MenuItemSelectAvatar
text={workspace.displayName ?? '(No name)'}
avatar={
<StyledLogo
logo={
getImageAbsoluteURI({
imageUrl: workspace.logo ?? DEFAULT_WORKSPACE_LOGO,
baseUrl: REACT_APP_SERVER_BASE_URL,
}) ?? ''
}
<Avatar
placeholder={workspace.displayName || ''}
avatarUrl={workspace.logo ?? DEFAULT_WORKSPACE_LOGO}
/>
}
selected={currentWorkspace?.id === workspace.id}

View File

@ -7,11 +7,11 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { isNonEmptyString } from '@sniptt/guards';
import { Avatar } from 'twenty-ui';
import { NavigationDrawerCollapseButton } from './NavigationDrawerCollapseButton';
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
const StyledContainer = styled.div`
align-items: center;
@ -19,20 +19,12 @@ const StyledContainer = styled.div`
height: ${({ theme }) => theme.spacing(8)};
user-select: none;
`;
const StyledSingleWorkspaceContainer = styled(StyledContainer)`
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(1)};
`;
const StyledLogo = styled.div<{ logo: string }>`
background: url(${({ logo }) => logo});
background-position: center;
background-size: cover;
border-radius: ${({ theme }) => theme.border.radius.xs};
height: 16px;
width: 16px;
`;
const StyledName = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-family: 'Inter';
@ -75,9 +67,7 @@ export const NavigationDrawerHeader = ({
<MultiWorkspaceDropdownButton workspaces={workspaces} />
) : (
<StyledSingleWorkspaceContainer>
<StyledLogo
logo={isNonEmptyString(logo) ? logo : DEFAULT_WORKSPACE_LOGO}
/>
<Avatar placeholder={name} avatarUrl={logo} />
<NavigationDrawerAnimatedCollapseWrapper>
<StyledName>{name}</StyledName>
</NavigationDrawerAnimatedCollapseWrapper>

View File

@ -1,4 +1,5 @@
import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState';
import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo';
import { Helmet } from 'react-helmet-async';
import { useRecoilValue } from 'recoil';
import { getImageAbsoluteURI } from 'twenty-shared';
@ -16,7 +17,7 @@ export const PageFavicon = () => {
getImageAbsoluteURI({
imageUrl: workspacePublicData.logo,
baseUrl: REACT_APP_SERVER_BASE_URL,
}) ?? ''
}) ?? DEFAULT_WORKSPACE_LOGO
}
/>
)}

View File

@ -1,5 +1,5 @@
import { styled } from '@linaria/react';
import { isNonEmptyString, isUndefined } from '@sniptt/guards';
import { isNonEmptyString, isNull, isUndefined } from '@sniptt/guards';
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
@ -90,12 +90,10 @@ export const Avatar = ({
})
: null;
const noAvatarUrl = !isNonEmptyString(avatarImageURI);
const placeholderChar = placeholder?.[0]?.toLocaleUpperCase();
const showPlaceholder =
noAvatarUrl || invalidAvatarUrls.includes(avatarImageURI);
isNull(avatarImageURI) || invalidAvatarUrls.includes(avatarImageURI);
const handleImageError = () => {
if (isNonEmptyString(avatarImageURI)) {