Why
Merge and Update base/head both write to the repository and can leave the browser waiting. Without a pending state the button looks idle, so a second click can accidentally run the mutation again. The same applies to other native POST actions that do real server work.
What changed
- A native POST form disables its submit button(s) as soon as it is submitted, so a second run cannot be triggered.
- After 150 ms the button icon becomes a spinner, so a fast save does not flash a loader.
- A cancelled submission restores the buttons, and
pageshowrestores them after a back/forward-cache restore. - GET forms and HTMX forms are left alone;
data-no-busyis an escape hatch. - This covers Merge, Update base/head, and other native POST actions such as release writes, repository create/rename/delete, settings saves, and opening a change request.
Checks
node --check server/web/static/app.jsgo test ./..../vole workflow check