mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-06 19:22:13 +00:00
feat: Add loading state to all threads page (#260)
* feat: Implement a loading and empty state for recent & running threads * cr * feat: Add loading state to all threads page
This commit is contained in:
parent
a93614ffa6
commit
42f67464bc
4 changed files with 24 additions and 12 deletions
|
|
@ -33,7 +33,7 @@ export default function ThreadPage({
|
||||||
process.env.NEXT_PUBLIC_MANAGER_ASSISTANT_ID,
|
process.env.NEXT_PUBLIC_MANAGER_ASSISTANT_ID,
|
||||||
);
|
);
|
||||||
// Find the thread by ID
|
// Find the thread by ID
|
||||||
const thread = threads?.find((t) => t.thread_id === thread_id);
|
const thread = threads.find((t) => t.thread_id === thread_id);
|
||||||
|
|
||||||
const handleBackToHome = () => {
|
const handleBackToHome = () => {
|
||||||
router.push("/chat");
|
router.push("/chat");
|
||||||
|
|
@ -44,8 +44,7 @@ export default function ThreadPage({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert all threads to display format
|
// Convert all threads to display format
|
||||||
const displayThreads: ThreadDisplayInfo[] =
|
const displayThreads: ThreadDisplayInfo[] = threads.map(threadToDisplayInfo);
|
||||||
threads?.map(threadToDisplayInfo) ?? [];
|
|
||||||
const currentDisplayThread = threadToDisplayInfo(thread);
|
const currentDisplayThread = threadToDisplayInfo(thread);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@ export default function ChatPage() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convert Thread objects to ThreadDisplayInfo for UI
|
// Convert Thread objects to ThreadDisplayInfo for UI
|
||||||
const displayThreads: ThreadDisplayInfo[] =
|
const displayThreads: ThreadDisplayInfo[] = threads.map(threadToDisplayInfo);
|
||||||
threads?.map(threadToDisplayInfo) ?? [];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-background h-screen overflow-y-hidden">
|
<div className="bg-background h-screen overflow-y-hidden">
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,21 @@ import { useRouter } from "next/navigation";
|
||||||
import { ThreadDisplayInfo, threadToDisplayInfo } from "@/components/v2/types";
|
import { ThreadDisplayInfo, threadToDisplayInfo } from "@/components/v2/types";
|
||||||
import { useThreads } from "@/hooks/useThreads";
|
import { useThreads } from "@/hooks/useThreads";
|
||||||
import { GraphState } from "@open-swe/shared/open-swe/types";
|
import { GraphState } from "@open-swe/shared/open-swe/types";
|
||||||
import { ThreadCard } from "@/components/v2/thread-card";
|
import { ThreadCard, ThreadCardLoading } from "@/components/v2/thread-card";
|
||||||
import { ThemeToggle } from "@/components/theme-toggle";
|
import { ThemeToggle } from "@/components/theme-toggle";
|
||||||
|
|
||||||
type FilterStatus = "all" | "running" | "completed" | "failed" | "pending";
|
type FilterStatus = "all" | "running" | "completed" | "failed" | "pending";
|
||||||
|
|
||||||
export default function AllThreadsPage() {
|
export default function AllThreadsPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { threads } = useThreads<GraphState>(
|
const { threads, threadsLoading } = useThreads<GraphState>(
|
||||||
process.env.NEXT_PUBLIC_MANAGER_ASSISTANT_ID,
|
process.env.NEXT_PUBLIC_MANAGER_ASSISTANT_ID,
|
||||||
);
|
);
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [statusFilter, setStatusFilter] = useState<FilterStatus>("all");
|
const [statusFilter, setStatusFilter] = useState<FilterStatus>("all");
|
||||||
|
|
||||||
// Convert Thread objects to ThreadDisplayInfo for UI
|
// Convert Thread objects to ThreadDisplayInfo for UI
|
||||||
const displayThreads: ThreadDisplayInfo[] =
|
const displayThreads: ThreadDisplayInfo[] = threads.map(threadToDisplayInfo);
|
||||||
threads?.map(threadToDisplayInfo) ?? [];
|
|
||||||
|
|
||||||
// Filter and search threads
|
// Filter and search threads
|
||||||
const filteredThreads = displayThreads.filter((thread) => {
|
const filteredThreads = displayThreads.filter((thread) => {
|
||||||
|
|
@ -178,7 +177,7 @@ export default function AllThreadsPage() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{filteredThreads.length === 0 && (
|
{filteredThreads.length === 0 && !threadsLoading && (
|
||||||
<div className="py-12 text-center">
|
<div className="py-12 text-center">
|
||||||
<div className="text-muted-foreground mb-2">No threads found</div>
|
<div className="text-muted-foreground mb-2">No threads found</div>
|
||||||
<div className="text-muted-foreground/70 text-xs">
|
<div className="text-muted-foreground/70 text-xs">
|
||||||
|
|
@ -188,6 +187,21 @@ export default function AllThreadsPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{threadsLoading && threads.length === 0 && (
|
||||||
|
<div>
|
||||||
|
<div className="mb-3 flex items-center gap-2">
|
||||||
|
<h2 className="text-foreground text-base font-semibold capitalize">
|
||||||
|
Loading threads...
|
||||||
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ export function useThreads<State extends Record<string, any>>(
|
||||||
assistantId?: string,
|
assistantId?: string,
|
||||||
) {
|
) {
|
||||||
const apiUrl: string | undefined = process.env.NEXT_PUBLIC_API_URL ?? "";
|
const apiUrl: string | undefined = process.env.NEXT_PUBLIC_API_URL ?? "";
|
||||||
const [threads, setThreads] = useState<Thread<State>[] | null>(null);
|
const [threads, setThreads] = useState<Thread<State>[]>([]);
|
||||||
const [threadsLoading, setThreadsLoading] = useState(false);
|
const [threadsLoading, setThreadsLoading] = useState(false);
|
||||||
|
|
||||||
const getThread = useCallback(
|
const getThread = useCallback(
|
||||||
|
|
@ -50,7 +50,7 @@ export function useThreads<State extends Record<string, any>>(
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getThreads().then((threads) => {
|
getThreads().then((threads) => {
|
||||||
setThreads(threads);
|
setThreads(threads ?? []);
|
||||||
});
|
});
|
||||||
}, [getThreads]);
|
}, [getThreads]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue