jobs: header running/queued badges + GET /jobs/counts (phase 3d)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sh
|
||||
import type { DockItem } from '../Dock';
|
||||
import { useIsTouch } from '../useIsTouch';
|
||||
import { UserMenu } from './UserMenu';
|
||||
import { JobsIndicator } from './JobsIndicator';
|
||||
import { RescanButton } from '../Rescan/RescanButton';
|
||||
// import { BugReportButton } from '../BugReport/BugReportButton';
|
||||
|
||||
@@ -53,6 +54,7 @@ export function Header({ dockItems }: HeaderProps) {
|
||||
*/}
|
||||
{/* Bug Report — hidden */}
|
||||
{/* <BugReportButton /> */}
|
||||
<JobsIndicator />
|
||||
<RescanButton />
|
||||
<UserMenu />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Loader2, ListOrdered } from 'lucide-react';
|
||||
import { useClient } from 'hooks/useClient';
|
||||
|
||||
type Counts = { running: number; runningJobId: string | null; queued: number };
|
||||
|
||||
// Always-present header badges: how many jobs are running (→ the running job) and queued (→ the queue).
|
||||
export const JobsIndicator = () => {
|
||||
const client = useClient();
|
||||
const [counts, setCounts] = useState<Counts>({ running: 0, runningJobId: null, queued: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
let alive = true;
|
||||
const load = () => client.get<Counts>('/jobs/counts').then((c) => alive && setCounts(c)).catch(() => {});
|
||||
load();
|
||||
const timer = setInterval(load, 3000);
|
||||
return () => { alive = false; clearInterval(timer); };
|
||||
}, []);
|
||||
|
||||
const pill = 'flex items-center gap-1 h-8 px-2.5 rounded-full text-xs font-semibold tabular-nums transition-colors';
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Link
|
||||
to={counts.runningJobId ? `/jobs/${counts.runningJobId}` : '/jobs'}
|
||||
title={counts.running ? 'Running job' : 'Nothing running'}
|
||||
className={`${pill} ${counts.running ? 'bg-blue-500/30 text-white hover:bg-blue-500/45' : 'bg-white/10 text-white/50 hover:bg-white/20'}`}
|
||||
>
|
||||
<Loader2 className={`h-3.5 w-3.5 ${counts.running ? 'animate-spin' : ''}`} />
|
||||
{counts.running}
|
||||
</Link>
|
||||
<Link
|
||||
to="/jobs"
|
||||
title="Queued jobs"
|
||||
className={`${pill} ${counts.queued ? 'bg-amber-500/30 text-white hover:bg-amber-500/45' : 'bg-white/10 text-white/50 hover:bg-white/20'}`}
|
||||
>
|
||||
<ListOrdered className="h-3.5 w-3.5" />
|
||||
{counts.queued}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user