The Devices page's Pending Device Registrations section (Approve/Reject cards broadcast to every account) is replaced by an always-visible Pair a Device field: type the 6-digit code shown on the registering e-reader, a templ-rendered confirm card shows what will be bound, and confirming claims the device to the signed-in account. Rendering ownership (AGENTS.md): the confirm card and every lookup outcome are templ partials (PairingLookupResult) swapped by htmx from a new SSR route POST /devices/pairing/lookup — the server decides what UI looks like, no JSON-built HTML. Errors render as content because htmx only swaps 2xx bodies (the route is web-only; the JSON API keeps real status codes), and one delegated htmx:responseError listener in device-management.ts toasts the non-swap failure path. The claim confirm button posts straight to /api/devices/claim; success comes back as HX-Refresh (same pattern as token regeneration), so the page reloads into the paired state. No new TS module is needed — plain htmx attributes drive the whole flow. Ride-alongs: the Add New Device modal loses the device-type select and the kobo manual form (its post-register UX depended on the broadcast list and silently produced an unclaimable registration; native Kobo sync is still server-side-only and will get its own pairing UX when it lands) — the modal is now a single Connect-a-KOReader-Device guide with the pairing steps. PendingRegistrationData, convertPending, and the pending plumbing in the page handler are gone with the section. ui-controls.md glossary and tests/ui COVERAGE.md updated in the same commit as the control rename, per the drift gates.
14 KiB
14 KiB
UI controls glossary
The canonical spellings for controls cited across the UI documentation. Docs
quote the label exactly as this page lists it — one entry per control; two
spellings of one control is a defect. The controls block is machine-read:
when a doc first names a control, add its entry in the same commit; when a
rename lands, update the entry in the same commit and the gate goes green
again.
Entry fields:
label— the exact rendered text users seewhere— semantic path (page → section/card), never spatial; see the writing standarddoes— what interacting with it produces (the outcome)source— optional; defaulttempl(templates/*.templ);tssearchesweb/srcalso— optional, pipe-separated extra literal fragments to search when the visible label is Alpine-composed rather than static (OR-checked withlabel)note— optional clarifier
Form-field labels inside a single modal (Name, Description…) are cited inline in docs and not tracked here; this list carries the controls people navigate by.
Dashboard, profile & podcasts
label: Customize Dashboard
where: Library bar on the dashboard (button); opens the Customize Dashboard panel
does: Opens per-library shelf arrangement — drag order, show/hide switches, items per section.
label: Save Changes
where: Customize Dashboard panel → submit
does: Saves that library's shelf arrangement.
label: Refresh
where: Library bar on the dashboard (button)
does: Re-reads libraries without a full page reload.
note: icon button with a tooltip title
label: Create Custom Section
where: the custom-section builder page (/custom-section) → page title
does: Page where a dashboard shelf is defined by filter rules or hand-picked books.
label: Update Password
where: profile page → Change Password → submit
does: Saves the new password after live requirement checks.
label: Remove My Account
where: profile page → Danger Zone
does: Deletes the account and all personal data after confirmation; blocked for the last admin.
label: Add Feed
where: Podcasts page
does: Opens the Add Podcast Feed panel.
label: Add & Subscribe
where: Add Podcast Feed panel → submit
does: Subscribes the feed and starts watching it for new episodes.
also: Add & Subscribe
note: templ source stores the ampersand entity; the rendered label reads "Add & Subscribe"
label: Download all episodes now
where: Add Podcast Feed panel
does: Grabs the feed's back catalog immediately on subscribe.
label: Player settings
where: audio player → settings control
does: Opens the per-player preferences — Autoplay on open, Default playback speed, Resume rewind.
also: title="Settings"
label: Shortcuts & interactions
where: audio player → the ? control
does: Lists every keyboard shortcut the player supports.
also: Shortcuts & interactions
note: templ source stores the ampersand entity
label: Chapters
where: audio player → chapter-list control
does: Opens the chapter list and shows the current chapter position.
note: title attribute on the control
label: Bookmarks
where: audio player → bookmarks control
does: Opens your markers for this title; tap one to jump back.
note: title attribute on the control
Collections
label: New Collection
where: Collections page
does: Opens the create-collection modal.
note: the empty page offers the same action as "Create Your First Collection"
label: Create Your First Collection
where: Collections page, when no collections exist
does: Opens the create-collection modal.
label: Create Collection
where: create-collection modal → submit
does: Saves the new collection and returns to the Collections page.
label: Update Collection
where: edit-collection modal → submit
does: Saves your changes to the collection.
label: Static
where: create-collection modal → Type
does: Chooses a hand-picked collection — you add and remove items yourself.
label: ⚡ Smart
where: create-collection modal → Type; also shown as a badge on smart collections page and detail
does: Chooses a rules-matched collection — its membership stays current by itself.
label: Rules scope
where: create-collection modal, when Smart is chosen
does: Asks what the rules ask about — the two buttons below it.
also: 📚 Books|🎧 Podcast episodes
note: "Books" and "Podcast episodes" as the two scope buttons
label: Restore System
where: Collections page
does: Opens a pick-a-shelf modal to bring back a system collection you deleted.
label: Restore
where: Restore System Collection modal → submit
does: Brings the selected system collection back.
label: Edit Rules
where: collection detail page
does: Opens the smart-collection rules editor for this collection.
label: Filter tree
where: smart-collection rules editor
does: The area where the group and rules are built.
note: read/write rules — the how is the filter guide
label: Apply to Collection
where: smart-collection rules editor → save
does: Saves the filter tree and makes the collection match those rules from now on.
label: Add Items
where: collection detail page
does: Opens the item picker window.
label: Add Selected
where: item picker → footer
does: Adds everything checked in the picker to the collection.
label: Remove Selected
where: collection detail page
does: Opens a confirm dialog to remove the checked items from the collection.
label: Search within collection...
where: collection detail page → search box
does: Filters the displayed items — nothing is removed.
label: Play as Sequence
where: collection detail page (when it has a downloaded episode)
does: Plays the collection's episodes one after another in the listening order you pick.
label: Hide finished books (reading-queue mode)
where: edit-collection modal
does: Finished books disappear from the collection's shelf.
label: Show Up Next strip
where: edit-collection modal
does: Adds this collection's Up Next strip to the podcast page.
Everywhere else
label: Filters
where: All Books / Podcasts page → toolbar
does: Opens the filter drawer for building and applying rules.
label: Find device
where: Devices page → Pair a Device
does: Looks up the pairing code shown on the registering e-reader and renders the confirm card.
label: Pair device
where: Devices page → Pair a Device → confirm card
does: Binds the device behind the pairing code to the signed-in account.
label: Download All
where: Podcast page → episodes area
does: Queues every episode of the feed for download.
label: Download order
where: Add Podcast Feed panel; podcast feed settings
does: Sets the ordering used when feed episodes are downloaded.
label: Match ALL / Group ANY header
where: filter drawer → group header (also smart collections → Rules and dashboard sections)
does: Sets how the group combines its rules; clicking the header flips ALL/ANY.
also: ? 'Match' : 'Group'|? 'ANY' : 'ALL'
note: label is Alpine-composed — 'Match' for the whole builder, 'Group' for nested; docs write it as MATCH ALL / MATCH ANY
label: Reset to Scanned
where: book detail → edit modal → scan information area
does: Restores scanner-extracted metadata over manual edits.
label: Auto-Scan
where: Settings page → Scanning section
does: Enables automatic periodic library scanning on the interval below it.
label: Scan Interval (seconds)
where: Settings page → Scanning section
does: Sets the seconds between automatic scans.
label: Force Rescan All Libraries
where: /admin dashboard → Quick Actions
does: Force-rescans every library — re-reads each file, re-extracts metadata with original-scan semantics, and recomputes hash identifiers. Unlike the shallow per-library and per-folder scans, nothing unchanged is skipped; this is the admin's backfill tool.
also: Scan All Libraries
note: renamed 2026-11-02 — the old label under-promised a heavy operation
label: Force Rescan
where: Admin → Libraries → a library's card row
does: Force-rescans that one library — re-reads and re-extracts every file in it. Same semantics as Force Rescan All Libraries, scoped to a single library.
also: Scan
note: renamed 2026-11-02 per owner — the label now carries the force semantics instead of hiding them
label: Scan this folder
where: Admin → Libraries → a library's panel → a folder row
does: Shallow-scans only that folder's subtree — unchanged files are skipped, and items in the library's other folders are never marked missing by a partial scan.
label: Retry
where: Admin → Libraries → a library's Processing Issues page → an issue card
does: Re-runs that one item through the scanner (a per-item scan, not a library pass). Success closes the issue; failure shows the real error.
label: Retry all
where: Admin → Libraries → a library's Processing Issues page → beside the severity cards
does: Queues every issue on the page and re-runs them one at a time, showing done/total progress. Deliberately not a whole-library scan.
label: Dismiss
where: Admin → Libraries → Processing Issues → warning and info cards only
does: Closes the issue without re-processing, after a confirm. Error-severity issues cannot be dismissed.
label: Purge All Archived
where: Admin → Archived Items → page header
does: Permanently deletes every archived item and its reading history, after a confirm. The per-item alternative is Delete.
label: Merge
where: Admin → Archived Items → rows with a matching active book
does: Folds the archived copy's reading data (progress, annotations, collections) into the active copy and removes the archived entry; per-user collisions keep the active copy's data.
label: Delete
where: Admin → Archived Items rows, and other admin destructive rows
does: Permanently removes the item and its reading history — no archive, no undo. Every Delete is confirm-guarded and states the scope.
label: Create Library
where: Admin → Libraries → page header
does: Opens the create-library modal (name, optional description, library type). Type is fixed at creation — it cannot be edited later.
label: Manage
where: Admin → Libraries → a library's card row
does: Opens that library's panel: folders, user access, processing issues, edit/delete.
label: Edit Details
where: Admin → Libraries → a library's panel
does: Edits the library's name and description. Library type is not editable.
label: Delete Library
where: Admin → Libraries → a library's panel
does: Permanently deletes the library, its folder mappings, and all book records with reading progress, highlights, notes, bookmarks, and ratings. Files on disk are not touched.
label: View Archived
where: Admin → Libraries → the archived banner
does: Opens the Archived Items page.
label: Purge Archived Now
where: Admin → Libraries → the archived banner
does: Same permanent wipe as Purge All Archived on the Archived Items page, offered inline.
label: Browse
where: Admin → Libraries → a library's panel → folder form
does: Opens the server-side folder browser: walk the filesystem, Select This Folder fills the path input.
label: User Access
where: Admin → Libraries → a library's panel → section heading
does: Per-user visibility checkboxes — checked (default) shows the library to that user; unchecked hides it everywhere for them, enforced in the database.
label: Keep both
where: Admin → Hash Conflicts → a conflict group card
does: Records the resolution and stops flagging the group; every copy stays, nothing merged or removed. For intentional duplicates.
label: Keep this copy
where: Admin → Hash Conflicts → a copy row
does: Keeps that copy, folds the other copies' reading data into it, and removes their catalog rows. Files on disk are never touched.
label: Delete files
where: Admin → All Podcasts → a feed row
does: Frees the disk and resets downloaded episodes to pending; they re-download on demand. A feed refresh will NOT re-materialize them.
label: Remove
where: Admin → All Podcasts → a feed row
does: Admin-wide feed removal — episode rows, downloaded files, and every user's subscription are deleted. Instance-wide, unlike a user's own unsubscribe.
label: + Create User
where: Admin → Users → page header
does: Opens the account-creation form (hidden until clicked). Available even when public registration is disabled; password rules mirror the live Settings.
label: Edit User Profile
where: Admin → Users → a user card → Edit
does: The admin edit modal — profile fields, role, and Change Password without requiring the user's current password.
label: Save Settings
where: Admin → Settings → top card
does: Commits the Base URL and Default Timezone together.
label: Save Scan Settings
where: Admin → Settings → Scanning card
does: Commits Auto-Scan and the Scan Interval.
label: Tunable Settings — Live
where: Admin → Settings → section heading
does: Settings that apply immediately on save, grouped by area.
label: Tunable Settings — Restart Required
where: Admin → Settings → section heading
does: Settings whose saves take effect only after the server restarts; the bucket is marked in amber.
label: Default Timezone
where: Admin → Settings → System Defaults card
does: The timezone used for any user who hasn't chosen their own; governs how dates and times render for them.
label: Resume rewind
where: audio player → player settings; profile settings
does: Rewinds playback a configured few seconds when you resume.
also: Resume Rewind
note: profile page spells it capitalized
label: Reading Direction
where: book detail → edit modal
does: Chooses the direction pages advance (publisher convention — e.g. manga).
label: Scan Info
where: book detail page → info block
does: Displays scanner-supplied notes attached to the item.
also: Scan Information
note: the editable form label in the modal reads "Scan Information"