openvibers/openvibe.community Commits

Community: empty forum lists draw the kit's empty state (#339)

OP OpenVibers committed 3 days ago · 20b217f19b · 2 files, +16 −2

A forum with no threads, a filtered list with no match and the forum index
with no forums were bare sentences with an underlined link. They now use
the shared kit's empty state and its button: start the first thread, see
everything in the forum, or see what is happening on Pulse.
test/forum-home.test.js checks the empty forum and its button.

Changes

ddiff --git a/server/render/forum.js b/server/render/forum.js
iindex 633e398..8660f0b 100644
---- a/server/render/forum.js
++++ b/server/render/forum.js
@@@ -77,7 +77,7 @@ function spacesPage({ spaces }) {
${s.description ? `<p class="muted">${esc(s.description)}</p>` : ''}
<p class="small muted">${num(s.thread_count)} ${s.thread_count === 1 ? 'thread' : 'threads'}${s.last_activity_at ? ` · last activity ${timeTag(s.last_activity_at)}` : ''}</p>
</li>`).join('')}
-- </ul>` : '<p class="empty">No forums yet.</p>';
++ </ul>` : kit.empty({ icon: 'chat', title: 'No forums yet', text: 'No forum has been started here yet.', action: { href: '/pulse', label: 'See what is happening', icon: 'live' } });
const body = `
<header class="page-head">
<nav class="crumbs" aria-label="Breadcrumb"><a href="/">Home</a> › <span aria-current="page">Forum</span></nav>
@@@ -154,7 +154,7 @@ ${chatRoom}
${categoryNav}${statusNav}
<nav class="tabs sort-tabs" aria-label="Sort threads">${tabs}</nav>
<section data-results>
-- ${threads.length ? `<ol class="thread-list">${threads.map((t) => threadRow(t, space)).join('')}</ol>` : filtered ? `<p class="empty">Nothing here yet. <a href="${esc(spaceHref(space.slug))}">See everything in ${esc(space.name)}</a>.</p>` : canStart ? `<p class="empty">No threads yet — <a href="/forum/${esc(space.slug)}/new">start the first one</a>.</p>` : '<p class="empty">Nothing here yet.</p>'}
++ ${threads.length ? `<ol class="thread-list">${threads.map((t) => threadRow(t, space)).join('')}</ol>` : filtered ? kit.empty({ icon: 'search', title: 'Nothing here yet', text: 'No thread matches these filters.', action: { href: spaceHref(space.slug), label: `See everything in ${space.name}`, icon: 'grid' } }) : canStart ? kit.empty({ icon: 'chat', title: 'No threads yet', text: 'This forum has no thread yet.', action: { href: `/forum/${space.slug}/new`, label: 'Start the first thread', icon: 'plus' } }) : kit.empty({ icon: 'chat', title: 'Nothing here yet', text: 'No thread has been started here yet.', action: { href: '/forum', label: 'See the other forums', icon: 'grid' } })}
${pager((n) => spaceHref(space.slug, { sort, page: n, category, status }), page, pages)}
</section>
${footer}
ddiff --git a/test/forum-home.test.js b/test/forum-home.test.js
iindex b0e3b6a..643bff6 100644
---- a/test/forum-home.test.js
++++ b/test/forum-home.test.js
@@@ -59,6 +59,20 @@ const { boot, check, done } = require('./helpers/app');
assert.strictEqual(r.status, 308);
assert.strictEqual(r.headers.get('location'), '/forum/general/hello/reply');
});
++ await check('a forum with no threads draws the kit empty state and one button to start one', async () => {
++ const forumStore = require('../server/forum/store');
++ const db = t.app.locals.db || t.db;
++ await forumStore.createSpace(db, { slug: 'plain-pages-empty', name: 'Quiet forum', created_by: 'staff', visibility: 'public' });
++ const r = await t.get('/forum/plain-pages-empty');
++ assert.strictEqual(r.status, 200);
++ assert.match(r.text, /class="ovk-empty"/, 'the kit empty state is used, not a bare sentence');
++ assert.match(r.text, /This forum has no thread yet/);
++ assert.match(r.text, /class="ovk-btn[^"]*" href="\/forum\/plain-pages-empty\/new"/, 'the empty state offers the button that starts the first thread');
++ const filtered = await t.get('/forum/plain-pages-empty?sort=top');
++ assert.strictEqual(filtered.status, 200, `filtered page ${filtered.status}`);
++ assert.match(filtered.text, /class="ovk-empty"/, 'the empty list keeps the kit empty state under another sort');
++ });
++
await t.close();
done();
})().catch((e) => { console.error(e); process.exitCode = 1; });