Scope: Add an always-visible "Send feedback" button anchored mid-right of the viewport that opens a modal letting the user submit free-form feedback either as a Phabricator task or as a section on User talk:Daanvr on Commons. The button frames the tool as in beta to encourage feedback.
Background
T426408 (v0.28.0) already shipped most of the plumbing in src/ui/error-report-modal.jsx for the error-report flow on the hard-error panels:
- A modal that captures context (timestamp, version, deploy target, URL, user agent, plus a free-text comment), shows an editable preview body, and offers two window.open submission paths: pre-filled Phabricator task (maniphest/task/edit/form/default/?projects=tool-upload-workbench&title=&description=) and the talk-page edit form (commons.wikimedia.org/w/index.php?title=User%20talk:Daanvr&action=edit§ion=new&preloadtitle=, with the body copied to clipboard since MediaWiki's URL pre-fill for body content uses preload= and won't accept a literal multi-line string).
- No new OAuth scopes (everything is a window.open user gesture).
- Accompanying CSS in src/app.css:4104-4174 (.error-report-modal*).
This task reuses that infrastructure for the always-visible feedback flow.
Differences from "Report this error"
- Trigger: floating fixed-position button, not only shown on error.
- Pre-fill: drop timestamp, error message, stack trace. Keep version + deploy target + current URL for context (handy when feedback references "I clicked X on this page").
- Copy: encouraging "we want your feedback" framing, not "report this error".
- Beta framing: button label/styling and modal copy say "Beta — your feedback is valuable" so the affordance feels welcoming, not error-prone.
Affected code
- New: src/ui/feedback-button.jsx (floating button + thin modal wrapper, sharing the URL-builders from error-report-modal). Likely cleanest is a new src/ui/feedback-modal.jsx plus the button component, both imported (regular ESM, like the existing src/ui/ modals).
- New CSS rules in src/app.css (a .feedback-fab floating-button block + a .feedback-modal* block — or share .error-report-modal* styles where possible).
- Mounted from src/main.jsx (or src/app.jsx) at the same level as the topbar so it's visible regardless of route/state.
Behaviour
- Button is fixed-position on the right edge of the viewport, vertically centred (top: 50%; transform: translateY(-50%); right: 0;). Renders as a vertical pill with text "Feedback" or "Send feedback" + a small "Beta" indicator.
- Visible always except when a modal is open (z-index lower than .modal-backdrop so the backdrop covers it; or hide via body[data-modal-open] if simpler).
- Click opens the feedback modal:
- Title: "Send feedback"
- Lede: short encouraging copy noting the tool is in beta and any feedback (bugs, suggestions, confusing UI, "I wish it did X") is welcome.
- Comment textarea (the actual feedback) — required-ish (button greyed out if blank).
- Editable preview body — same pattern as error-report-modal: derived ## Feedback heading + comment + a tiny context table (Time, Version, URL).
- Two submit buttons: "Open Phabricator task" (window.open to maniphest create) and "Post to User talk:Daanvr" (window.open to talk-page edit + clipboard copy of the body).
- Mobile/narrow viewport: keep button on the right edge but consider hiding the text label and showing only an icon at narrow widths (≤640px) — pure CSS via media query.
Acceptance criteria
- Floating button visible mid-right on every screen of the app (login, bootstrap, main view, error panels).
- Button visually signals "Beta" (chip / tone / label).
- Click opens a modal with encouraging copy and a comment textarea.
- Both submission routes work (Phabricator task pre-fill loads with title/description; talk-page edit form loads with section title pre-filled and body on clipboard).
- No new OAuth scopes.
- No regression to the existing error-report flow on <BootErrorPanel> (T426408).
- npm run build (incl. undefined-identifier scanner) passes.
- CHANGELOG.md has an [Unreleased] entry under Added.