feat(admin): redesign feedback list as scannable rows linking to detail (BUNYIP-422) #410

Merged
longjacksonle merged 1 commit from feat/BUNYIP-422-feedback-list-redesign into main 2026-07-30 01:38:16 +02:00

What

Closes BUNYIP-422. Redesigns the admin Feedback list to match the Users list from BUNYIP-405: a clean, scannable list where each row links into the detail view, with all triage actions moved off the rows and onto that detail page.

Before: every row carried the full toolbar inline (Reply, Reviewed/Un-review, Close, Archive, Spam, Delete). After: each row is a whole-row link showing subject, submitter identity, source page, message excerpt, relative time, and a color-coded status chip with a trailing chevron and hover highlight. No inline buttons.

How

  • feedback_row is now a whole-row <a href="/admin/feedback/{id}?from={tab}"> with a status chip + chevron, no forms. New feedback_status_chip mirrors the users verified_indicator (icon + short label, color-coded per status).
  • Triage actions live on the detail page via a new feedback_detail_actions(id, status, tab) helper, rendered tab-aware. The ?from= slug is parsed by FeedbackTab::from_query so the detail page shows the right action set and each action redirects back to the originating list tab (the existing from -> from_tab_path redirect contract is unchanged).
  • Detail header now uses the same status chip, and its Back link returns to the originating tab.
  • Tabs, Export CSV, empty states, and pagination are untouched. The Archive tab (separate endpoint, single Restore action) is already clean and is left as-is.

Action coverage moved to detail, tab-aware, nothing lost:

  • Active: Reviewed / Un-review, Close, Archive, Mark as spam, Delete
  • Closed: Re-open, Archive, Mark as spam, Delete
  • Spam: Not spam, Archive, Delete
  • Archive: Delete

Tests

  • feedback_row_links_to_detail_with_no_inline_actions - row is a detail link with the tab slug, shows the status chip, and carries no <form> and none of the action endpoints.
  • feedback_row_carries_originating_tab_slug - a Spam-tab row links back with ?from=spam.
  • feedback_detail_actions_are_tab_aware - Active vs Closed vs Spam render the correct buttons (incl. Un-review when already reviewed) with the correct from redirect value.
  • feedback_tab_from_query_round_trips - slug <-> tab round-trip, unknown/absent falls back to Active.

just check-container is green (fmt + clippy -D warnings + build + full workspace tests, 141 bunyip-web tests pass).

Verification

The row and detail markup reuse the exact icon / button_class / hover + focus token classes the users rows already use, so both light and dark themes render without bespoke styling. Structural behavior (row-as-link, no inline actions, tab-aware detail actions, correct redirects) is covered by the unit tests above.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LerAorB26HGHLfjC9iDUbd

## What Closes BUNYIP-422. Redesigns the admin Feedback list to match the Users list from BUNYIP-405: a clean, scannable list where each row links into the detail view, with all triage actions moved off the rows and onto that detail page. Before: every row carried the full toolbar inline (Reply, Reviewed/Un-review, Close, Archive, Spam, Delete). After: each row is a whole-row link showing subject, submitter identity, source page, message excerpt, relative time, and a color-coded status chip with a trailing chevron and hover highlight. No inline buttons. ## How - `feedback_row` is now a whole-row `<a href="/admin/feedback/{id}?from={tab}">` with a status chip + chevron, no forms. New `feedback_status_chip` mirrors the users `verified_indicator` (icon + short label, color-coded per status). - Triage actions live on the detail page via a new `feedback_detail_actions(id, status, tab)` helper, rendered tab-aware. The `?from=` slug is parsed by `FeedbackTab::from_query` so the detail page shows the right action set and each action redirects back to the originating list tab (the existing `from` -> `from_tab_path` redirect contract is unchanged). - Detail header now uses the same status chip, and its Back link returns to the originating tab. - Tabs, Export CSV, empty states, and pagination are untouched. The Archive tab (separate endpoint, single Restore action) is already clean and is left as-is. Action coverage moved to detail, tab-aware, nothing lost: - Active: Reviewed / Un-review, Close, Archive, Mark as spam, Delete - Closed: Re-open, Archive, Mark as spam, Delete - Spam: Not spam, Archive, Delete - Archive: Delete ## Tests - `feedback_row_links_to_detail_with_no_inline_actions` - row is a detail link with the tab slug, shows the status chip, and carries no `<form>` and none of the action endpoints. - `feedback_row_carries_originating_tab_slug` - a Spam-tab row links back with `?from=spam`. - `feedback_detail_actions_are_tab_aware` - Active vs Closed vs Spam render the correct buttons (incl. Un-review when already reviewed) with the correct `from` redirect value. - `feedback_tab_from_query_round_trips` - slug <-> tab round-trip, unknown/absent falls back to Active. `just check-container` is green (fmt + clippy -D warnings + build + full workspace tests, 141 bunyip-web tests pass). ## Verification The row and detail markup reuse the exact `icon` / `button_class` / hover + focus token classes the users rows already use, so both light and dark themes render without bespoke styling. Structural behavior (row-as-link, no inline actions, tab-aware detail actions, correct redirects) is covered by the unit tests above. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LerAorB26HGHLfjC9iDUbd
feat(admin): redesign feedback list as scannable rows linking to detail (BUNYIP-422)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 1m28s
Check / fmt + clippy + build + tests (pull_request) Successful in 8m8s
Create release / Create release from merged PR (pull_request) Has been skipped
c4bb9a7826
The admin feedback list crammed the full triage toolbar (Reply, Reviewed/Un-review, Close, Archive, Spam, Delete) inline on every row, so each row was a wall of buttons and the queue was hard to scan. This brings it to parity with the users list from BUNYIP-405: each row is now a whole-row link into the existing feedback detail page, showing subject, submitter identity, source page, a message excerpt, the relative time, and a color-coded status chip (mirroring the users verification indicator) with a trailing chevron and hover highlight. No action buttons on the row.

All triage actions move to the detail page, rendered tab-aware. The row links carry a `?from=<tab>` slug; the detail handler parses it back into the originating tab so it shows the right action set (Active: Reviewed/Un-review, Close, Archive, Mark as spam, Delete; Closed: Re-open, Archive, Mark as spam, Delete; Spam: Not spam, Archive, Delete; Archive: Delete) and each action still redirects back to the list view the admin came from. No triage capability is lost. The detail page's status badge is now the same status chip, and its Back link returns to the originating tab.

The four tabs, Export CSV, empty states, and pagination are unchanged. Reuses the existing `icon` / `button_class` / hover-token styling the users rows use, so both themes render without bespoke CSS. Adds render tests: the row links to detail with no inline forms/actions, the row carries its originating tab slug, the detail actions are tab-aware with correct `from` redirects, and the tab slug round-trips.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LerAorB26HGHLfjC9iDUbd
longjacksonle deleted branch feat/BUNYIP-422-feedback-list-redesign 2026-07-30 01:38:16 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!410
No description provided.