Skip to content

Card: sort order + pagination + filtering for large installations - #1

Merged
pos-ei-don merged 20 commits into
pos-ei-don:masterfrom
cerebrate:master
Oct 19, 2026
Merged

pos-ei-don merged 20 commits into
pos-ei-don:masterfrom
cerebrate:master

Conversation

@cerebrate

@cerebrate cerebrate commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Why

On Home Assistant installations with entity counts in the thousands, the management card's Throttled/Accepted tabs (which list every matching entity with no cap at all) and even the Unthrottled tab become unwieldy — everything renders as one long, unbroken list. This PR adds a live sort toggle and pagination so the card stays usable at that scale.

A related pain point on the same large installations: once you throttle an entity it moves into the (now paginated) Throttled tab, and there was no quick way to find it again to mark it accepted without paging through everything already reviewed.

This is a small, self-contained addition scoped entirely to the card (no backend/service changes), so I went straight to a PR rather than opening an issue first. Hope that's OK.

What changed

  • Throttled/Accepted tabs get a live sort-order toggle (Entity ID / Friendly name), sharing one setting between the two tabs. The initial default is settable via a new sort card option.
  • All three tabs (Unthrottled, Throttled, Accepted) are now paginated client-side via a new page_size card option (default 50), instead of rendering as one long list.
  • Unthrottled keeps its existing write-rate-first order from the backend top_writers response and hides the sort toggle, since it doesn't apply there.
  • The existing limit option is unchanged — it still only bounds how many writers the backend returns for Unthrottled; page_size is a new, independent, purely client-side display setting.
  • Bulk "set all to X" on Unthrottled still targets the full matching set, not just the visible page.
  • Fixed a UX issue found during testing: navigating to a page with fewer rows than page_size shrank the card, which could trigger a Lovelace masonry reflow and move the card unexpectedly on screen. The row-list container now reserves a full page's worth of height once pagination is active, so the card's footprint stays constant across pages.
  • The Throttled tab gets a live All/Unaccepted filter (next to the sort toggle), so an entity you've just throttled — which moves it out of Unthrottled — is easy to find and accept without paging through everything already reviewed. Unthrottled and Accepted tabs are unaffected.
  • The Throttled tab's count badge shows "shown/total" (e.g. Throttled (88/767)) while the filter is narrowing the view, so it's clear you're looking at a subset rather than the full list.
  • The toolbar (sort + filter) stays visible even when the current tab has zero rows — filtering Throttled down to nothing no longer hides the control needed to switch back to "All".
  • Version bump to 1.1, a CHANGELOG.md entry, README documentation for the two new options, and the card's console-banner version kept in sync via scripts/sync_card_version.py.

Card-only change (recorder-throttle-card.js, manifest.json, CHANGELOG.md, README.md); no backend/service changes.

Testing

  • node --check on the card file (syntax; no local build/test harness in this repo).
  • python3 scripts/sync_card_version.py --check passes.
  • Manually verified on a live Home Assistant instance with a large real-world entity count: sort toggle behavior on Throttled/Accepted (hidden on Unthrottled); independent per-tab pagination at the configured page size; prev/next boundary disabling; sort-change page reset; bulk action still affecting the full Unthrottled set; the height fix confirmed to eliminate the masonry-reflow jump; the filter correctly narrows the Throttled tab to unaccepted entities only; the tab badge switches to "shown/total" while filtering and back to a plain count when off; the toolbar remains visible and usable when the filtered view is empty; accepting an entity drops it out of the filtered view on the next refresh.

claude and others added 13 commits September 4, 2026 02:10
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
The `hacs` check's "no valid topics" and "issues not enabled" failures are
GitHub repo settings that forks don't inherit, not code problems. Document
this so it isn't mistaken for a real CI regression in future sessions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Throttled/Accepted tabs get a live toggle to sort by entity ID or
friendly name (shared between the two tabs); all three tabs are now
paginated client-side via a new page_size config option (default 50).
Unthrottled keeps its existing write-rate-first order from the backend
and hides the sort toggle, since it doesn't apply there. The existing
limit option is unchanged.

No release housekeeping (manifest version bump, CHANGELOG, README, card
banner sync) in this commit — deferred until after a live smoke test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Card: sort order toggle + pagination
Navigating to a page with fewer rows than page_size shrank the card,
which could trigger a Lovelace masonry reflow that moved the card
unexpectedly on screen (or off it). The rows container now reserves a
full page's worth of height (measured from a previously rendered row)
whenever pagination is active, so the card's footprint stays constant
across pages within a tab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Card: fix height jump on short last page
Bump manifest.json to 1.1, sync the card's console-banner version via
scripts/sync_card_version.py --fix, add a CHANGELOG entry, and document
the new page_size/sort card options and their live controls in README.

