From fb8d19323857c25fc82899a9c9808b8f2b3622d1 Mon Sep 17 00:00:00 2001 From: Murali Singh <68021313+muraliSingh7@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:12:06 +0530 Subject: [PATCH] Fix: Replace styled logo with Avatar component for workspace logo in NavigationDrawerHeader (#9093) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Co-authored-by: FĂ©lix Malfait Co-authored-by: Charles Bochet --- .../MultiWorkspaceDropdownButton.tsx | 32 ++++--------------- .../components/NavigationDrawerHeader.tsx | 18 +++-------- .../page-favicon/components/PageFavicon.tsx | 3 +- .../src/display/avatar/components/Avatar.tsx | 6 ++-- 4 files changed, 15 insertions(+), 44 deletions(-) diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx index fd8f69afd9..7d7f718f56 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx @@ -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} > - {currentWorkspace?.displayName ?? ''} @@ -135,13 +121,9 @@ export const MultiWorkspaceDropdownButton = ({ } selected={currentWorkspace?.id === workspace.id} diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx index 4d7bf0fa47..decd0475aa 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx @@ -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 = ({ ) : ( - + {name} diff --git a/packages/twenty-front/src/modules/ui/utilities/page-favicon/components/PageFavicon.tsx b/packages/twenty-front/src/modules/ui/utilities/page-favicon/components/PageFavicon.tsx index e72ff93a7d..dd7b5d8ece 100644 --- a/packages/twenty-front/src/modules/ui/utilities/page-favicon/components/PageFavicon.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/page-favicon/components/PageFavicon.tsx @@ -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 } /> )} diff --git a/packages/twenty-ui/src/display/avatar/components/Avatar.tsx b/packages/twenty-ui/src/display/avatar/components/Avatar.tsx index 35941629b6..0f17ca9edf 100644 --- a/packages/twenty-ui/src/display/avatar/components/Avatar.tsx +++ b/packages/twenty-ui/src/display/avatar/components/Avatar.tsx @@ -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)) {