File size: 1,981 Bytes
8b41737 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import type { GroupedInstance } from "../types";
interface Props {
instances: GroupedInstance[];
currentId: string;
onSelect: (id: string) => void;
}
export function InstanceNav({ instances, currentId, onSelect }: Props) {
const currentIdx = instances.findIndex((g) => g.instance_id === currentId);
return (
<div className="bg-gray-900 border-t border-gray-800 px-4 py-2 flex items-center justify-between">
<button
onClick={() => currentIdx > 0 && onSelect(instances[currentIdx - 1].instance_id)}
disabled={currentIdx <= 0}
className="px-3 py-1 rounded text-xs bg-gray-800 text-gray-300 hover:bg-gray-700 disabled:opacity-30 disabled:cursor-not-allowed"
>
← Prev (k)
</button>
<div className="flex items-center gap-2">
<span className="text-xs text-gray-500">
{currentIdx + 1} / {instances.length}
</span>
{/* Dot navigation for nearby instances */}
<div className="flex gap-0.5">
{instances.slice(Math.max(0, currentIdx - 5), currentIdx + 6).map((g) => (
<button
key={g.instance_id}
onClick={() => onSelect(g.instance_id)}
className={`w-2 h-2 rounded-full ${
g.instance_id === currentId
? "bg-blue-400"
: g.datasets.every((d) => d.summary.resolved)
? "bg-emerald-600"
: "bg-gray-600"
}`}
title={g.instance_id}
/>
))}
</div>
</div>
<button
onClick={() =>
currentIdx < instances.length - 1 &&
onSelect(instances[currentIdx + 1].instance_id)
}
disabled={currentIdx >= instances.length - 1}
className="px-3 py-1 rounded text-xs bg-gray-800 text-gray-300 hover:bg-gray-700 disabled:opacity-30 disabled:cursor-not-allowed"
>
Next (j) →
</button>
</div>
);
}
|