Support inbox drawer on the topbar, 1:1 with the notification drawer (#45)

## Summary

A Support inbox drawer on the topbar, next to the notification bell, fed by
the plugin-owned support inbox in sow-nodebb-plugin-support#15.

It is not a lookalike: the rows are rendered with core's own
`partials/notifications_list` partial, from entries the support plugin now
returns in core's notification field names, inside a dropdown that copies
Harmony's `partials/sidebar/notifications.tpl`. So the drawer has the
notification drawer's avatar block, stretched link, muted timeago, per-entry
read dot, All/Unread filter row, and the same two footer buttons — and needs
no CSS of its own, because it reuses the `.notifications-dropdown` classes
this theme already styles.

Behaviour matches the bell too: opening the box does not mark anything read;
an entry is read when you click it or use "Mark all read", and the dot toggles
both ways. Only the API paths differ, because the list is plugin-owned (core's
unread count is one aggregate with no hook to carve one type out of it).

Every string is a translation key.

## Test plan

- [x] `for f in tests/*.test.js; do node "$f"; done` — all pass, including the
      updated topbar contract test
- [x] Live against a dev NodeBB as a `support:viewall` holder: badge count 4,
      four rows, per-entry read dot drops the badge to 3, Unread filter hides
      the read row, "Mark all read" clears every dot and hides the badge,
      empty state reads "Nothing new" — no console errors
- [x] Screenshotted side by side with the real notifications dropdown; the two
      are structurally identical

Depends on sow-nodebb-plugin-support#15 for the endpoints.

Generated with Claude CodeReviewed-on: #45

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
This commit was merged in pull request #45.
This commit is contained in:
2026-07-24 21:46:02 +00:00
committed by archvillainette
parent 0bdb59aaa0
commit 9c6e2963e9
124 changed files with 29 additions and 52393 deletions
+15
View File
@@ -57,6 +57,21 @@ for driving a headless browser on this NixOS box (the Playwright MCP server
does not work here). Point any browser tooling at `http://localhost:4567` to
load pages, take screenshots, and compare before/after.
**Assume the stack is dirty when you arrive, and leave it clean.** Reset it
(`make dev-reset`) before the first boot of a testing session and tear it down
after every cycle, including a failed one; a stack carrying the last session's
data is the usual reason a screenshot shows something that no longer exists in
the code. Full hygiene rules live in `../sow-nodebb/AGENTS.md`. Two things
that bite here in particular:
- **Templates and client JS are compiled**, so a browser reload alone proves
nothing after editing them. `make dev-build` — and note the build marker
lives on the container filesystem, so a plain `restart` skips the rebuild.
- **Playwright login on this forum**: the form is `#username` / `#password`
with a `#login` submit button, and a successful login lands on
`/?loggedin=true`, which `page.waitForURL('**/')` never matches. Wait on
`page.waitForLoadState('networkidle')` instead.
## Design Context
- `PRODUCT.md`: strategic design context — register, users, purpose,