Admin: a module card is a status line until you open it

Every module's settings were always spread out, so the page read as a wall
of forms. A card now shows what you check at a glance — dot, name, version,
description, status readout, the enabled switch, Uninstall — with one button
at the bottom right: Configure opens the settings and becomes Apply, which
saves without closing them. Clicking the module name opens and closes the
settings too (keyboard as well: it is a focusable button). A card stays open
across a reload for the rest of the session, so re-checking something after
an Apply doesn't fold it away. A module with nothing to configure has no
button.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Waters Church
2026-09-13 14:03:10 -04:00
co-authored by Claude Fable 5.1
parent b9d9e2894a
commit e7b0ea6ebf
2 changed files with 30 additions and 5 deletions
+25 -3
View File
@@ -585,15 +585,37 @@ function buildModuleCard(mod) {
const actions = document.createElement('div');
actions.className = 'module-actions';
const save = document.createElement('button');
save.className = 'btn primary';
save.textContent = 'Apply';
const status = document.createElement('span');
status.className = 'admin-status';
actions.append(status, save);
form.appendChild(actions);
// A card is a status line until someone wants to change something: the
// form starts folded, and the row at the bottom holds one button that
// does both jobs — "Configure" opens the form and becomes "Apply", which
// saves without closing it. The name is the other way in and out.
card.appendChild(form);
card.appendChild(actions);
const openKey = 'proddash:admin:open:' + mod.id;
const setOpen = (open) => {
form.hidden = !open;
status.hidden = !open;
save.textContent = open ? 'Apply' : 'Configure';
save.className = open ? 'btn primary' : 'btn';
try { sessionStorage.setItem(openKey, open ? '1' : '0'); } catch { /* fine */ }
};
let wasOpen = false;
try { wasOpen = sessionStorage.getItem(openKey) === '1'; } catch { /* fine */ }
setOpen(wasOpen);
name.classList.add('is-toggle');
name.title = 'Show or hide this module\'s settings';
name.tabIndex = 0;
name.setAttribute('role', 'button');
name.addEventListener('click', () => setOpen(form.hidden));
name.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpen(form.hidden); }
});
save.addEventListener('click', async () => {
if (form.hidden) return setOpen(true);
const config = {};
for (const [key, read] of readers) config[key] = read();
save.disabled = true;