Skip to content

Commit 9c7bde2

Browse files
authored
Show pending approvals on the device page (#609)
Pending HITL approvals only appeared on the home page. Add an optional agentIP filter to HITLBar and render a scoped instance on the device page so a device's outstanding approvals show up there too. With no agentIP the bar behaves as before (all devices); the home page is unchanged. Renders nothing when the device has no pending approvals.
1 parent b439d94 commit 9c7bde2

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

dashboard/src/components/DevicePage.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
type Integration,
99
} from "../lib/api";
1010
import { fmtBytes } from "../lib/format";
11+
import { HITLBar } from "./HITLBar";
1112
import { IntegrationsCards } from "./IntegrationsCards";
1213
import { LiveRequests } from "./LiveRequests";
1314
import { DeviceIcon } from "./Logos";
@@ -205,6 +206,11 @@ export function DevicePage({
205206
</div>
206207
</section>
207208

209+
{/* pending approvals awaiting a decision for this device — same
210+
cards as the home page, scoped to this device's agent IP.
211+
Renders nothing when there are none. */}
212+
<HITLBar agentIP={a.ip} />
213+
208214
{/* agents (sessions) running on this device */}
209215
<SessionsTable sessions={a.sessions ?? []} />
210216

dashboard/src/components/HITLBar.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { useEffect, useState } from "react";
22
import { decideHITL, getHITLPending, type HITLPending, type HITLResolveResult } from "../lib/api";
33
import { Button } from "./Button";
44

5-
export function HITLBar() {
5+
// agentIP, when set, scopes the bar to a single device's pending
6+
// approvals (used on the device page); unset shows every device's
7+
// (the home page).
8+
export function HITLBar({ agentIP }: { agentIP?: string } = {}) {
69
const [pending, setPending] = useState<HITLPending[]>([]);
710
const [justResolved, setJustResolved] = useState<HITLPending[]>([]);
811
const [notice, setNotice] = useState("");
@@ -13,7 +16,7 @@ export function HITLBar() {
1316
try {
1417
const r = await getHITLPending();
1518
if (!cancelled) {
16-
const incoming = r ?? [];
19+
const incoming = (r ?? []).filter((p) => !agentIP || p.agent_ip === agentIP);
1720
// Detect >0 → 0 transition: briefly flash green "Approved" cards.
1821
setPending((prev) => {
1922
if (prev.length > 0 && incoming.length === 0) {
@@ -33,7 +36,7 @@ export function HITLBar() {
3336
cancelled = true;
3437
clearInterval(t);
3538
};
36-
}, []);
39+
}, [agentIP]);
3740

3841
async function decide(id: string, allow: boolean, confirmMsg: string) {
3942
if (!confirm(confirmMsg)) return;

0 commit comments

Comments
 (0)