Covers the sort-toggle + pagination feature (merged in #2) and the
follow-up card-height fix for short last pages (merged in #3), both
confirmed working in live testing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Release housekeeping for 1.1: card sort + pagination
Setting a throttle policy moves an entity from Unthrottled to Throttled,
but there was no way to jump straight to the newly-throttled, not-yet-
accepted entities without paging through everything already reviewed.
The Throttled tab now gets a live filter (alongside the existing sort
toggle) to show only unaccepted entities. Unthrottled/Accepted tabs are
unaffected — the filter doesn't apply to either.

The toolbar (sort + filter) now renders even when the current tab has
zero rows, so filtering Throttled down to nothing doesn't strand the
control needed to switch back to "All".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
With the Unaccepted filter on, the tab badge dropped straight to the
filtered count (e.g. "Throttled (88)"), which read as if most throttled
entities had vanished rather than just being filtered from view. It now
shows "Throttled (88/767)" while the filter is active.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Card: filter Throttled tab to unaccepted entities
@cerebrate cerebrate changed the title Card: sort order + pagination for large installations Card: sort order + pagination + filtering for large installations Sep 21, 2026
@pos-ei-don

Copy link
Copy Markdown
Owner

Thanks a lot for this, and apologies for the long silence — notifications for this repo weren't reaching me.

The feature set is exactly what large installations need, and I'd like to merge it. Release 1.1 landed in the meantime and touches the same card (the Unthrottled list now asks top_writers with exclude_throttled: true, so throttled entities no longer crowd it out before the limit; rates for the other tabs come from a second call). Could you:

  1. rebase onto current master (the card merges cleanly; CHANGELOG.md conflicts),
  2. drop the CLAUDE.md from the PR — it's a local working file, not something I want to ship in the repo,
  3. leave the version in manifest.json (and the card banner) as it is — I'll bump it when releasing.

After that I'll review and test it on a large instance. Thanks again!

Throttled/Accepted tabs get a live toggle to sort by entity ID or
friendly name (shared between the two tabs); all three tabs are now
paginated client-side via a new page_size config option (default 50).
Unthrottled keeps its existing write-rate-first order from the backend
and hides the sort toggle, since it doesn't apply there. The existing
limit option is unchanged.

No release housekeeping (manifest version bump, CHANGELOG, README, card
banner sync) in this commit — deferred until after a live smoke test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Navigating to a page with fewer rows than page_size shrank the card,
which could trigger a Lovelace masonry reflow that moved the card
unexpectedly on screen (or off it). The rows container now reserves a
full page's worth of height (measured from a previously rendered row)
whenever pagination is active, so the card's footprint stays constant
across pages within a tab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Bump manifest.json to 1.1, sync the card's console-banner version via
scripts/sync_card_version.py --fix, add a CHANGELOG entry, and document
the new page_size/sort card options and their live controls in README.

Covers the sort-toggle + pagination feature (merged in #2) and the
follow-up card-height fix for short last pages (merged in #3), both
confirmed working in live testing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
Setting a throttle policy moves an entity from Unthrottled to Throttled,
but there was no way to jump straight to the newly-throttled, not-yet-
accepted entities without paging through everything already reviewed.
The Throttled tab now gets a live filter (alongside the existing sort
toggle) to show only unaccepted entities. Unthrottled/Accepted tabs are
unaffected — the filter doesn't apply to either.

The toolbar (sort + filter) now renders even when the current tab has
zero rows, so filtering Throttled down to nothing doesn't strand the
control needed to switch back to "All".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
With the Unaccepted filter on, the tab badge dropped straight to the
filtered count (e.g. "Throttled (88)"), which read as if most throttled
entities had vanished rather than just being filtered from view. It now
shows "Throttled (88/767)" while the filter is active.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZ7r86yV5jMT25CF2uhNwY
@cerebrate

Copy link
Copy Markdown
Contributor Author

This should do it.

(I think at this point it's messy enough to really deserve a squash merge, heh.)

@pos-ei-don
pos-ei-don merged commit 1943909 into pos-ei-don:master Oct 19, 2026
@pos-ei-don

Copy link
Copy Markdown
Owner

Thanks — tested with a large entity set and squash-merged. It shipped in 1.2, together with three small follow-ups from review: the sort/filter toolbar wraps on narrow cards, the reserved page height no longer shrinks after a one-row last page (the last row's border is now transparent instead of removed), and page_size/limit are parsed as numbers (a quoted "50" used to concatenate when paging).

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.

3 participants