Files
Bohan Jiang 37f3bb7dd9 MUL-5587: fix(autopilots): tell the user which required field blocks Create (#6231) (#6237)
* fix(autopilots): tell the user which required field blocks Create (MUL-5587)

The create dialog gated its submit button with native `disabled` on an
empty title, an unpicked assignee, or a server-rejected schedule. A
natively disabled button is neither hoverable nor focusable, so a user
who had not picked an assignee got a dead grey control and no hint about
what was missing (GitHub #6231) — the assignee picker looks exactly like
the optional Project and Subscribers pickers beside it, and nothing said
only that one was required.

An unmet requirement now uses `aria-disabled` instead: the button still
takes the hover that shows a tooltip naming the missing field, and still
takes the click, which reveals an inline error under the field at fault
and focuses it. `handleSubmit` is the real gate either way, so nothing
can be submitted that could not be before. The assignee section also
carries a required marker up front, so the dead end is avoided rather
than only explained.

The three states come from one `submitBlock` value shared by the button,
the tooltip, the inline errors and `handleSubmit`, so a rendered
affordance cannot disagree with what submitting actually does.

Co-authored-by: multica-agent <github@multica.ai>

* refactor(autopilots): stop dimming Create at all — the click is the feedback (MUL-5587)

Follow-up on review. The previous commit kept the button greyed via
`aria-disabled` and explained the grey with a tooltip. Since a blocked
click now intercepts and points at the offending field, the greying earns
nothing: drop `aria-disabled`, the dimming classes and the tooltip, and
let the button be an ordinary live button whenever a save isn't already
in flight.

The schedule case no longer scrolls to the editor's inline error and
returns. It falls through to `scheduleGate.ensureAccepted`, which re-asks
the server and toasts its actual reason — visible feedback where the
scroll could be a no-op, and it self-heals when a stored expression the
server once rejected is accepted again.

That leaves nothing in this dialog reading the gate's `scheduleValid`, so
its `onValidityChange` / `clearRejection` wiring goes too rather than
sitting inert. The shared hook keeps them for the detail page's
add-trigger dialog, which still gates on it.

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: Bohan-J <bohan@devv.ai>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-01 11:04:10 +08:00
..