mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 16:13:15 +00:00
feat: Implement a loading and empty state for recent & running threads (#257)
* feat: Implement a loading and empty state for recent & running threads * cr
This commit is contained in:
parent
3cd44ed86b
commit
a93614ffa6
3 changed files with 69 additions and 12 deletions
|
|
@ -9,7 +9,7 @@ import { Toaster } from "@/components/ui/sonner";
|
|||
import { Suspense } from "react";
|
||||
|
||||
export default function ChatPage() {
|
||||
const { threads } = useThreads<GraphState>(
|
||||
const { threads, threadsLoading } = useThreads<GraphState>(
|
||||
process.env.NEXT_PUBLIC_MANAGER_ASSISTANT_ID,
|
||||
);
|
||||
|
||||
|
|
@ -22,7 +22,10 @@ export default function ChatPage() {
|
|||
<Suspense>
|
||||
<Toaster />
|
||||
<GitHubAppProvider>
|
||||
<DefaultView threads={displayThreads} />
|
||||
<DefaultView
|
||||
threads={displayThreads}
|
||||
threadsLoading={threadsLoading}
|
||||
/>
|
||||
</GitHubAppProvider>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
GitPullRequest,
|
||||
Bug,
|
||||
FilePlus2,
|
||||
Archive,
|
||||
} from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ThreadDisplayInfo } from "./types";
|
||||
|
|
@ -33,13 +34,14 @@ import { Label } from "../ui/label";
|
|||
import { ContentBlocksPreview } from "../thread/ContentBlocksPreview";
|
||||
import { TooltipIconButton } from "../ui/tooltip-icon-button";
|
||||
import { ThemeToggle } from "../theme-toggle";
|
||||
import { ThreadCard } from "./thread-card";
|
||||
import { ThreadCard, ThreadCardLoading } from "./thread-card";
|
||||
|
||||
interface DefaultViewProps {
|
||||
threads: ThreadDisplayInfo[];
|
||||
threadsLoading: boolean;
|
||||
}
|
||||
|
||||
export function DefaultView({ threads }: DefaultViewProps) {
|
||||
export function DefaultView({ threads, threadsLoading }: DefaultViewProps) {
|
||||
const router = useRouter();
|
||||
const apiUrl: string | undefined = process.env.NEXT_PUBLIC_API_URL ?? "";
|
||||
const assistantId: string | undefined =
|
||||
|
|
@ -149,14 +151,31 @@ export function DefaultView({ threads }: DefaultViewProps) {
|
|||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
{threads.slice(0, 4).map((thread) => (
|
||||
<ThreadCard
|
||||
key={thread.id}
|
||||
thread={thread}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{threadsLoading || threads.length ? (
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
{threadsLoading && threads.length === 0 && (
|
||||
<>
|
||||
<ThreadCardLoading />
|
||||
<ThreadCardLoading />
|
||||
<ThreadCardLoading />
|
||||
<ThreadCardLoading />
|
||||
</>
|
||||
)}
|
||||
{threads.slice(0, 4).map((thread) => (
|
||||
<ThreadCard
|
||||
key={thread.id}
|
||||
thread={thread}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<span className="text-muted-foreground flex items-center gap-2">
|
||||
<Archive className="size-4" />
|
||||
<span className="text-sm">No threads found</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Quick Actions */}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { ThreadDisplayInfo } from "./types";
|
|||
import { useRouter } from "next/navigation";
|
||||
import { Badge } from "../ui/badge";
|
||||
import { Button } from "../ui/button";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
|
||||
export function ThreadCard({ thread }: { thread: ThreadDisplayInfo }) {
|
||||
const router = useRouter();
|
||||
|
|
@ -136,3 +137,37 @@ export function ThreadCard({ thread }: { thread: ThreadDisplayInfo }) {
|
|||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export function ThreadCardLoading() {
|
||||
return (
|
||||
<Card className="border-border bg-card px-0 py-3 dark:bg-gray-950">
|
||||
<CardHeader>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="min-w-0 flex-1">
|
||||
<CardTitle className="text-foreground truncate text-sm font-medium">
|
||||
<Skeleton className="h-5 w-48" />
|
||||
</CardTitle>
|
||||
<div className="mt-1 flex items-center gap-1">
|
||||
<Skeleton className="h-3 w-3 rounded-full" />
|
||||
<Skeleton className="h-3 w-32" />
|
||||
</div>
|
||||
</div>
|
||||
<Skeleton className="h-6 w-24 rounded-full" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Skeleton className="h-3 w-16" />
|
||||
<Skeleton className="h-3 w-1" />
|
||||
<Skeleton className="h-3 w-24" />
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Skeleton className="h-5 w-5 rounded-full" />
|
||||
<Skeleton className="h-5 w-5 rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue