3263 modify timeline messagingservice to allow the frontend to get multiple participants in a thread (#3611)

* wip

* wip

* add pagination

* wip

* wip

* wip

* update resolver

* wip

* wip

* endpoint is working but there is still work to do

* merge main

* wip

* subject is now first subject

* number of messages is working

* improving query

* fix bug

* fix bug

* added parameter

* pagination introduced a bug

* pagination is working

* fix type

* improve typing

* improve typing

* fix bug

* add displayName

* display displayName in the frontend

* move entities

* fix

* generate metadata

* add avatarUrl

* modify after comments on PR

* updates

* remove email mocks

* remove console log

* move files

* remove mock

* use constant

* use constant

* use fragments

* remove console.log

* generate

* changes made

* update DTO

* generate
This commit is contained in:
bosiraphael
2024-01-25 17:04:51 +01:00
committed by GitHub
parent 6f98d1847f
commit 6004969096
19 changed files with 617 additions and 207 deletions

View File

@ -92,20 +92,22 @@ export const EmailThreadPreview = ({
<StyledCardContent onClick={() => onClick()} divider={divider}>
<StyledHeading unread={!thread.read}>
<StyledAvatar
avatarUrl={thread.senderPictureUrl}
placeholder={thread.senderName}
avatarUrl={thread.firstParticipant.avatarUrl}
placeholder={thread.firstParticipant.displayName}
type="rounded"
/>
<StyledSenderName>{thread.senderName}</StyledSenderName>
<StyledSenderName>
{thread.firstParticipant.displayName}
</StyledSenderName>
<StyledThreadCount>{thread.numberOfMessagesInThread}</StyledThreadCount>
</StyledHeading>
<StyledSubjectAndBody>
<StyledSubject unread={!thread.read}>{thread.subject}</StyledSubject>
<StyledBody>{thread.body}</StyledBody>
<StyledBody>{thread.lastMessageBody}</StyledBody>
</StyledSubjectAndBody>
<StyledReceivedAt>
{formatToHumanReadableDate(thread.receivedAt)}
{formatToHumanReadableDate(thread.lastMessageReceivedAt)}
</StyledReceivedAt>
</StyledCardContent>
);

View File

@ -2,11 +2,8 @@ import { useQuery } from '@apollo/client';
import styled from '@emotion/styled';
import { EmailThreadPreview } from '@/activities/emails/components/EmailThreadPreview';
import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from '@/activities/emails/constants/messaging.constants';
import { useEmailThread } from '@/activities/emails/hooks/useEmailThread';
import {
mockedEmailThreads,
MockedThread,
} from '@/activities/emails/mocks/mockedEmailThreads';
import { getTimelineThreadsFromCompanyId } from '@/activities/emails/queries/getTimelineThreadsFromCompanyId';
import { getTimelineThreadsFromPersonId } from '@/activities/emails/queries/getTimelineThreadsFromPersonId';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
@ -17,6 +14,7 @@ import {
} from '@/ui/display/typography/components/H1Title';
import { Card } from '@/ui/layout/card/components/Card';
import { Section } from '@/ui/layout/section/components/Section';
import { TimelineThread } from '~/generated/graphql';
const StyledContainer = styled.div`
display: flex;
@ -46,10 +44,13 @@ export const EmailThreads = ({
? getTimelineThreadsFromPersonId
: getTimelineThreadsFromCompanyId;
const threadQueryVariables =
entity.targetObjectNameSingular === CoreObjectNameSingular.Person
const threadQueryVariables = {
...(entity.targetObjectNameSingular === CoreObjectNameSingular.Person
? { personId: entity.id }
: { companyId: entity.id };
: { companyId: entity.id }),
page: 1,
pageSize: TIMELINE_THREADS_DEFAULT_PAGE_SIZE,
};
const threads = useQuery(threadQuery, {
variables: threadQueryVariables,
@ -59,16 +60,12 @@ export const EmailThreads = ({
return;
}
// To use once the id is returned by the query
// const fetchedTimelineThreads: TimelineThread[] =
// threads.data[
// entity.targetObjectNameSingular === CoreObjectNameSingular.Person
// ? 'getTimelineThreadsFromPersonId'
// : 'getTimelineThreadsFromCompanyId'
// ];
const timelineThreads = mockedEmailThreads;
const timelineThreads: TimelineThread[] =
threads.data[
entity.targetObjectNameSingular === CoreObjectNameSingular.Person
? 'getTimelineThreadsFromPersonId'
: 'getTimelineThreadsFromCompanyId'
];
return (
<StyledContainer>
@ -77,16 +74,14 @@ export const EmailThreads = ({
title={
<>
Inbox{' '}
<StyledEmailCount>
{timelineThreads && timelineThreads.length}
</StyledEmailCount>
<StyledEmailCount>{timelineThreads?.length}</StyledEmailCount>
</>
}
fontColor={H1TitleFontColor.Primary}
/>
<Card>
{timelineThreads &&
timelineThreads.map((thread: MockedThread, index: number) => (
timelineThreads.map((thread: TimelineThread, index: number) => (
<EmailThreadPreview
key={index}
divider={index < timelineThreads.length - 1}

View File

@ -0,0 +1 @@
export const TIMELINE_THREADS_DEFAULT_PAGE_SIZE = 20;

View File

@ -1,15 +1,15 @@
import { useRecoilState } from 'recoil';
import { MockedThread } from '@/activities/emails/mocks/mockedEmailThreads';
import { useOpenEmailThreadRightDrawer } from '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer';
import { viewableEmailThreadState } from '@/activities/emails/state/viewableEmailThreadState';
import { TimelineThread } from '~/generated/graphql';
export const useEmailThread = () => {
const [, setViewableEmailThread] = useRecoilState(viewableEmailThreadState);
const openEmailThredRightDrawer = useOpenEmailThreadRightDrawer();
const openEmailThread = (thread: MockedThread) => {
const openEmailThread = (thread: TimelineThread) => {
openEmailThredRightDrawer();
setViewableEmailThread(thread);

View File

@ -1,30 +0,0 @@
import { Scalars, TimelineThread } from '~/generated/graphql';
export type MockedThread = {
id: string;
} & TimelineThread;
export const mockedEmailThreads: MockedThread[] = [
{
__typename: 'TimelineThread',
id: 'ec7e12b9-4063-410f-ae9a-30e32452b9c0',
body: 'This is a test email' as Scalars['String'],
numberOfMessagesInThread: 5 as Scalars['Float'],
read: true as Scalars['Boolean'],
receivedAt: new Date().toISOString() as Scalars['DateTime'],
senderName: 'Thom Trp' as Scalars['String'],
senderPictureUrl: '' as Scalars['String'],
subject: 'Test email' as Scalars['String'],
},
{
__typename: 'TimelineThread',
id: 'ec7e12b9-4063-410f-ae9a-30e32452b9c0',
body: 'This is a second test email' as Scalars['String'],
numberOfMessagesInThread: 5 as Scalars['Float'],
read: true as Scalars['Boolean'],
receivedAt: new Date().toISOString() as Scalars['DateTime'],
senderName: 'Coco Den' as Scalars['String'],
senderPictureUrl: '' as Scalars['String'],
subject: 'Test email number 2' as Scalars['String'],
},
];

View File

@ -0,0 +1,13 @@
import { gql } from '@apollo/client';
export const participantFragment = gql`
fragment ParticipantFragment on TimelineThreadParticipant {
personId
workspaceMemberId
firstName
lastName
displayName
avatarUrl
handle
}
`;

View File

@ -0,0 +1,22 @@
import { gql } from '@apollo/client';
import { participantFragment } from '@/activities/emails/queries/fragments/participantFragment';
export const timelineThreadFragment = gql`
fragment TimelineThreadFragment on TimelineThread {
id
read
firstParticipant {
...ParticipantFragment
}
lastTwoParticipants {
...ParticipantFragment
}
lastMessageReceivedAt
lastMessageBody
subject
numberOfMessagesInThread
participantCount
}
${participantFragment}
`;

View File

@ -1,15 +1,20 @@
import { gql } from '@apollo/client';
import { timelineThreadFragment } from '@/activities/emails/queries/fragments/timelineThreadFragment';
export const getTimelineThreadsFromCompanyId = gql`
query GetTimelineThreadsFromCompanyId($companyId: String!) {
getTimelineThreadsFromCompanyId(companyId: $companyId) {
body
numberOfMessagesInThread
read
receivedAt
senderName
senderPictureUrl
subject
query GetTimelineThreadsFromCompanyId(
$companyId: ID!
$page: Int!
$pageSize: Int!
) {
getTimelineThreadsFromCompanyId(
companyId: $companyId
page: $page
pageSize: $pageSize
) {
...TimelineThreadFragment
}
}
${timelineThreadFragment}
`;

View File

@ -1,15 +1,20 @@
import { gql } from '@apollo/client';
import { timelineThreadFragment } from '@/activities/emails/queries/fragments/timelineThreadFragment';
export const getTimelineThreadsFromPersonId = gql`
query GetTimelineThreadsFromPersonId($personId: String!) {
getTimelineThreadsFromPersonId(personId: $personId) {
body
numberOfMessagesInThread
read
receivedAt
senderName
senderPictureUrl
subject
query GetTimelineThreadsFromPersonId(
$personId: ID!
$page: Int!
$pageSize: Int!
) {
getTimelineThreadsFromPersonId(
personId: $personId
page: $page
pageSize: $pageSize
) {
...TimelineThreadFragment
}
}
${timelineThreadFragment}
`;

View File

@ -50,7 +50,7 @@ export const RightDrawerEmailThread = () => {
<StyledContainer>
<EmailThreadHeader
subject={viewableEmailThread.subject}
lastMessageSentAt={viewableEmailThread.receivedAt}
lastMessageSentAt={viewableEmailThread.lastMessageReceivedAt}
/>
{messages.map((message) => (
<EmailThreadMessage

View File

@ -1,8 +1,8 @@
import { atom } from 'recoil';
import { MockedThread } from '@/activities/emails/mocks/mockedEmailThreads';
import { TimelineThread } from '~/generated/graphql';
export const viewableEmailThreadState = atom<MockedThread | null>({
export const viewableEmailThreadState = atom<TimelineThread | null>({
key: 'viewableEmailThreadState',
default: null,
});