Take the support drawer back out of the topbar (sow-nodebb-plugin-support#10)

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>
This commit is contained in:
2026-07-24 23:28:00 +02:00
co-authored by Claude Opus 5
parent 9d4adca127
commit cc799475f2
6 changed files with 8 additions and 254 deletions
+7 -51
View File
@@ -181,60 +181,16 @@ assertIncludes(
'Topbar styles should cover the unread dropdown'
);
const supportDrawer = read('templates/partials/header/support-drawer.tpl');
assertIncludes(
topbar,
'<!-- IMPORT partials/header/support-drawer.tpl -->',
'Topbar should mount the support inbox drawer'
);
assertIncludes(
topbar,
'{{{ if support.visible }}}',
'Support inbox drawer should be gated on the viewer having any support access'
);
// Support case notifications live in the notification bell, added by
// nodebb-plugin-support on core's own hooks. This theme owns nothing about
// them, which is the point — see that plugin's ADR-0002.
assert(
topbar.indexOf('partials/sidebar/notifications.tpl') < topbar.indexOf('partials/header/support-drawer.tpl'),
'Support inbox should sit next to (after) the notifications bell'
);
assertIncludes(
supportDrawer,
'component="support/count"',
'Support toggle should carry its own unread count badge'
);
assertIncludes(
supportDrawer,
'component="support/list"',
'Support dropdown menu should expose the JS mount hook'
);
assertIncludes(
supportDrawer,
'notifications-dropdown',
'Support drawer should reuse Harmony\'s notification dropdown styling, not a bespoke class'
);
assertIncludes(
supportDrawer,
'notification-list',
'Support inbox list should reuse Harmony\'s own notification-list styling, not a bespoke class'
);
['data-filter="unread"', 'mark-all-read', 'mark-read'].forEach((marker) => {
assertIncludes(
supportDrawer,
marker,
`Support drawer should offer the same controls as the notification drawer (${marker})`
);
});
assertIncludes(
supportDrawer,
'[[westgate:support-inbox.title]]',
'Support inbox strings should be translation keys, matching every other topbar item'
);
assertMatches(
topbar,
/href="\{relative_path\}\/support"[^>]*>[\s\S]*?component="support\/count"/,
'Mobile drawer actions should include a Support inbox link with count badge'
!/support/i.test(topbar),
'Topbar should carry no support-specific markup'
);
assertIncludes(
stylesheet,
'.wg-topbar .notifications-dropdown',
'Topbar styles should cover the notification-style dropdowns the support inbox reuses'
'Topbar styles should cover the notification dropdown'
);
-28
View File
@@ -1,28 +0,0 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const client = fs.readFileSync(path.join(__dirname, '..', 'public', 'client.js'), 'utf8');
assert(
client.includes("'show.bs.dropdown.westgateSupport'"),
'client.js should fetch the support inbox when its dropdown opens'
);
assert(
client.includes("'/plugins/support/notifications'"),
'client.js should load the support inbox from the plugin API via the api module (for CSRF-safe writes)'
);
assert(
client.includes("'/plugins/support/notifications/read'"),
'client.js should mark the support inbox read when it is opened with unread entries'
);
assert(
client.includes('renderSupportMenu'),
'client.js should expose the support inbox menu renderer'
);
assert(
/textContent/.test(client) && !/innerHTML\s*=[^=]*bodyShort/.test(client),
'Support inbox entry text must be inserted via textContent, never innerHTML'
);