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',