From 2366c2cd94a0ff2d0cf450c6825cf63c08b0f937 Mon Sep 17 00:00:00 2001 From: JeevaRamanathan M Date: Sat, 19 Oct 2024 04:24:14 +0000 Subject: [PATCH 1/5] enhancement: added loading state for conversation --- frontend/src/Navigation.tsx | 23 ++++++++++++++++----- frontend/src/preferences/preferenceApi.ts | 11 +++++----- frontend/src/preferences/preferenceSlice.ts | 10 +++++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index ac7063be..c8252e37 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -37,11 +37,12 @@ import { setSelectedDocs, setSourceDocs, } from './preferences/preferenceSlice'; +import Spinner from './assets/spinner.svg'; +import SpinnerDark from './assets/spinner-dark.svg'; import Upload from './upload/Upload'; import ShareButton from './components/ShareButton'; import Help from './components/Help'; - interface NavigationProps { navOpen: boolean; setNavOpen: React.Dispatch>; @@ -89,18 +90,20 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const navigate = useNavigate(); useEffect(() => { - if (!conversations) { + if (!conversations?.data) { fetchConversations(); } - }, [conversations, dispatch]); + }, [conversations?.data, dispatch]); async function fetchConversations() { + dispatch(setConversations({ data: null, loading: true })); return await getConversations() .then((fetchedConversations) => { dispatch(setConversations(fetchedConversations)); }) .catch((error) => { console.error('Failed to fetch conversations: ', error); + dispatch(setConversations({ data: null, loading: false })); }); } @@ -196,6 +199,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { setNavOpen(!isMobile); }, [isMobile]); useDefaultDocument(); + return ( <> {!navOpen && ( @@ -278,13 +282,22 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { id="conversationsMainDiv" className="mb-auto h-[78vh] overflow-y-auto overflow-x-hidden dark:text-white" > - {conversations && conversations.length > 0 ? ( + {conversations?.loading && ( +
+ +
+ )} + + {conversations?.data && conversations.data.length > 0 ? (

{t('chats')}

- {conversations?.map((conversation) => ( + {conversations.data?.map((conversation) => ( { } } -export async function getConversations(): Promise< - { name: string; id: string }[] | null -> { +export async function getConversations(): Promise<{ + data: { name: string; id: string }[] | null; + loading: boolean; +}> { try { const response = await conversationService.getConversations(); const data = await response.json(); @@ -34,10 +35,10 @@ export async function getConversations(): Promise< conversations.push(conversation as { name: string; id: string }); }); - return conversations; + return { data: conversations, loading: false }; } catch (error) { console.log(error); - return null; + return { data: null, loading: false }; } } diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts index 6fb2480b..c566ba70 100644 --- a/frontend/src/preferences/preferenceSlice.ts +++ b/frontend/src/preferences/preferenceSlice.ts @@ -15,7 +15,10 @@ export interface Preference { token_limit: number; selectedDocs: Doc | null; sourceDocs: Doc[] | null; - conversations: { name: string; id: string }[] | null; + conversations: { + data: { name: string; id: string }[] | null; + loading: boolean; + }; modalState: ActiveState; } @@ -34,7 +37,10 @@ const initialState: Preference = { retriever: 'classic', } as Doc, sourceDocs: null, - conversations: null, + conversations: { + data: null, + loading: false, + }, modalState: 'INACTIVE', }; From a185b2a12a526e843b0a0723c02d255c02dc953c Mon Sep 17 00:00:00 2001 From: JeevaRamanathan M Date: Sat, 19 Oct 2024 04:45:00 +0000 Subject: [PATCH 2/5] retaining original state --- frontend/src/Navigation.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index c8252e37..d858bc02 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -96,14 +96,14 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { }, [conversations?.data, dispatch]); async function fetchConversations() { - dispatch(setConversations({ data: null, loading: true })); + dispatch(setConversations({ ...conversations, loading: true })); return await getConversations() .then((fetchedConversations) => { dispatch(setConversations(fetchedConversations)); }) .catch((error) => { console.error('Failed to fetch conversations: ', error); - dispatch(setConversations({ data: null, loading: false })); + dispatch(setConversations({ ...conversations, loading: false })); }); } From 6a024b0ced42d89a32d4ba868dbcecaded4c5b37 Mon Sep 17 00:00:00 2001 From: JeevaRamanathan M Date: Sat, 19 Oct 2024 04:46:46 +0000 Subject: [PATCH 3/5] update catch block --- frontend/src/Navigation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index d858bc02..5aa694f8 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -103,7 +103,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { }) .catch((error) => { console.error('Failed to fetch conversations: ', error); - dispatch(setConversations({ ...conversations, loading: false })); + dispatch(setConversations({ data: null, loading: false })); }); } From fcb5f946dd676d3583587350a4db5e5c8403760a Mon Sep 17 00:00:00 2001 From: JeevaRamanathan M Date: Tue, 22 Oct 2024 22:37:56 +0000 Subject: [PATCH 4/5] fixed according to suggestion Signed-off-by: JeevaRamanathan M --- frontend/src/Navigation.tsx | 10 ++++------ frontend/src/store.ts | 5 ++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index aa0b1a58..6050108e 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -11,7 +11,6 @@ import DocsGPT3 from './assets/cute_docsgpt3.svg'; import Discord from './assets/discord.svg'; import Expand from './assets/expand.svg'; import Github from './assets/github.svg'; -import Info from './assets/info.svg'; import SettingGear from './assets/settingGear.svg'; import Twitter from './assets/TwitterX.svg'; import UploadIcon from './assets/upload.svg'; @@ -44,7 +43,6 @@ import Spinner from './assets/spinner.svg'; import SpinnerDark from './assets/spinner-dark.svg'; import { selectQueries } from './conversation/conversationSlice'; import Upload from './upload/Upload'; -import ShareButton from './components/ShareButton'; import Help from './components/Help'; interface NavigationProps { @@ -314,14 +312,14 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { className="mb-auto h-[78vh] overflow-y-auto overflow-x-hidden dark:text-white" > {conversations?.loading && ( -
+
+ className="animate-spin cursor-pointer bg-transparent" + alt="Loading..." + />
)} - {conversations?.data && conversations.data.length > 0 ? (
diff --git a/frontend/src/store.ts b/frontend/src/store.ts index 565ea8cc..5843d493 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -23,7 +23,10 @@ const preloadedState: { preference: Preference } = { chunks: JSON.parse(chunks ?? '2').toString(), token_limit: token_limit ? parseInt(token_limit) : 2000, selectedDocs: doc !== null ? JSON.parse(doc) : null, - conversations: null, + conversations: { + data: null, + loading: false, + }, sourceDocs: [ { name: 'default', From 1e88c8637824ecdfee7210c2e5dd6333fdd796bf Mon Sep 17 00:00:00 2001 From: JeevaRamanathan M Date: Tue, 22 Oct 2024 23:34:32 +0000 Subject: [PATCH 5/5] updated loader state Signed-off-by: JeevaRamanathan M --- frontend/src/Navigation.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index 6050108e..cf9da2d1 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -72,6 +72,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const conversations = useSelector(selectConversations); const modalStateDeleteConv = useSelector(selectModalStateDeleteConv); const conversationId = useSelector(selectConversationId); + const [isDeletingConversation, setIsDeletingConversation] = useState(false); const { isMobile } = useMediaQuery(); const [isDarkTheme] = useDarkTheme(); @@ -114,6 +115,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { } const handleDeleteAllConversations = () => { + setIsDeletingConversation(true); conversationService .deleteAll() .then(() => { @@ -123,6 +125,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { }; const handleDeleteConversation = (id: string) => { + setIsDeletingConversation(true); conversationService .delete(id, {}) .then(() => { @@ -311,7 +314,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { id="conversationsMainDiv" className="mb-auto h-[78vh] overflow-y-auto overflow-x-hidden dark:text-white" > - {conversations?.loading && ( + {conversations?.loading && !isDeletingConversation && (