diff --git a/packages/twenty-front/public/images/placeholders/background/loading_messages_bg.png b/packages/twenty-front/public/images/placeholders/background/loading_messages_bg.png new file mode 100644 index 000000000..60f7e8dd4 Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/background/loading_messages_bg.png differ diff --git a/packages/twenty-front/public/images/placeholders/moving-image/loading_messages.png b/packages/twenty-front/public/images/placeholders/moving-image/loading_messages.png new file mode 100644 index 000000000..674d2810b Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/moving-image/loading_messages.png differ diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailLoader.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailLoader.tsx new file mode 100644 index 000000000..cfaaab37b --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailLoader.tsx @@ -0,0 +1,17 @@ +import { Loader } from '@/ui/feedback/loader/components/Loader'; +import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder'; +import { + StyledEmptyContainer, + StyledEmptyTextContainer, + StyledEmptyTitle, +} from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled'; + +export const EmailLoader = ({ loadingText }: { loadingText?: string }) => ( + + + + {loadingText || 'Loading emails'} + + + +); diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx index 0d2567234..c24bf6e7e 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx @@ -3,6 +3,7 @@ import { useQuery } from '@apollo/client'; import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; +import { EmailLoader } from '@/activities/emails/components/EmailLoader'; import { EmailThreadFetchMoreLoader } from '@/activities/emails/components/EmailThreadFetchMoreLoader'; import { EmailThreadPreview } from '@/activities/emails/components/EmailThreadPreview'; import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from '@/activities/emails/constants/messaging.constants'; @@ -148,6 +149,10 @@ export const EmailThreads = ({ const { totalNumberOfThreads, timelineThreads }: TimelineThreadsWithTotal = data?.[queryName] ?? []; + if (firstQueryLoading) { + return ; + } + if (!firstQueryLoading && !timelineThreads?.length) { return ( diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx index 639f2cf99..b9de5bd11 100644 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx @@ -2,6 +2,7 @@ import React, { useCallback } from 'react'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; +import { EmailLoader } from '@/activities/emails/components/EmailLoader'; import { EmailThreadFetchMoreLoader } from '@/activities/emails/components/EmailThreadFetchMoreLoader'; import { EmailThreadHeader } from '@/activities/emails/components/EmailThreadHeader'; import { EmailThreadMessage } from '@/activities/emails/components/EmailThreadMessage'; @@ -25,7 +26,7 @@ export const RightDrawerEmailThread = () => { const { records: messages, - loading, + loading: firstQueryLoading, fetchMoreRecords, } = useFindManyRecords({ depth: 3, @@ -44,10 +45,10 @@ export const RightDrawerEmailThread = () => { }); const fetchMoreMessages = useCallback(() => { - if (!loading) { + if (!firstQueryLoading) { fetchMoreRecords(); } - }, [fetchMoreRecords, loading]); + }, [fetchMoreRecords, firstQueryLoading]); if (!viewableEmailThread) { return null; @@ -59,18 +60,24 @@ export const RightDrawerEmailThread = () => { subject={viewableEmailThread.subject} lastMessageSentAt={viewableEmailThread.lastMessageReceivedAt} /> - {messages.map((message) => ( - - ))} - + {firstQueryLoading ? ( + + ) : ( + <> + {messages.map((message) => ( + + ))} + + + )} ); }; diff --git a/packages/twenty-front/src/modules/ui/feedback/loader/components/Loader.tsx b/packages/twenty-front/src/modules/ui/feedback/loader/components/Loader.tsx new file mode 100644 index 000000000..15cc03852 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/feedback/loader/components/Loader.tsx @@ -0,0 +1,38 @@ +import styled from '@emotion/styled'; +import { motion } from 'framer-motion'; + +const StyledLoaderContainer = styled.div` + justify-content: center; + align-items: center; + display: flex; + gap: ${({ theme }) => theme.spacing(2)}; + width: ${({ theme }) => theme.spacing(6)}; + height: ${({ theme }) => theme.spacing(3)}; + border-radius: ${({ theme }) => theme.border.radius.pill}; + border: 1px solid ${({ theme }) => theme.font.color.tertiary}; + overflow: hidden; +`; + +const StyledLoader = styled(motion.div)` + background-color: ${({ theme }) => theme.font.color.tertiary}; + border-radius: ${({ theme }) => theme.border.radius.pill}; + height: 8px; + width: 8px; +`; + +export const Loader = () => ( + + + +); diff --git a/packages/twenty-front/src/modules/ui/layout/animated-placeholder/constants/AnimatedImages.ts b/packages/twenty-front/src/modules/ui/layout/animated-placeholder/constants/AnimatedImages.ts index ac941cff2..00e4836b1 100644 --- a/packages/twenty-front/src/modules/ui/layout/animated-placeholder/constants/AnimatedImages.ts +++ b/packages/twenty-front/src/modules/ui/layout/animated-placeholder/constants/AnimatedImages.ts @@ -5,6 +5,7 @@ export const Background: Record = { noTask: '/images/placeholders/background/no_task_bg.png', errorIndex: '/images/placeholders/background/error_index_bg.png', emptyTimeline: '/images/placeholders/background/empty_timeline_bg.png', + loadingMessages: '/images/placeholders/background/loading_messages_bg.png', emptyInbox: '/images/placeholders/background/empty_inbox_bg.png', error404: '/images/placeholders/background/404_bg.png', error500: '/images/placeholders/background/500_bg.png', @@ -17,6 +18,7 @@ export const MovingImage: Record = { noTask: '/images/placeholders/moving-image/no_task.png', errorIndex: '/images/placeholders/moving-image/error_index.png', emptyTimeline: '/images/placeholders/moving-image/empty_timeline.png', + loadingMessages: '/images/placeholders/moving-image/loading_messages.png', emptyInbox: '/images/placeholders/moving-image/empty_inbox.png', error404: '/images/placeholders/moving-image/404.png', error500: '/images/placeholders/moving-image/500.png',