Pattern: settings & admin
Who uses it: a workspace admin, occasionally a first-time
setup wizard. How often: rarely per person, but every
workspace has one. What "done" looks like: a section's
values saved, or an unsaved change clearly marked before the admin
navigates away. Composed entirely from existing components —
.bo-tabs to split General/Users/Notifications,
.bo-form-section fieldsets, .bo-checkbox for
on/off preferences (there is no separate "switch" component — a labeled
checkbox already covers the same setting, per the "one component, many
settings" principle), and the data table for the user list. Nothing new
to learn.
Not for a single end user's own preferences — this
screen is workspace-wide configuration an admin changes for everyone
(tabs, a member list, org defaults). One person editing their own
notification or display preferences needs none of that surface; use a
plain detail form scoped to
that person instead.
| Name | Role | Status |
|---|---|---|
| Admin | Active | |
| Member | Active | |
| Member | Invited |
Tabs require initTabs() —
wired below, same as every other tabbed page.
Anatomy
- Section navigation — tabs or a sub-sidebar; each section is its own form and saves independently.
- Form sections —
.bo-form-sectionfieldsets grouping related settings. - Save bar — sticky
.bo-form-actions, scoped to the current section. - Danger zone — destructive settings visually separated, each behind a confirm dialog. Not shown in the demo below (nothing in this workspace's settings is destructive); the contract is specified in this page's Data contract section, under the reset endpoint, for a screen that needs one.
Data contract
| Request | Returns / on failure |
|---|---|
| GET /settings/:section | the section form with current values |
| POST /settings/:section | the section re-rendered with a success banner; 422 → the same form with field errors and values kept |
| POST /settings/:section/reset | defaults restored — behind a confirm dialog, never a bare button |
States
| State | What ships |
|---|---|
| Saved | a success alert in the section, not a global toast — the user needs to know WHICH section saved |
| Unsaved changes | a dirty marker in the save bar; warn on section switch, not just on unload |
| Validation error | field-level messages; focus the first invalid control |
| Read-only (non-admin) | render values as key-value facts and omit the save bar |
| Destructive action (not in this demo) | confirm dialog naming the exact consequence and requiring the object name typed for irreversible ones |
| No JS | the tabbed sections need initTabs() to switch panels — without it, whichever panel the server marked visible (not hidden) is the only one reachable, since the inactive tabs' panels carry a static hidden attribute and clicking a tab does nothing |
Components used
complexity 2 of 4