Polish the Site and Facility settings page
Booleans render as checkbox toggles, the employee/USB directory-mode settings as selfhosted/external dropdowns, and every field has a label and help text (raw keys and type-true/false text boxes are gone). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,9 @@ ADR-007 and ADR-002.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Site & Facility settings page renders booleans as toggles and the
|
||||
directory-mode settings as dropdowns, with labels and help text for every
|
||||
field (no more raw keys or type-true/false boxes).
|
||||
- System Settings tabs follow the URL: clicking a settings-rail link that
|
||||
only changes the ?tab= query (Branding, Floor Map) now switches the right
|
||||
panel, tab clicks update the URL, and browser back/forward restore tabs.
|
||||
|
||||
@@ -10,7 +10,14 @@
|
||||
<div v-else class="form-grid">
|
||||
<label v-for="s in items" :key="s.key" class="field">
|
||||
<span>{{ prettyLabel(s.key) }}</span>
|
||||
<input v-model="s.value" type="text" :placeholder="fieldHelp(s.key) ? '' : s.description" />
|
||||
<span v-if="s.valuetype === 'boolean'" class="bool-row">
|
||||
<input type="checkbox" :checked="isTrue(s)" @change="s.value = isTrue(s) ? 'false' : 'true'" />
|
||||
<span class="muted">{{ isTrue(s) ? 'Enabled' : 'Disabled' }}</span>
|
||||
</span>
|
||||
<select v-else-if="OPTIONS[s.key]" v-model="s.value">
|
||||
<option v-for="opt in OPTIONS[s.key]" :key="opt" :value="opt">{{ opt }}</option>
|
||||
</select>
|
||||
<input v-else v-model="s.value" type="text" :placeholder="fieldHelp(s.key) ? '' : s.description" />
|
||||
<small class="muted">{{ fieldHelp(s.key) || s.description }}</small>
|
||||
</label>
|
||||
|
||||
@@ -45,14 +52,30 @@ const LABELS = {
|
||||
pc_access_domain: 'PC Access Domain',
|
||||
employeeid_pattern: 'Employee ID Pattern',
|
||||
printer_hostname_template: 'Printer Hostname Template',
|
||||
dualpath_single_machine: 'Dualpath as Single Machine'
|
||||
dualpath_single_machine: 'Dualpath as Single Machine',
|
||||
employee_directory_mode: 'Employee Directory Mode',
|
||||
usb_directory_mode: 'USB Directory Mode',
|
||||
setup_complete: 'Setup Complete'
|
||||
}
|
||||
function prettyLabel(key) {
|
||||
return LABELS[key] || key
|
||||
}
|
||||
|
||||
// Enumerated settings render as dropdowns to prevent typos.
|
||||
const OPTIONS = {
|
||||
employee_directory_mode: ['selfhosted', 'external'],
|
||||
usb_directory_mode: ['selfhosted', 'external']
|
||||
}
|
||||
|
||||
function isTrue(setting) {
|
||||
return String(setting.value).toLowerCase() === 'true'
|
||||
}
|
||||
|
||||
// Inline help for site fields that need more than the stored description.
|
||||
const HELP = {
|
||||
employee_directory_mode: 'Where employee records live: selfhosted (managed in this app, with CSV import and photo uploads) or external (a read-only HR database configured via EMPLOYEE_DB_* environment variables).',
|
||||
usb_directory_mode: 'Where USB checkout data lives: selfhosted (tables in this app) or external (a separate cmmc_usb database via CMMC_USB_DB_* environment variables).',
|
||||
setup_complete: 'Set automatically when the first-run setup wizard finishes. Turning it off sends admins back to the /setup wizard on next login.',
|
||||
employeeid_pattern: 'Regular expression that a scanned/typed employee ID must match to be recognized. Default: ^\\d{9}$ (9 digits). An invalid regex is ignored and the default is used.',
|
||||
printer_hostname_template: 'Template for generating printer hostnames from an IP. Use {ip} where the dash-separated IP goes. Example: Printer-{ip}.printer.geaerospace.net',
|
||||
dualpath_single_machine: 'Treat a Dualpath pair (a dual-bay machine with one controller) as a single machine in lists, counts, and the floor map. Both bay records are always kept; detail pages stay per-bay with a sibling banner. Enter true or false. Default: true.'
|
||||
@@ -109,13 +132,24 @@ onMounted(load)
|
||||
.field > span {
|
||||
font-weight: 600;
|
||||
}
|
||||
.field input {
|
||||
.field input[type='text'],
|
||||
.field select {
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
.bool-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.bool-row input[type='checkbox'] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
.muted {
|
||||
color: var(--text-light);
|
||||
font-size: 0.85rem;
|
||||
|
||||
Reference in New Issue
Block a user