feat(web): auto fresh every 5 seconds for workflow display

This commit is contained in:
BennyKok 2024-01-06 01:53:21 +08:00
parent 825c8a63fb
commit 3c4bce630e
6 changed files with 81 additions and 10 deletions

View File

@ -1,4 +1,5 @@
import { LoadingWrapper } from "@/components/LoadingWrapper";
import { RouteRefresher } from "@/components/RouteRefresher";
import { RunsTable } from "@/components/RunsTable";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@ -13,8 +14,11 @@ export default async function Page({
return (
<Card className="w-full h-fit min-w-0">
<CardHeader>
<CardHeader className="relative">
<CardTitle>Run</CardTitle>
<div className="absolute right-6 top-6">
<RouteRefresher interval={5000} />
</div>
</CardHeader>
<CardContent>

View File

@ -54,7 +54,7 @@ export function LiveStatus({
? `${data.json.event} - ${data.json.data.node}`
: "-"}
</TableCell>
<TableCell className="text-right">
<TableCell className="truncate text-right">
<StatusBadge status={status} />
</TableCell>
</>

View File

@ -12,6 +12,22 @@ export function PaginationControl(props: {
totalPage: number;
currentPage: number;
}) {
let startPage = Math.max(props.currentPage - 2, 1);
let endPage = Math.min(startPage + 3, props.totalPage);
if (props.currentPage <= 2) {
endPage = Math.min(4, props.totalPage);
}
if (props.currentPage > props.totalPage - 2) {
startPage = Math.max(props.totalPage - 3, 1);
}
const pageNumbers = Array.from(
{ length: endPage - startPage + 1 },
(_, i) => startPage + i
);
return (
<Pagination>
<PaginationContent>
@ -22,9 +38,15 @@ export function PaginationControl(props: {
: `?page=${props.currentPage}`
}
/>
<PaginationLink href="#" isActive>
{props.currentPage}
</PaginationLink>
{pageNumbers.map((page) => (
<PaginationLink
key={page}
href={`?page=${page}`}
isActive={props.currentPage === page}
>
{page}
</PaginationLink>
))}
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>

View File

@ -0,0 +1,41 @@
"use client";
import { LoadingIcon } from "@/components/LoadingIcon";
import { useRouter } from "next/navigation";
import { useEffect, useTransition } from "react";
export function RouteRefresher(props: { interval: number }) {
const [isPending, startTransition] = useTransition();
const router = useRouter();
useEffect(() => {
let timeout: NodeJS.Timeout;
const refresh = () => {
console.log("refreshing");
startTransition(() => {
router.refresh();
});
timeout = setTimeout(refresh, props.interval);
};
const handleVisibilityChange = () => {
if (document.hidden) {
clearTimeout(timeout);
} else {
refresh();
}
};
window.addEventListener("visibilitychange", handleVisibilityChange);
refresh();
return () => {
clearTimeout(timeout);
window.removeEventListener("visibilitychange", handleVisibilityChange);
};
}, [props.interval, router]);
return <div>{isPending && <LoadingIcon />}</div>;
}

View File

@ -24,8 +24,12 @@ export async function RunDisplay({
<DialogTrigger asChild className="appearance-none hover:cursor-pointer">
<TableRow>
<TableCell>{run.number}</TableCell>
<TableCell className="font-medium">{run.machine?.name}</TableCell>
<TableCell>{getRelativeTime(run.created_at)}</TableCell>
<TableCell className="font-medium truncate">
{run.machine?.name}
</TableCell>
<TableCell className="truncate">
{getRelativeTime(run.created_at)}
</TableCell>
<TableCell>{run.version?.version}</TableCell>
<LiveStatus run={run} />
</TableRow>

View File

@ -15,7 +15,7 @@ import {
} from "@/components/ui/table";
import { parseAsInteger } from "next-usequerystate";
const itemPerPage = 4;
const itemPerPage = 6;
const pageParser = parseAsInteger.withDefault(1);
export async function RunsTable(props: {
@ -33,7 +33,7 @@ export async function RunsTable(props: {
});
return (
<div>
<div className="overflow-auto h-[400px] w-full">
<div className="overflow-auto h-fit w-full">
<Table className="">
{/* <TableCaption>A list of your recent runs.</TableCaption> */}
<TableHeader className="bg-background top-0 sticky">
@ -42,7 +42,7 @@ export async function RunsTable(props: {
<TableHead className="">Machine</TableHead>
<TableHead className="">Time</TableHead>
<TableHead className="w-[100px]">Version</TableHead>
<TableHead className="">Live Status</TableHead>
<TableHead className="truncate">Live Status</TableHead>
<TableHead className=" text-right">Status</TableHead>
</TableRow>
</TableHeader>