51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import type { RunActivityRow } from "@rakazo/contracts";
|
|
import { rpc } from "../lib/api";
|
|
|
|
export async function fetchSpaceActivity(): Promise<{
|
|
active: RunActivityRow[];
|
|
recent: RunActivityRow[];
|
|
}> {
|
|
const [active, recent] = await Promise.all([
|
|
rpc<{ runs: RunActivityRow[] }>("runs/list", { filter: "active" }),
|
|
rpc<{ runs: RunActivityRow[] }>("runs/list", { filter: "recent" }),
|
|
]);
|
|
return { active: active.runs, recent: recent.runs };
|
|
}
|
|
|
|
export function formatActivityRelativeTime(iso: string, now = new Date()): string {
|
|
const date = new Date(iso);
|
|
if (Number.isNaN(date.getTime())) return "";
|
|
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
|
if (seconds < 45) return "just now";
|
|
const minutes = Math.floor(seconds / 60);
|
|
if (minutes < 60) return `${minutes}m ago`;
|
|
const hours = Math.floor(minutes / 60);
|
|
if (hours < 24) return `${hours}h ago`;
|
|
const days = Math.floor(hours / 24);
|
|
if (days < 7) return `${days}d ago`;
|
|
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
}
|
|
|
|
export function activityStatusLabel(status: RunActivityRow["status"]): string {
|
|
switch (status) {
|
|
case "queued":
|
|
return "Queued";
|
|
case "leased":
|
|
return "Starting";
|
|
case "running":
|
|
return "Running";
|
|
case "waiting_input":
|
|
return "Needs input";
|
|
case "waiting_takeover":
|
|
return "Needs takeover";
|
|
case "completed":
|
|
return "Done";
|
|
case "failed":
|
|
return "Failed";
|
|
case "cancelled":
|
|
return "Cancelled";
|
|
default:
|
|
return status;
|
|
}
|
|
}
|