fix: Improve loading state handling on chat/threads page (#576)

* Apply patch

* Apply patch

* Apply patch

* cr

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: bracesproul <braceasproul@gmail.com>
This commit is contained in:
open-swe[bot] 2025-07-28 16:33:37 -07:00 • committed by GitHub
parent 2c774ee517
commit 25c3709e69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -29,7 +29,7 @@ type FilterStatus =
function AllThreadsPageContent() { function AllThreadsPageContent() {
const router = useRouter(); const router = useRouter();
const { currentInstallation } = useGitHubAppProvider(); const { currentInstallation, installationsLoading } = useGitHubAppProvider();
const { threads, isLoading: threadsLoading } = useThreadsSWR({ const { threads, isLoading: threadsLoading } = useThreadsSWR({
assistantId: MANAGER_GRAPH_ID, assistantId: MANAGER_GRAPH_ID,
currentInstallation, currentInstallation,
@ -48,40 +48,52 @@ function AllThreadsPageContent() {
isLoading: statusLoading, isLoading: statusLoading,
} = useThreadsStatus(threadIds, threads); } = useThreadsStatus(threadIds, threads);
const filteredThreads = threadsMetadata.filter((thread: ThreadMetadata) => { const filteredThreads = useMemo(() => {
const matchesSearch = return threadsMetadata.filter((thread: ThreadMetadata) => {
thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || const matchesSearch =
thread.repository.toLowerCase().includes(searchQuery.toLowerCase()); thread.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
thread.repository.toLowerCase().includes(searchQuery.toLowerCase());
const matchesStatus = const matchesStatus =
statusFilter === "all" || statusMap[thread.id] === statusFilter; statusFilter === "all" || statusMap[thread.id] === statusFilter;
return matchesSearch && matchesStatus; return matchesSearch && matchesStatus;
}); });
}, [threadsMetadata, searchQuery, statusFilter, statusMap]);
const groupedThreads = { const groupedThreads = useMemo(() => {
running: filteredThreads.filter( return {
(thread: ThreadMetadata) => statusMap[thread.id] === "running", running: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "running",
completed: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "completed", completed: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "completed",
failed: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "failed", failed: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "failed",
pending: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "pending", pending: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "pending",
idle: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "idle", idle: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "idle",
paused: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "paused", paused: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "paused",
error: filteredThreads.filter( ),
(thread: ThreadMetadata) => statusMap[thread.id] === "error", error: filteredThreads.filter(
), (thread: ThreadMetadata) => statusMap[thread.id] === "error",
}; ),
};
}, [filteredThreads, statusMap]);
// Show loading state if threads/status/installation requests are loading, and there are no
// threads to display (conditional of the status filter)
const showThreadsLoading =
(threadsLoading || statusLoading || installationsLoading) &&
(statusFilter === "all"
? Object.values(groupedThreads).flat().length === 0
: filteredThreads.length === 0);
return ( return (
<div className="bg-background flex h-screen flex-col"> <div className="bg-background flex h-screen flex-col">
@ -236,21 +248,20 @@ function AllThreadsPageContent() {
</div> </div>
)} )}
{(threadsLoading || statusLoading) && {showThreadsLoading && (
(!threads || threads.length === 0) && ( <div>
<div> <div className="mb-3 flex items-center gap-2">
<div className="mb-3 flex items-center gap-2"> <h2 className="text-foreground text-base font-semibold capitalize">
<h2 className="text-foreground text-base font-semibold capitalize"> Loading threads...
Loading threads... </h2>
</h2>
</div>
<div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
{Array.from({ length: 9 }).map((_, index) => (
<ThreadCardLoading key={`all-threads-loading-${index}`} />
))}
</div>
</div> </div>
)} <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
{Array.from({ length: 9 }).map((_, index) => (
<ThreadCardLoading key={`all-threads-loading-${index}`} />
))}
</div>
</div>
)}
</div> </div>
</div> </div>
</div> </div>