Skip to content

fix(notifications): reconcile stale monitored-node IDs; per-source select/deselect (#3486)#3487

Merged
Yeraze merged 1 commit into
mainfrom
fix/3486-monitored-nodes-reconcile
Jun 15, 2026
Merged

fix(notifications): reconcile stale monitored-node IDs; per-source select/deselect (#3486)#3487
Yeraze merged 1 commit into
mainfrom
fix/3486-monitored-nodes-reconcile

Conversation

@Yeraze

@Yeraze Yeraze commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Fixes #3486.

Problem

In Notifications → Battery Alerts, the "Select which nodes to monitor" picker showed a stuck selection count (e.g. "11 node(s) selected") with nothing visibly checked, and "Deselect all" couldn't clear it. Low-battery alerts also silently matched nothing.

Root cause

The picker is source-scoped: it only lists the current source's nodes (/api/nodes?sourceId=…, also channel-permission filtered). The saved selection is per-source too, but node IDs saved under a different source — or for nodes that no longer exist under the active source — stayed in selectedMonitoredNodes while being invisible in the list. "Deselect all" mapped over only the visible/filtered rows (filteredNodes), so those stale IDs were unreachable and the count never went to 0. getLowBatteryMonitoredNodes then found no matching nodes to alert on.

(There is no key-format mismatch — selection and list both compare bare nodeId strings. The IDs are simply filtered out of the source-scoped response.)

Fix

  • Reconcile / prune (on load): prune the per-source selection down to IDs that actually resolve under the active source. Guarded on a populated node list so a failed or not-yet-returned fetch can't wipe a valid selection, and works regardless of whether the nodes or the prefs load first (length-guarded, no re-render loop).
  • Per-source Select all / Deselect all:
    • No search term → Select all selects the entire current source; Deselect all clears the entire selection (stale IDs included).
    • Search active → previous subset add/remove behaviour preserved, so you can still do targeted multi-select while filtering (and stale IDs outside the filter are left untouched).

Set logic is extracted into pure helpers (src/components/monitoredNodes.ts) with unit tests.

Notes

  • For non-admin users, the active-source list is also channel-permission filtered, so reconcile prunes against what the user can actually see/manage in the picker. Admins see the full source list.
  • Reconcile updates local state only; the cleaned selection persists when the user saves preferences (consistent with the rest of the form).

Validation

  • New unit tests: 10/10 pass (reconcile + both button modes)
  • tsc --noEmit: clean
  • Full Vitest suite: 6480 pass, 0 fail, 0 suite failures

🤖 Generated with Claude Code

…lect/deselect (#3486)

The Battery Alerts "monitored nodes" picker is source-scoped: it only lists the
current source's nodes (/api/nodes?sourceId=…, also channel-permission filtered).
The saved selection is per-source too, but IDs saved under a different source or
for nodes that no longer exist under the active source stayed in
selectedMonitoredNodes invisibly. "Deselect all" mapped only the visible/filtered
rows, so it could never clear them — the count stuck at e.g. "11 selected" with
nothing checked, and getLowBatteryMonitoredNodes matched nothing.

- Reconcile: on load, prune the per-source selection to IDs that actually resolve
  under the active source (guarded on a populated node list so a failed/empty
  fetch can't wipe a valid selection; handles either nodes/prefs load order).
- Select all / Deselect all now operate per-source: with no search term, Select
  all selects the whole current source and Deselect all clears the entire
  selection (stale IDs included). With a search active, the previous subset
  add/remove behaviour is preserved.

Extracts the set logic into pure helpers (src/components/monitoredNodes.ts) with
unit tests covering reconcile and both button modes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

1 similar comment
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

@Yeraze Yeraze merged commit fbbdd96 into main Jun 15, 2026
18 of 20 checks passed
@Yeraze Yeraze deleted the fix/3486-monitored-nodes-reconcile branch June 15, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Notify on Low Battery

1 participant