Fix count avatar color + align thread preview items (#3695)

Fix count avatar and align items

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette 2024-01-30 15:01:12 +01:00 committed by GitHub
parent 84b6bea2b9
commit 511627ccb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 56 additions and 48 deletions

View File

@ -77,7 +77,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
<Avatar
avatarUrl={avatarUrl}
size="md"
colorId={author?.id}
entityId={author?.id}
placeholder={authorName}
/>
<StyledName>{authorName}</StyledName>

View File

@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { grayScale } from '@/ui/theme/constants/colors';
import { Avatar } from '@/users/components/Avatar';
import { TimelineThread } from '~/generated/graphql';
import { formatToHumanReadableDate } from '~/utils';
@ -15,29 +16,17 @@ const StyledCardContent = styled(CardContent)`
`;
const StyledHeading = styled.div<{ unread: boolean }>`
align-items: center;
display: flex;
color: ${({ theme, unread }) =>
unread ? theme.font.color.primary : theme.font.color.secondary};
display: flex;
font-weight: ${({ theme, unread }) =>
unread ? theme.font.weight.medium : theme.font.weight.regular};
gap: ${({ theme }) => theme.spacing(1)};
overflow: hidden;
width: 160px;
:before {
background-color: ${({ theme, unread }) =>
unread ? theme.color.blue : 'transparent'};
border-radius: ${({ theme }) => theme.border.radius.rounded};
content: '';
display: block;
height: 6px;
width: 6px;
}
width: 20%;
`;
const StyledParticipantsContainer = styled.div`
align-items: center;
align-items: flex-start;
display: flex;
`;
@ -46,6 +35,7 @@ const StyledAvatar = styled(Avatar)`
`;
const StyledSenderNames = styled.span`
display: flex;
margin: ${({ theme }) => theme.spacing(0, 1)};
overflow: hidden;
text-overflow: ellipsis;
@ -56,26 +46,27 @@ const StyledThreadCount = styled.span`
color: ${({ theme }) => theme.font.color.tertiary};
`;
const StyledSubject = styled.span<{ unread: boolean }>`
color: ${({ theme, unread }) =>
unread ? theme.font.color.primary : theme.font.color.secondary};
white-space: nowrap;
`;
const StyledBody = styled.span`
color: ${({ theme }) => theme.font.color.tertiary};
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledSubjectAndBody = styled.div`
display: flex;
flex: 1;
gap: ${({ theme }) => theme.spacing(2)};
overflow: hidden;
`;
const StyledSubject = styled.span<{ unread: boolean }>`
color: ${({ theme, unread }) =>
unread ? theme.font.color.primary : theme.font.color.secondary};
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0;
`;
const StyledBody = styled.span`
color: ${({ theme }) => theme.font.color.tertiary};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledReceivedAt = styled.div`
@ -104,12 +95,13 @@ export const EmailThreadPreview = ({
? `, ${thread.lastTwoParticipants?.[1]?.displayName}`
: '');
const [finalDisplayedName, finalAvatarUrl] =
const [finalDisplayedName, finalAvatarUrl, isCountIcon] =
thread.participantCount > 3
? [`${thread.participantCount}`, '']
? [`${thread.participantCount}`, '', true]
: [
thread?.lastTwoParticipants?.[1]?.displayName,
thread?.lastTwoParticipants?.[1]?.avatarUrl,
false,
];
return (
@ -133,6 +125,8 @@ export const EmailThreadPreview = ({
avatarUrl={finalAvatarUrl}
placeholder={finalDisplayedName}
type="rounded"
color={isCountIcon ? grayScale.gray50 : undefined}
backgroundColor={isCountIcon ? grayScale.gray10 : undefined}
/>
)}
</StyledParticipantsContainer>

View File

@ -328,7 +328,7 @@ export const CommandMenu = () => {
<Avatar
type="rounded"
avatarUrl={null}
colorId={person.id}
entityId={person.id}
placeholder={
person.name.firstName +
' ' +
@ -350,7 +350,7 @@ export const CommandMenu = () => {
to={`object/company/${company.id}`}
Icon={() => (
<Avatar
colorId={company.id}
entityId={company.id}
placeholder={company.name}
avatarUrl={getLogoUrlFromDomainName(
company.domainName,

View File

@ -46,7 +46,7 @@ export const Favorites = () => {
label={labelIdentifier}
Icon={() => (
<Avatar
colorId={recordId}
entityId={recordId}
avatarUrl={avatarUrl}
type={avatarType}
placeholder={labelIdentifier}

View File

@ -43,7 +43,7 @@ export const MultipleObjectRecordSelectItem = ({
avatar={
<Avatar
avatarUrl={objectRecordForSelect.recordIdentifier.avatarUrl}
colorId={objectRecordForSelect.record.id}
entityId={objectRecordForSelect.record.id}
placeholder={objectRecordForSelect.recordIdentifier.name}
size="md"
type={

View File

@ -40,7 +40,7 @@ export const SelectableMenuItemSelect = ({
avatar={
<Avatar
avatarUrl={entity.avatarUrl}
colorId={entity.id}
entityId={entity.id}
placeholder={entity.name}
size="md"
type={entity.avatarType ?? 'rounded'}

View File

@ -69,7 +69,7 @@ export const MultipleRecordSelectDropdown = ({
avatar={
<Avatar
avatarUrl={record.avatarUrl}
colorId={record.id}
entityId={record.id}
placeholder={record.name}
size="md"
type={record.avatarType ?? 'rounded'}

View File

@ -64,7 +64,7 @@ export const EntityChip = ({
) : (
<Avatar
avatarUrl={avatarUrl}
colorId={entityId}
entityId={entityId}
placeholder={name}
size="sm"
type={avatarType}

View File

@ -99,7 +99,7 @@ export const ShowPageSummaryCard = ({
avatarUrl={logoOrAvatar}
onClick={onUploadPicture ? handleAvatarClick : undefined}
size="xl"
colorId={id}
entityId={id}
placeholder={avatarPlaceholder}
type={avatarType}
/>

View File

@ -16,21 +16,24 @@ export type AvatarProps = {
className?: string;
size?: AvatarSize;
placeholder: string | undefined;
colorId?: string;
entityId?: string;
type?: Nullable<AvatarType>;
color?: string;
backgroundColor?: string;
onClick?: () => void;
};
const StyledAvatar = styled.div<AvatarProps & { colorId: string }>`
export const StyledAvatar = styled.div<
AvatarProps & { color: string; backgroundColor: string }
>`
align-items: center;
background-color: ${({ avatarUrl, colorId }) =>
!isNonEmptyString(avatarUrl) ? stringToHslColor(colorId, 75, 85) : 'none'};
background-color: ${({ backgroundColor }) => backgroundColor};
${({ avatarUrl }) =>
isNonEmptyString(avatarUrl) ? `background-image: url(${avatarUrl});` : ''}
background-position: center;
background-size: cover;
border-radius: ${(props) => (props.type === 'rounded' ? '50%' : '2px')};
color: ${({ colorId }) => stringToHslColor(colorId, 75, 25)};
color: ${({ color }) => color};
cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
display: flex;
@ -95,9 +98,11 @@ export const Avatar = ({
className,
size = 'md',
placeholder,
colorId = placeholder,
entityId = placeholder,
onClick,
type = 'squared',
color,
backgroundColor,
}: AvatarProps) => {
const noAvatarUrl = !isNonEmptyString(avatarUrl);
const [isInvalidAvatarUrl, setIsInvalidAvatarUrl] = useState(false);
@ -114,6 +119,13 @@ export const Avatar = ({
}
}, [avatarUrl]);
const fixedColor = color ?? stringToHslColor(entityId ?? '', 75, 25);
const fixedBackgroundColor =
backgroundColor ??
(!isNonEmptyString(avatarUrl)
? stringToHslColor(entityId ?? '', 75, 85)
: 'none');
return (
<StyledAvatar
className={className}
@ -121,8 +133,10 @@ export const Avatar = ({
placeholder={placeholder}
size={size}
type={type}
colorId={colorId ?? ''}
entityId={entityId}
onClick={onClick}
color={fixedColor}
backgroundColor={fixedBackgroundColor}
>
{(noAvatarUrl || isInvalidAvatarUrl) &&
placeholder?.[0]?.toLocaleUpperCase()}

View File

@ -40,7 +40,7 @@ export const WorkspaceMemberCard = ({
<StyledContainer>
<Avatar
avatarUrl={workspaceMember.avatarUrl}
colorId={workspaceMember.id}
entityId={workspaceMember.id}
placeholder={workspaceMember.name.firstName || ''}
type="squared"
size="xl"