From 43b10cb00c651eb7e928ebd710ee1473b484f3b1 Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Thu, 25 Jan 2024 18:34:19 +0100 Subject: [PATCH] Add record chip for sender and add receivers (#3629) * Add record chip for sender and add receivers * Build enum for roles * Rename var and use string literal --------- Co-authored-by: Thomas Trompette --- .../emails/components/EmailThreadMessage.tsx | 41 ++++-------------- .../EmailThreadMessageReceivers.tsx | 33 +++++++++++++++ .../components/EmailThreadMessageSender.tsx | 42 ++++++++++++++----- .../emails/types/EmailParticipantRole.ts | 1 + .../types/EmailThreadMessageParticipant.ts | 3 +- .../utils/getDisplayNameFromParticipant.ts | 35 ++++++++++++++++ 6 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageReceivers.tsx create mode 100644 packages/twenty-front/src/modules/activities/emails/types/EmailParticipantRole.ts create mode 100644 packages/twenty-front/src/modules/activities/emails/utils/getDisplayNameFromParticipant.ts diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessage.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessage.tsx index dd179fba1..55532393b 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessage.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessage.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { EmailThreadMessageBody } from '@/activities/emails/components/EmailThreadMessageBody'; import { EmailThreadMessageBodyPreview } from '@/activities/emails/components/EmailThreadMessageBodyPreview'; +import { EmailThreadMessageReceivers } from '@/activities/emails/components/EmailThreadMessageReceivers'; import { EmailThreadMessageSender } from '@/activities/emails/components/EmailThreadMessageSender'; import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; @@ -27,28 +28,6 @@ type EmailThreadMessageProps = { participants: EmailThreadMessageParticipant[]; }; -const getDisplayNameFromParticipant = ( - participant: EmailThreadMessageParticipant, -) => { - if (participant.person) { - return `${participant.person?.name?.firstName} ${participant.person?.name?.lastName}`; - } - - if (participant.workspaceMember) { - return `${participant.workspaceMember?.name?.firstName} ${participant.workspaceMember?.name?.lastName}`; - } - - if (participant.displayName) { - return participant.displayName; - } - - if (participant.handle) { - return participant.handle; - } - - return 'Unknown'; -}; - export const EmailThreadMessage = ({ body, sentAt, @@ -57,25 +36,19 @@ export const EmailThreadMessage = ({ const [isOpen, setIsOpen] = useState(false); const from = participants.find((participant) => participant.role === 'from'); - const to = participants.filter((participant) => participant.role === 'to'); + const receivers = participants.filter( + (participant) => participant.role !== 'from', + ); - if (!from || to.length === 0) { + if (!from || receivers.length === 0) { return null; } - const displayName = getDisplayNameFromParticipant(from); - - const avatarUrl = - from.person?.avatarUrl ?? from.workspaceMember?.avatarUrl ?? ''; - return ( setIsOpen(!isOpen)}> - + + {isOpen && } {isOpen ? ( diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageReceivers.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageReceivers.tsx new file mode 100644 index 000000000..fd2f879a4 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageReceivers.tsx @@ -0,0 +1,33 @@ +import styled from '@emotion/styled'; + +import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; +import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant'; +import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip'; + +type EmailThreadMessageReceiversProps = { + receivers: EmailThreadMessageParticipant[]; +}; + +const StyledThreadMessageReceivers = styled.span` + color: ${({ theme }) => theme.font.color.tertiary}; + display: flex; + font-size: ${({ theme }) => theme.font.size.xs}; + padding: ${({ theme }) => theme.spacing(2, 0, 0, 1)}; + width: 50%; +`; + +export const EmailThreadMessageReceivers = ({ + receivers, +}: EmailThreadMessageReceiversProps) => { + const displayedReceivers = receivers + .map((receiver) => getDisplayNameFromParticipant({ participant: receiver })) + .join(', '); + + const body = `to: ${displayedReceivers}`; + + return ( + + + + ); +}; diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx index 0ebe0d66f..cb54fc90c 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx @@ -1,6 +1,10 @@ import React from 'react'; import styled from '@emotion/styled'; +import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; +import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { RecordChip } from '@/object-record/components/RecordChip'; import { Avatar } from '@/users/components/Avatar'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; @@ -32,26 +36,42 @@ const StyledThreadMessageSentAt = styled.div` `; type EmailThreadMessageSenderProps = { - displayName: string; - avatarUrl: string; + sender: EmailThreadMessageParticipant; sentAt: string; }; export const EmailThreadMessageSender = ({ - displayName, - avatarUrl, + sender, sentAt, }: EmailThreadMessageSenderProps) => { + const { person, workspaceMember } = sender; + + const displayName = getDisplayNameFromParticipant({ + participant: sender, + shouldUseFullName: true, + }); + + const avatarUrl = person?.avatarUrl ?? workspaceMember?.avatarUrl ?? ''; + return ( - - {displayName} + {person ? ( + + ) : ( + <> + + {displayName} + + )} {beautifyPastDateRelativeToNow(sentAt)} diff --git a/packages/twenty-front/src/modules/activities/emails/types/EmailParticipantRole.ts b/packages/twenty-front/src/modules/activities/emails/types/EmailParticipantRole.ts new file mode 100644 index 000000000..f852b3ac0 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/types/EmailParticipantRole.ts @@ -0,0 +1 @@ +export type EmailParticipantRole = 'from' | 'to' | 'cc' | 'bcc'; diff --git a/packages/twenty-front/src/modules/activities/emails/types/EmailThreadMessageParticipant.ts b/packages/twenty-front/src/modules/activities/emails/types/EmailThreadMessageParticipant.ts index 8f1367f54..ed81fa848 100644 --- a/packages/twenty-front/src/modules/activities/emails/types/EmailThreadMessageParticipant.ts +++ b/packages/twenty-front/src/modules/activities/emails/types/EmailThreadMessageParticipant.ts @@ -1,10 +1,11 @@ +import { EmailParticipantRole } from '@/activities/emails/types/EmailParticipantRole'; import { Person } from '@/people/types/Person'; import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; export type EmailThreadMessageParticipant = { displayName: string; handle: string; - role: string; + role: EmailParticipantRole; person: Person; workspaceMember: WorkspaceMember; }; diff --git a/packages/twenty-front/src/modules/activities/emails/utils/getDisplayNameFromParticipant.ts b/packages/twenty-front/src/modules/activities/emails/utils/getDisplayNameFromParticipant.ts new file mode 100644 index 000000000..8735711c2 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/utils/getDisplayNameFromParticipant.ts @@ -0,0 +1,35 @@ +import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; + +export const getDisplayNameFromParticipant = ({ + participant, + shouldUseFullName = false, +}: { + participant: EmailThreadMessageParticipant; + shouldUseFullName?: boolean; +}) => { + if (participant.person) { + return ( + `${participant.person?.name?.firstName}` + + (shouldUseFullName ? ` ${participant.person?.name?.lastName}` : '') + ); + } + + if (participant.workspaceMember) { + return ( + participant.workspaceMember?.name?.firstName + + (shouldUseFullName + ? ` ${participant.workspaceMember?.name?.lastName}` + : '') + ); + } + + if (participant.displayName) { + return participant.displayName; + } + + if (participant.handle) { + return participant.handle; + } + + return 'Unknown'; +};