Changed
- Marketplace install / uninstall queues a restart instead of asking the user to find a button. A new "Restart required" button lights up in the topbar (rendered site-wide from
_base.htmlvia amarketplace_restart_pendingcontext-processor flag) whenever one or more widget installs or uninstalls are waiting on a process restart. Click any number of Install / Update / Uninstall buttons on Settings → Widgets → Browse; the chip stays lit until you hit it, which opens the spinner modal, kicksUpdater.restart(), and auto-reloads the page when the new process is back. static/restart-form.jsno longer crashes the UX when the POST itself fails. The restart-after-submit handler used to land in the outer.catchiffetch(form.action)rejected with "Failed to fetch" (the server killing the connection before flushing the response, common when the Werkzeug reloader races the restart timer in--dev, occasional in production too). The POST-level rejection is now squashed into a resolved chain so the/healthzdown-then-up poll becomes the source of truth.- Refactor: the restart-form spinner-modal markup and its
/healthzpoll-and-reload script extracted out oftemplates/settings.htmlinto a shared partial (templates/_restart_modal.html) and a static JS file (static/restart-form.js), both included from_base.html. Any page that drops a<form data-restart-form>now inherits the full UX.