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
for f in tests/*.test.js; do node "$f"; done — all pass, including the
updated topbar contract test
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
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 Code
## 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 Code
Mirrors the existing unread-drawer pattern: a new dropdown next to the
notification bell, gated on templateData.support.visible (injected by
the support plugin's filter:middleware.renderHeader hook, on every page
render, for viewers with any support access at all). Opening it fetches
GET /plugins/support/notifications via the api module, renders up to
10 entries by textContent (never innerHTML), and marks everything read
via POST .../notifications/read, clearing the badge client-side.
Also present in the mobile burger drawer, same gating.
ponytail: no live socket push for this badge (core's own unread/notification
counts get one); it only catches up on the next full page load after the
box is opened. Noted in client.js as the upgrade path if that gap matters.
Verified live against sow-nodebb-plugin-support's dev NodeBB stack (theme +
plugin both mounted): icon hidden for a user with no support access, badge
count and dropdown contents correct for a reviewer, badge clears on open.
Full plain-node test suite passes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The first version of this drawer built its own rows in JS. This one renders
core's `partials/notifications_list` partial with entries the support plugin
now returns in core's notification shape, so the markup is literally the
notification drawer's: avatar block, stretched link, muted timeago, per-entry
read dot, All/Unread filter row, and the same two footer buttons. The
handlers mirror core's too — only the API paths differ, because the list is
plugin-owned (core's unread count is one aggregate with no hook to carve a
type out of it).
Opening the box no longer marks everything read: like the bell, an entry is
read when you click it or use "Mark all read", and the dot toggles both ways.
Deletes the bespoke row builder and its hand-rolled relative-time helper;
`$.timeago` is what core uses for JS-inserted rows. The dropdown reuses the
`.notifications-dropdown` class this theme already styles, so it needs no CSS
of its own. Hardcoded English is gone (the code-review finding on the first
version): every string is a translation key.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
archvillainette
changed title from Support inbox: header icon and dropdown to Support inbox drawer on the topbar, 1:1 with the notification drawer2026-07-24 20:20:35 +00:00
Reworked (4acf32e) after feedback asking for 1:1 parity with the Harmony notification drawer. The first version built its own rows in JS; this one renders core's partials/notifications_list partial and reuses core's handler shape, which also deletes the hand-rolled relative-time helper and the bespoke CSS class. The two code-review findings on the first version (hardcoded English, badge markup diverging from the precedent) are folded into the same rework.
The backend side moved with it: the support plugin now returns entries in core's notification shape and has per-nid read/unread routes, so the per-entry read dot is real rather than decorative — see sow-nodebb-plugin-support#15.
Verified live, not just unit-tested: badge, per-entry dot, unread filter, mark-all-read and the empty state, with no console errors.
Reworked (`4acf32e`) after feedback asking for 1:1 parity with the Harmony notification drawer. The first version built its own rows in JS; this one renders core's `partials/notifications_list` partial and reuses core's handler shape, which also deletes the hand-rolled relative-time helper and the bespoke CSS class. The two code-review findings on the first version (hardcoded English, badge markup diverging from the precedent) are folded into the same rework.
The backend side moved with it: the support plugin now returns entries in core's notification shape and has per-nid read/unread routes, so the per-entry read dot is real rather than decorative — see sow-nodebb-plugin-support#15.
Verified live, not just unit-tested: badge, per-entry dot, unread filter, mark-all-read and the empty state, with no console errors.
Assume the dev stack is dirty on arrival and leave it clean; the compiled
templates/client JS need an explicit build, and the build marker lives on the
container filesystem so a plain restart skips it. Also records this forum's
login selectors and the fact that waitForURL('**/') never matches NodeBB's
post-login /?loggedin=true.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Support case notifications move into the notification bell as a "Cases" tab, owned by the support plugin, so the plugin's notifications stop depending on this theme. Full design and reasoning: ShadowsOverWestgate/sow-nodebb-plugin-support#15.
templates/partials/header/topbar.tpl — drop the support icon block and the mobile-drawer support entry
public/client.js — drop the support inbox block, both support dropdown handlers, and the renderSupportMenu export
languages/en-GB/westgate.json — drop the three support-inbox.* keys
delete tests/support-drawer-client.test.js; drop the support assertions from tests/global-topbar-contract.test.js
The /support link stays where it already is in the ACP navigation, which this theme already renders in both the desktop bar and the mobile drawer. Checked the rest of the repo: no other support references, and the topbar design spec does not mention it.
## Plan change: the support drawer comes out
Support case notifications move into the notification bell as a "Cases" tab, owned by the support plugin, so the plugin's notifications stop depending on this theme. Full design and reasoning: ShadowsOverWestgate/sow-nodebb-plugin-support#15.
This PR becomes a removal:
- delete `templates/partials/header/support-drawer.tpl`
- `templates/partials/header/topbar.tpl` — drop the support icon block and the mobile-drawer support entry
- `public/client.js` — drop the support inbox block, both support dropdown handlers, and the `renderSupportMenu` export
- `languages/en-GB/westgate.json` — drop the three `support-inbox.*` keys
- delete `tests/support-drawer-client.test.js`; drop the support assertions from `tests/global-topbar-contract.test.js`
The `/support` link stays where it already is in the ACP navigation, which this theme already renders in both the desktop bar and the mobile drawer. Checked the rest of the repo: no other support references, and the topbar design spec does not mention it.
Support case notifications now live in the notification bell, as a "Cases"
filter button added by nodebb-plugin-support on core's own hooks. The plugin
owns all of it, so this theme's second bell — its icon, drawer, client code,
language keys and tests — comes out.
The theme was the wrong home for it. The drawer's markup and JS lived here, so
whether the support plugin could notify anyone depended on which theme a forum
ran. Nothing about support belongs in a theme.
The `/support` link is unaffected; it comes from the ACP navigation, which
this theme already renders in both the desktop bar and the mobile drawer.
Checked in a browser on the dev stack: no support icon in the topbar, and the
bell's new tab filters a mixed notification list correctly.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removal pushed as cc79947. Everything listed above is gone: the drawer template, the topbar icon and mobile-drawer entry, the support block and both dropdown handlers in client.js, the renderSupportMenu export, the three support-inbox.* keys, and tests/support-drawer-client.test.js.
The support assertions in tests/global-topbar-contract.test.js are replaced by one that asserts the opposite — the topbar carries no support-specific markup at all — so this cannot quietly grow back.
Checked in a browser on the dev stack: no support icon in the topbar, and the notification bell's new "Cases" tab (owned by nodebb-plugin-support) filters a mixed list of 31 notifications down to the 30 support ones and back. All eight contract tests pass and eslint is clean.
Also closes#33 while here — its unread badge and dropdown are both working on this branch, and its closing suggestion (reuse core's notification dropdown rather than maintain bespoke topbar drawers) is exactly what the support change does. Details in that issue.
Plugin side: ShadowsOverWestgate/sow-nodebb-plugin-support#15. Both need to land together in one sow-nodebb image bump, since this PR removes the UI that PR replaces.
Removal pushed as `cc79947`. Everything listed above is gone: the drawer template, the topbar icon and mobile-drawer entry, the support block and both dropdown handlers in `client.js`, the `renderSupportMenu` export, the three `support-inbox.*` keys, and `tests/support-drawer-client.test.js`.
The support assertions in `tests/global-topbar-contract.test.js` are replaced by one that asserts the opposite — the topbar carries no support-specific markup at all — so this cannot quietly grow back.
Checked in a browser on the dev stack: no support icon in the topbar, and the notification bell's new "Cases" tab (owned by `nodebb-plugin-support`) filters a mixed list of 31 notifications down to the 30 support ones and back. All eight contract tests pass and `eslint` is clean.
Also closes #33 while here — its unread badge and dropdown are both working on this branch, and its closing suggestion (reuse core's notification dropdown rather than maintain bespoke topbar drawers) is exactly what the support change does. Details in that issue.
Plugin side: `ShadowsOverWestgate/sow-nodebb-plugin-support#15`. Both need to land together in one `sow-nodebb` image bump, since this PR removes the UI that PR replaces.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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_listpartial, from entries the support plugin nowreturns in core's notification field names, inside a dropdown that copies
Harmony's
partials/sidebar/notifications.tpl. So the drawer has thenotification 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-dropdownclassesthis 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
for f in tests/*.test.js; do node "$f"; done— all pass, including theupdated topbar contract test
support:viewallholder: 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
are structurally identical
Depends on sow-nodebb-plugin-support#15 for the endpoints.
Generated with Claude Code
Support inbox: header icon and dropdownto Support inbox drawer on the topbar, 1:1 with the notification drawerReworked (
4acf32e) after feedback asking for 1:1 parity with the Harmony notification drawer. The first version built its own rows in JS; this one renders core'spartials/notifications_listpartial and reuses core's handler shape, which also deletes the hand-rolled relative-time helper and the bespoke CSS class. The two code-review findings on the first version (hardcoded English, badge markup diverging from the precedent) are folded into the same rework.The backend side moved with it: the support plugin now returns entries in core's notification shape and has per-nid read/unread routes, so the per-entry read dot is real rather than decorative — see sow-nodebb-plugin-support#15.
Verified live, not just unit-tested: badge, per-entry dot, unread filter, mark-all-read and the empty state, with no console errors.
Assume the dev stack is dirty on arrival and leave it clean; the compiled templates/client JS need an explicit build, and the build marker lives on the container filesystem so a plain restart skips it. Also records this forum's login selectors and the fact that waitForURL('**/') never matches NodeBB's post-login /?loggedin=true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Plan change: the support drawer comes out
Support case notifications move into the notification bell as a "Cases" tab, owned by the support plugin, so the plugin's notifications stop depending on this theme. Full design and reasoning: ShadowsOverWestgate/sow-nodebb-plugin-support#15.
This PR becomes a removal:
templates/partials/header/support-drawer.tpltemplates/partials/header/topbar.tpl— drop the support icon block and the mobile-drawer support entrypublic/client.js— drop the support inbox block, both support dropdown handlers, and therenderSupportMenuexportlanguages/en-GB/westgate.json— drop the threesupport-inbox.*keystests/support-drawer-client.test.js; drop the support assertions fromtests/global-topbar-contract.test.jsThe
/supportlink stays where it already is in the ACP navigation, which this theme already renders in both the desktop bar and the mobile drawer. Checked the rest of the repo: no other support references, and the topbar design spec does not mention it.Removal pushed as
cc79947. Everything listed above is gone: the drawer template, the topbar icon and mobile-drawer entry, the support block and both dropdown handlers inclient.js, therenderSupportMenuexport, the threesupport-inbox.*keys, andtests/support-drawer-client.test.js.The support assertions in
tests/global-topbar-contract.test.jsare replaced by one that asserts the opposite — the topbar carries no support-specific markup at all — so this cannot quietly grow back.Checked in a browser on the dev stack: no support icon in the topbar, and the notification bell's new "Cases" tab (owned by
nodebb-plugin-support) filters a mixed list of 31 notifications down to the 30 support ones and back. All eight contract tests pass andeslintis clean.Also closes #33 while here — its unread badge and dropdown are both working on this branch, and its closing suggestion (reuse core's notification dropdown rather than maintain bespoke topbar drawers) is exactly what the support change does. Details in that issue.
Plugin side:
ShadowsOverWestgate/sow-nodebb-plugin-support#15. Both need to land together in onesow-nodebbimage bump, since this PR removes the UI that PR replaces.