From 0258599a4695eb47eb708bcd138d0fe1d9295512 Mon Sep 17 00:00:00 2001 From: Rod Boev Date: Wed, 24 Jun 2026 10:16:52 -0400 Subject: [PATCH] fix(approval): clear pending attention state on dismiss (#4754) --- static/messages.js | 2 ++ ...test_issue4754_approval_dismiss_persist.py | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/static/messages.js b/static/messages.js index 3e438336..cdee9cb8 100644 --- a/static/messages.js +++ b/static/messages.js @@ -5433,7 +5433,9 @@ function showApprovalCard(pending, pendingCount) { function dismissApprovalCard() { if (_approvalCurrentId) _markApprovalDismissed(_approvalCurrentId); + const sid = _approvalSessionId; hideApprovalCard(true); + if (sid) _clearApprovalPendingForSession(sid); } function _syncApprovalCollapseButton(card) { diff --git a/tests/test_issue4754_approval_dismiss_persist.py b/tests/test_issue4754_approval_dismiss_persist.py index 17230158..de45665c 100644 --- a/tests/test_issue4754_approval_dismiss_persist.py +++ b/tests/test_issue4754_approval_dismiss_persist.py @@ -101,6 +101,34 @@ def test_dismiss_approval_card_hides_card(): assert "hideApprovalCard(true)" in body +def test_dismiss_approval_card_clears_pending_attention(): + # dismissApprovalCard must call _clearApprovalPendingForSession so the tab + # indicator stops blinking after dismiss. Without this, _rememberApprovalPending + # reinsertes the pending entry on every poll tick and the indicator stays lit. + compact = _compact(MESSAGES_JS) + func_start = compact.find("functiondismissApprovalCard(") + assert func_start != -1 + body_end = compact.find("}", func_start) + body = compact[func_start:body_end + 1] + assert "_clearApprovalPendingForSession(sid)" in body, ( + "dismissApprovalCard must call _clearApprovalPendingForSession(sid)" + ) + + +def test_dismiss_approval_card_captures_sid_before_hide(): + # The session ID must be captured before hideApprovalCard(true) nulls out + # _approvalSessionId so the clear call receives the correct ID. + compact = _compact(MESSAGES_JS) + func_start = compact.find("functiondismissApprovalCard(") + assert func_start != -1 + body_end = compact.find("}", func_start) + body = compact[func_start:body_end + 1] + sid_pos = body.find("constsid=_approvalSessionId") + hide_pos = body.find("hideApprovalCard(true)") + assert sid_pos != -1, "sid must be captured via const sid=_approvalSessionId" + assert sid_pos < hide_pos, "sid must be captured before hideApprovalCard is called" + + # --------------------------------------------------------------------------- # respondApproval prunes dismissed set # ---------------------------------------------------------------------------