Merge pull request #1343 from JeevaRamanathan/enhancement/conversation-loading-state

Enhancement: Added loading state for conversation list
This commit is contained in:
Alex
2024-10-30 10:55:40 +00:00
committed by GitHub
4 changed files with 39 additions and 12 deletions

View File

@@ -39,6 +39,8 @@ import {
setSelectedDocs,
setSourceDocs,
} from './preferences/preferenceSlice';
import Spinner from './assets/spinner.svg';
import SpinnerDark from './assets/spinner-dark.svg';
import { selectQueries } from './conversation/conversationSlice';
import Upload from './upload/Upload';
import Help from './components/Help';
@@ -70,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();
@@ -91,25 +94,28 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
const navigate = useNavigate();
useEffect(() => {
if (!conversations) {
if (!conversations?.data) {
fetchConversations();
}
if (queries.length === 0) {
resetConversation();
}
}, [conversations, dispatch]);
}, [conversations?.data, dispatch]);
async function fetchConversations() {
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 }));
});
}
const handleDeleteAllConversations = () => {
setIsDeletingConversation(true);
conversationService
.deleteAll()
.then(() => {
@@ -119,6 +125,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
};
const handleDeleteConversation = (id: string) => {
setIsDeletingConversation(true);
conversationService
.delete(id, {})
.then(() => {
@@ -205,6 +212,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
setNavOpen(!isMobile);
}, [isMobile]);
useDefaultDocument();
return (
<>
{!navOpen && (
@@ -306,13 +314,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 && !isDeletingConversation && (
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<img
src={isDarkTheme ? SpinnerDark : Spinner}
className="animate-spin cursor-pointer bg-transparent"
alt="Loading..."
/>
</div>
)}
{conversations?.data && conversations.data.length > 0 ? (
<div>
<div className=" my-auto mx-4 mt-2 flex h-6 items-center justify-between gap-4 rounded-3xl">
<p className="mt-1 ml-4 text-sm font-semibold">{t('chats')}</p>
</div>
<div className="conversations-container">
{conversations?.map((conversation) => (
{conversations.data?.map((conversation) => (
<ConversationTile
key={conversation.id}
conversation={conversation}

View File

@@ -21,9 +21,10 @@ export async function getDocs(): Promise<Doc[] | null> {
}
}
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 };
}
}

View File

@@ -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',
};

View File

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