From 551184c5b26993ebb984ff4c9b5bfa299d875ce6 Mon Sep 17 00:00:00 2001 From: viettranx Date: Wed, 18 Mar 2026 16:43:30 +0700 Subject: [PATCH] fix(heartbeat): delayed refresh after toggle/update for accurate countdown Wait 2s after toggle/update before refreshing config from backend to ensure nextRunAt is computed and persisted. Prevents stale countdown in header heartbeat button. --- ui/web/src/pages/agents/hooks/use-agent-heartbeat.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ui/web/src/pages/agents/hooks/use-agent-heartbeat.ts b/ui/web/src/pages/agents/hooks/use-agent-heartbeat.ts index a7df55bc..d66f2583 100644 --- a/ui/web/src/pages/agents/hooks/use-agent-heartbeat.ts +++ b/ui/web/src/pages/agents/hooks/use-agent-heartbeat.ts @@ -120,7 +120,8 @@ export function useAgentHeartbeat(agentId: string) { setSaving(true); try { await ws.call(Methods.HEARTBEAT_TOGGLE, { agentId, enabled }); - setConfig((prev) => (prev ? { ...prev, enabled } : prev)); + // Wait for backend to compute nextRunAt, then refresh. + setTimeout(() => refresh(), 2000); } catch (err) { const msg = err instanceof Error ? err.message : "Failed to toggle heartbeat"; toast.error(msg); @@ -128,7 +129,7 @@ export function useAgentHeartbeat(agentId: string) { setSaving(false); } }, - [ws, agentId], + [ws, agentId, refresh], ); const update = useCallback( @@ -142,6 +143,8 @@ export function useAgentHeartbeat(agentId: string) { { agentId, ...params }, ); setConfig(res.heartbeat); + // Delayed refresh to pick up any backend-computed state (e.g. nextRunAt). + setTimeout(() => refresh(), 2000); } catch (err) { const msg = err instanceof Error ? err.message : "Failed to save heartbeat"; setError(msg); @@ -151,7 +154,7 @@ export function useAgentHeartbeat(agentId: string) { setSaving(false); } }, - [ws, agentId], + [ws, agentId, refresh], ); const test = useCallback(async () => {