- IconStepStrip stays a compact horizontal row on narrow screens (smaller
tiles, label under icon, horizontal chevrons)
- tip-card-head stacks top-to-bottom with a smaller illustration
- InfoTip clamps to the viewport (collision padding clears the sticky
header, flips below when no room above, max-height scroll)
- card headers wrap on narrow screens; security subtitle gets its own line
Move prose into tap-friendly (i) tips and replace intro paragraphs with
icons, step strips and chips across settings, security, add-server,
server detail, proxy, backups, downloads, imports, marketplace and
templates.
Any failed refresh (offline, 5xx, 429) cleared both tokens, and each
expired request started its own refresh, so a burst of 401s could
trip the refresh rate limit and log the tab out. Page load also wiped
tokens on any /auth/me failure. Share one in-flight refresh, end the
session only on a 401/422 from /auth/refresh or /auth/me, and let
transient failures surface as errors with the tokens intact.
pg_create_database/user and pg_grant/revoke built superuser SQL from
raw names and passwords, unlike the MySQL helpers beside them. A quote
in a password broke CREATE USER, and the create routes ignored that
and returned credentials for a user that did not exist. Validate
identifiers and privilege lists, escape the password, and surface a
failed user as user_error instead of fake credentials.
Auto-provision defaulted on with role developer and no domain filter,
so enabling GitHub login for yourself let any GitHub user sign up and
open remote terminals, while password registration stayed closed.
Default to off and viewer; turning it on stays an explicit choice.
The vertical stepper rail floated between steps instead of joining the
markers, and the current step borrowed the focus ring. Radio cards
showed a radio dot beside the icon; the card already marks selection,
so the radio becomes a check badge in the corner.
FormField now hands its control the id, aria-describedby, aria-invalid
and aria-required through context, so every settings form announces
its hint and validation without per-call wiring. IconButton gets a real
tooltip instead of title=, ProgressBar is a labelled progressbar with
tones and an indeterminate state, and Button takes `loading` without
changing width.
New controls the panel lacked: NumberField, Combobox (single, multiple,
creatable), TagInput, Calendar with DatePicker and DateRangePicker,
PinInput, Slider, RadioGroup, Stepper, TreeView, and FileDropzone with
FileUploadList. Rounding, date and file-type rules live in lib/ with
unit tests. All of them render on /style-guide/controls.
The Templates page only featured a hard-coded list, so `featured: true`
in a template (Prompture Hub, Torre) never reached the Featured-first
view. The page now honors the flag alongside the list, and bundled
templates carry it into the catalog and the published index.
FileRow and FileCard were wrapped in memo, but every handler passed to
them was re-created on each render, so a keystroke or a selection
re-rendered every row of a large directory. useStableHandler gives the
rows fixed handler identities that still run the latest code.
The picker hardcoded ids like sp-hour, so two on one page (one per
schedule card) produced duplicate ids and every label pointed at the
first picker's field.
The pickers dropped an id, so the five labels above them named
nothing. They now put it on the trigger button; clicking the label
opens the picker. Ratchet 46 -> 41.
Three hand-rolled copies printed untranslated "3m 0s" and never
reached hours ("75m 0s"). They now use the intl formatter ("1h 15m",
in the panel language), keeping each caller's placeholder. The cron
and deploy-console formats with tenths of a second stay as they are.