Make the support drawer core's notification drawer (sow-nodebb-plugin-support#10)

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>
This commit is contained in:
2026-07-24 22:20:04 +02:00
co-authored by Claude Opus 5
parent ca2aefa156
commit 4acf32ec09
6 changed files with 173 additions and 77 deletions
+50 -7
View File
@@ -1,9 +1,52 @@
<a class="nav-link dropdown-toggle d-flex gap-2 align-items-center" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Support inbox">
<i class="fa fa-fw fa-life-ring" aria-hidden="true"></i>
<span component="support/count" class="badge rounded-1 bg-primary {{{ if !support.unreadCount }}}hidden{{{ end }}}">{support.unreadCount}</span>
<a data-bs-toggle="dropdown" data-bs-auto-close="outside" href="#" role="button" class="nav-link dropdown-toggle d-flex align-items-center justify-content-center" aria-haspopup="true" aria-expanded="false" aria-label="[[westgate:support-inbox.title]]">
<span class="position-relative">
<i component="support/icon" class="fa fa-fw fa-life-ring" aria-hidden="true"></i>
<span component="support/count" class="position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary {{{ if !support.unreadCount }}}hidden{{{ end }}}">{support.unreadCount}</span>
</span>
</a>
<ul class="dropdown-menu wg-topbar__dropdown support-dropdown p-1 shadow" role="menu" data-wg-support-menu>
<li data-wg-support-loading class="dropdown-item disabled"><i class="fa fa-fw fa-spinner fa-spin" aria-hidden="true"></i> Support inbox</li>
<li data-wg-support-empty class="hidden"><span class="dropdown-item disabled">Nothing new</span></li>
<li data-wg-support-footer><hr class="dropdown-divider"><a class="dropdown-item wg-support-item--all" href="{relative_path}/support">Go to Support</a></li>
<ul class="notifications-dropdown dropdown-menu wg-topbar__dropdown p-1 shadow" role="menu">
{{{ if !config.hideReadNotifications }}}
<li class="d-flex gap-1 align-items-center">
<button type="button" class="btn btn-ghost btn-sm ff-secondary active px-3" data-filter="all">[[notifications:all]]</button>
<button type="button" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2" data-filter="unread">[[unread:title]] <span component="support/count" class="{{{ if !support.unreadCount }}}hidden{{{ end }}}">{support.unreadCount}</span></button>
</li>
<li class="dropdown-divider"></li>
{{{ end }}}
<li>
<div component="support/list" class="list-container notification-list overscroll-behavior-contain pe-1 ff-base ghost-scrollbar">
<div class="mb-2 p-1">
<div class="d-flex gap-1 justify-content-between">
<div class="d-flex gap-2 flex-grow-1 placeholder-wave">
<div class="placeholder" style="width: 32px; height: 32px;"></div>
<div class="flex-grow-1">
<div class="d-flex flex-column">
<div class="text-sm">
<span class="placeholder placeholder-sm col-4"></span>
<span class="placeholder placeholder-sm col-6"></span>
<span class="placeholder placeholder-sm col-7"></span>
<span class="placeholder placeholder-sm col-2"></span>
<span class="placeholder placeholder-sm col-5"></span>
</div>
<div class="text-xs">
<div class="placeholder placeholder-xs col-6"></div>
</div>
</div>
</div>
</div>
<div>
<button class="mark-read btn btn-ghost btn-sm d-flex align-items-center justify-content-center flex-grow-0 flex-shrink-0 p-1" style="width: 1.5rem; height: 1.5rem;">
<i class="unread fa fa-2xs fa-circle text-primary"></i>
</button>
</div>
</div>
</div>
</div>
</li>
<li class="dropdown-divider"></li>
<li>
<div class="d-flex justify-content-center gap-1 flex-wrap">
<a role="button" href="#" class="btn btn-sm btn-light mark-all-read flex-fill text-nowrap text-truncate ff-secondary"><i class="fa fa-check-double" aria-hidden="true"></i> [[notifications:mark-all-read]]</a>
<a class="btn btn-sm btn-primary flex-fill text-nowrap text-truncate ff-secondary" href="{relative_path}/support"><i class="fa fa-life-ring" aria-hidden="true"></i> [[westgate:support-inbox.view-all]]</a>
</div>
</li>
</ul>