Add fetch more loader for email messages (#3618)

Add fetch more loader

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette 2024-01-25 14:44:54 +01:00 committed by GitHub
parent 6d997edabb
commit f099ff90c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 85 additions and 31 deletions

View File

@ -7,7 +7,7 @@ export type MockedThread = {
export const mockedEmailThreads: MockedThread[] = [
{
__typename: 'TimelineThread',
id: '4e88ec1f-a386-4235-bd82-98f25f6d557e',
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'],
@ -18,7 +18,7 @@ export const mockedEmailThreads: MockedThread[] = [
},
{
__typename: 'TimelineThread',
id: '4e88ec1f-a386-4235-bd82-98f25f6d557e',
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'],

View File

@ -4,6 +4,7 @@ import { useRecoilValue } from 'recoil';
import { EmailThreadHeader } from '@/activities/emails/components/EmailThreadHeader';
import { EmailThreadMessage } from '@/activities/emails/components/EmailThreadMessage';
import { RightDrawerEmailThreadFetchMoreLoader } from '@/activities/emails/right-drawer/components/RightDrawerEmailThreadFetchMoreLoader';
import { viewableEmailThreadState } from '@/activities/emails/state/viewableEmailThreadState';
import { EmailThreadMessage as EmailThreadMessageType } from '@/activities/emails/types/EmailThreadMessage';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
@ -22,7 +23,11 @@ const StyledContainer = styled.div`
export const RightDrawerEmailThread = () => {
const viewableEmailThread = useRecoilValue(viewableEmailThreadState);
const { records: messages } = useFindManyRecords<EmailThreadMessageType>({
const {
records: messages,
loading,
fetchMoreRecords: fetchMoreMessages,
} = useFindManyRecords<EmailThreadMessageType>({
depth: 3,
filter: {
messageThreadId: {
@ -55,6 +60,10 @@ export const RightDrawerEmailThread = () => {
sentAt={message.receivedAt}
/>
))}
<RightDrawerEmailThreadFetchMoreLoader
loading={loading}
fetchMoreMessages={fetchMoreMessages}
/>
</StyledContainer>
);
};

View File

@ -0,0 +1,26 @@
import { useRecoilCallback } from 'recoil';
import { FetchMoreLoader } from '@/ui/utilities/loading-state/components/FetchMoreLoader';
type RightDrawerEmailThreadFetchMoreLoaderProps = {
loading: boolean;
fetchMoreMessages: () => void;
};
export const RightDrawerEmailThreadFetchMoreLoader = ({
loading,
fetchMoreMessages,
}: RightDrawerEmailThreadFetchMoreLoaderProps) => {
const onLastRowVisible = useRecoilCallback(
() => async () => {
if (!loading) {
fetchMoreMessages();
}
},
[fetchMoreMessages, loading],
);
return (
<FetchMoreLoader loading={loading} onLastRowVisible={onLastRowVisible} />
);
};

View File

@ -1,12 +1,9 @@
import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable';
import { StyledRow } from '@/object-record/record-table/components/RecordTableRow';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState';
import { grayScale } from '@/ui/theme/constants/colors';
import { FetchMoreLoader } from '@/ui/utilities/loading-state/components/FetchMoreLoader';
type RecordTableBodyFetchMoreLoaderProps = {
objectNamePlural: string;
@ -29,30 +26,10 @@ export const RecordTableBodyFetchMoreLoader = ({
[setRecordTableLastRowVisible],
);
const { ref: tbodyRef } = useInView({
onChange: onLastRowVisible,
});
const StyledText = styled.div`
align-items: center;
box-shadow: none;
color: ${grayScale.gray40};
display: flex;
height: 32px;
margin-left: ${({ theme }) => theme.spacing(8)};
padding-left: ${({ theme }) => theme.spacing(2)};
`;
return (
<tbody ref={tbodyRef}>
{isFetchingMoreObjects && (
<StyledRow selected={false}>
<td colSpan={7}>
<StyledText>Loading more...</StyledText>
</td>
<td colSpan={7} />
</StyledRow>
)}
</tbody>
<FetchMoreLoader
loading={isFetchingMoreObjects}
onLastRowVisible={onLastRowVisible}
/>
);
};

View File

@ -0,0 +1,42 @@
import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
import { StyledRow } from '@/object-record/record-table/components/RecordTableRow';
import { grayScale } from '@/ui/theme/constants/colors';
type FetchMoreLoaderProps = {
loading: boolean;
onLastRowVisible: (...args: any[]) => any;
};
const StyledText = styled.div`
align-items: center;
box-shadow: none;
color: ${grayScale.gray40};
display: flex;
height: 32px;
margin-left: ${({ theme }) => theme.spacing(8)};
padding-left: ${({ theme }) => theme.spacing(2)};
`;
export const FetchMoreLoader = ({
loading,
onLastRowVisible,
}: FetchMoreLoaderProps) => {
const { ref: tbodyRef } = useInView({
onChange: onLastRowVisible,
});
return (
<tbody ref={tbodyRef}>
{loading && (
<StyledRow selected={false}>
<td colSpan={7}>
<StyledText>Loading more...</StyledText>
</td>
<td colSpan={7} />
</StyledRow>
)}
</tbody>
);
};