POC timeline activity (#5697)

TODO: 
- remove WorkspaceIsNotAuditLogged decorators on activity/activityTarget
to log task/note creations
- handle attachments
-  fix css and remove unnecessary styled components or duplicates
This commit is contained in:
Weiko
2024-06-11 18:53:28 +02:00
committed by GitHub
parent 64b8e4ec4d
commit be96c68416
60 changed files with 2134 additions and 443 deletions

View File

@ -44,9 +44,11 @@ export const EmailThreadHeader = ({
<StyledContainer>
<StyledHead>
<StyledHeading>{subject}</StyledHeading>
<StyledContent>
Last message {beautifyPastDateRelativeToNow(lastMessageSentAt)}
</StyledContent>
{lastMessageSentAt && (
<StyledContent>
Last message {beautifyPastDateRelativeToNow(lastMessageSentAt)}
</StyledContent>
)}
</StyledHead>
</StyledContainer>
);

View File

@ -43,11 +43,14 @@ export const RightDrawerEmailThread = () => {
useRegisterClickOutsideListenerCallback({
callbackId:
'EmailThreadClickOutsideCallBack-' + (thread.id ?? 'no-thread-id'),
'EmailThreadClickOutsideCallBack-' + (thread?.id ?? 'no-thread-id'),
callbackFunction: useRecoilCallback(
({ set }) =>
() => {
set(emailThreadIdWhenEmailThreadWasClosedState, thread.id);
set(
emailThreadIdWhenEmailThreadWasClosedState,
thread?.id ?? 'no-thread-id',
);
},
[thread],
),
@ -71,14 +74,14 @@ export const RightDrawerEmailThread = () => {
return (
<StyledContainer>
<EmailThreadHeader
subject={thread.subject}
lastMessageSentAt={thread.lastMessageReceivedAt}
/>
{loading ? (
<EmailLoader loadingText="Loading thread" />
) : (
<>
<EmailThreadHeader
subject={thread.subject}
lastMessageSentAt={lastMessage.receivedAt}
/>
{firstMessages.map((message) => (
<EmailThreadMessage
key={message.id}

View File

@ -3,9 +3,15 @@ import { renderHook } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useRightDrawerEmailThread } from '../useRightDrawerEmailThread';
jest.mock('@/object-record/hooks/useFindOneRecord', () => ({
__esModule: true,
useFindOneRecord: jest.fn(),
}));
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
__esModule: true,
useFindManyRecords: jest.fn(),
@ -13,11 +19,21 @@ jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
describe('useRightDrawerEmailThread', () => {
it('should return correct values', async () => {
const mockThread = { id: '1' };
const mockMessages = [
{ id: '1', text: 'Message 1' },
{ id: '2', text: 'Message 2' },
];
const mockFetchMoreRecords = jest.fn();
(useFindOneRecord as jest.Mock).mockReturnValue({
record: mockThread,
loading: false,
fetchMoreRecords: mockFetchMoreRecords,
});
(useFindManyRecords as jest.Mock).mockReturnValue({
records: mockMessages,
loading: false,

View File

@ -1,26 +1,26 @@
import { useCallback } from 'react';
import { useApolloClient } from '@apollo/client';
import gql from 'graphql-tag';
import { useRecoilValue } from 'recoil';
import { fetchAllThreadMessagesOperationSignatureFactory } from '@/activities/emails/graphql/operation-signatures/factories/fetchAllThreadMessagesOperationSignatureFactory';
import { EmailThread } from '@/activities/emails/types/EmailThread';
import { EmailThreadMessage as EmailThreadMessageType } from '@/activities/emails/types/EmailThreadMessage';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
export const useRightDrawerEmailThread = () => {
const viewableRecordId = useRecoilValue(viewableRecordIdState);
const { setRecords } = useSetRecordInStore();
const apolloClient = useApolloClient();
const thread = apolloClient.readFragment({
id: `TimelineThread:${viewableRecordId}`,
fragment: gql`
fragment timelineThread on TimelineThread {
id
subject
lastMessageReceivedAt
}
`,
const { record: thread } = useFindOneRecord<EmailThread>({
objectNameSingular: CoreObjectNameSingular.MessageThread,
objectRecordId: viewableRecordId ?? '',
recordGqlFields: {
id: true,
},
onCompleted: (record) => setRecords([record]),
});
const FETCH_ALL_MESSAGES_OPERATION_SIGNATURE =

View File

@ -0,0 +1,8 @@
import { EmailThreadMessage } from '@/activities/emails/types/EmailThreadMessage';
export type EmailThread = {
id: string;
subject: string;
messages: EmailThreadMessage[];
__typename: 'EmailThread';
};

View File

@ -4,6 +4,8 @@ export type EmailThreadMessage = {
id: string;
text: string;
receivedAt: string;
subject: string;
messageThreadId: string;
messageParticipants: EmailThreadMessageParticipant[];
__typename: 'EmailThreadMessage';
};