feat(opal): error toast actions, DropdownLoader and dropdown fixes

Merged
RA
1d ago
+282-52

Description

Opal changes for the admin settings stack. Nothing in the app uses the new pieces until the third PR in the stack (model load states).

  • Fixed: a dropdown that is disabled while it saves no longer flashes open when it is re-enabled. Disabling an open dropdown now closes it, and its list always plays its close animation.
  • LineLoader takes a height: each bar sits centred in a line of that height, so the shimmer lines up with the text beside it. height is a new LineHeight type, a closed Spacing step matching the --height-line-* tokens (default 5, 20px). The Plugins pages' two-line loaders become about 8px taller.
  • Toasts take an id: a toast with the id of a live one replaces it in place.
  • Toasts take an action: an icon button left of the close button, with its label as the tooltip. A click runs it, and the toast stays open.
  • New useErrorToast hook: shows a persistent error toast, with an optional Retry button, while a fetch is failing. A retry that fails again updates the toast in place, so it does not flash or animate in again; it is removed when the error clears.
  • New DropdownLoader: a select that has not loaded, drawn as the input's shell with a shimmering icon and label and a static chevron.
  • Disabled and invalid inputs: a disabled input with an invalid field shows the error border.

Changes

Additional States

  • error state
  • disabled state
  • error + disabled state
image

Loader edits

  • Added dropdown-loaders
  • Added variable line-heights to line-loaders

https://github.com/user-attachments/assets/6687b15e-c3ff-495b-bc41-f85d8a87d418

Disabled while loading

https://github.com/user-attachments/assets/3eda28e3-b8a6-43cf-b3f7-e5b12dda7d55

Summary by cubic

Reorganizes the Chat Preferences and Language Models admin pages and standardizes how their settings behave. Chat Preferences is now split into Chat and Search cards, Temperature and Reasoning Control move to Language Models, and "Disable Default Chat" becomes "Always Start with an Agent."

Behavior changes

  • Model selects (Chat Naming, Search Selection, personal language) start with a Global Default row naming the fallback; picking it clears the override.
  • Model pickers never list hidden models, except the current value.
  • Auto Mode is disabled, with a tooltip, when no router model exists; the Router Model row hides then.
  • Success toasts are removed from these pages and Settings; failures still toast, and model-load failures show a persistent error toast with a retry button while the select stays, disabled with an error border.
  • e2e helpers wait for the save response instead of the toast.

Opal

  • Toasts accept an id (replacing a live toast) and an action button; useErrorToast raises one for a failed fetch.
  • Adds DropdownLoader, and LineLoader bars now sit centered in a configurable LineHeight.
  • Fixes a disabled dropdown flashing open on re-enable.

Summary by CodeRabbit

  • New Features

    • Added accessible dropdown loading states with shimmer placeholders.
    • Added configurable loader heights for improved layout flexibility.
    • Toasts now support action buttons and persistent error notifications with optional retry actions.
    • Toasts with matching identifiers update in place.
  • Bug Fixes

    • Disabling an open dropdown now closes it with its normal exit animation.
    • Disabled inputs with invalid fields now display an error border.
    • Toast dismissal and replacement behavior now provide smoother transitions and cleanup.
  • Documentation

    • Updated component guidance for dropdowns, loaders, and toast actions.