Skip to content

Ask and report in the app's own dialogs, not the window's confirm() and alert() - #665

Merged
ryanwelcher merged 1 commit into
trunkfrom
fix/replace-confirm-and-alert
Oct 8, 2026
Merged

ryanwelcher merged 1 commit into
trunkfrom
fix/replace-confirm-and-alert

Conversation

@ryanwelcher

Copy link
Copy Markdown
Collaborator

Why

Five places still used the window's confirm() and alert(). The message was translated, but Electron draws those dialogs and their OK and Cancel buttons in English whatever the language. Found in the en-XA walk (#658).

What changes

  • The three discard questions (Discard all changes, the discard that answers loose edits on trunk before a switch, and Discard & update before a trunk update) now ask in the app's own dialog, the same ConfirmDialog a deletion already uses through askFirst. confirmAnd is gone.
  • The two failures (a path that could not be copied, and a dev server started before there is a build) are said in the window's error notices, confirm(message, { tone: 'error' }), which stay until dismissed.
  • Each question is a { title, description, confirm } object, like the deletion questions: discardQuestion() in changes-note.cjs replaces discardConfirmMessage(), and discardTrunkEditsQuestion() is new in ticket-actions.cjs. The yes button says what it does: Discard changes or Discard edits.
  • Two of the discards are asked from inside the older library's modals (the review dialog and the question before an update), whose overlay sits at z-index 100000 and covered the new dialog. The dialog's own portal now sets --wp-ui-dialog-z-index: 100000 in shell.css. That puts it level with those modals, and because its portal is added to the page later, it shows on top. The toast stack stays above it.
  • No confirm() or alert() is left in src/renderer, and the no-alert exceptions are gone.

How to test this

Journeys cover the whole flow and are red without the change:

# from the repository root
npm run build:once
npx playwright test --project=journeys tests/e2e/journeys/i18n.spec.js tests/e2e/journeys/trunk-update.spec.js tests/e2e/journeys/review-changes.spec.js tests/e2e/journeys/pr-checkout.spec.js
  • i18n.spec.js ("the ticket card's questions…" and "the trunk banners, the question before an update…") opens each of the three questions in en-XA and checks that the title, the yes button and Cancel are all bracketed. I checked it goes red when the button label skips __().
  • trunk-update.spec.js ("an update asks before it resets edits…") answers Cancel in the new dialog over the update question, then checks that the edit and the update question are both still there. It then answers yes and checks that the update runs. Before the stacking fix this was red, because the update modal's overlay intercepted the click.
  • review-changes.spec.js and pr-checkout.spec.js check that the discard asks first and touches nothing while it asks, then answer yes.

The journeys cannot tell you how the dialog looks over another modal, so look at that by hand. Platform: either; build: the current head.

Starting state: a site with an uncommitted edit to any tracked file, opened with npx electron . --lang=en-XA from the repository root (or the Buildkite build for the current head with the system language set to something translated).

  1. Click Review & submit changes (bracketed in en-XA), then Discard all changes. Expected: a dialog over the review asks Discard all local changes? with two buttons, Discard changes and Cancel, all bracketed. No dialog drawn by the system appears.
  2. Click Cancel. Expected: the dialog closes, the review is still open, and the diff still shows your edit.
  3. Close the review, open the site menu and choose Update to latest trunk. Choose Discard them, then Discard & update. Expected: the same question appears over the update dialog, which stays visible under it.
  4. Click Cancel. Expected: the update dialog is still open, and your edit is still in the file.
  5. Close the update dialog. Link a new ticket number while the edit is still there, and click Discard them and start clean in the question on the ticket card. Expected: a dialog asks Discard the uncommitted edits on trunk? with Discard edits and Cancel. Click Cancel: the edit is still in the file and the card still asks what to do with it.
  6. To see a copy failure, open DevTools (View → Toggle Developer Tools), run navigator.clipboard.writeText = () => Promise.reject(new Error('blocked')), then click Copy beside the path in the site's details (or Copy path in the site menu). Expected: a red notice in the bottom corner says Unable to copy path: blocked and stays until dismissed. Before this change it was a system alert.

What must not have happened:

  • Cancelling any of the three questions must not discard anything: the file keeps your edit, and the review or update dialog under it stays open.
  • Pressing Discard changes inside the review must not close the review before the discard reports back. It should then say there are no changes.
  • No system-drawn dialog (English OK and Cancel) appears anywhere in these flows.

Risks and limitations

  • The dev-server notice (Please complete the full build…) cannot be reached by hand. Every path that starts the server is either hidden or disabled until the site is built, so the guard is defensive. The change only moves where it is said. No journey covers it.
  • The native confirm() used to block the renderer, so the states that disable a discard could not change while it was up. The new dialog is modal, so nothing the contributor can press starts an install, build or server behind it. Something already running could still finish under it, but that only makes a discard less blocked. The comment above discardAllChanges says this. I added no re-check.
  • Raising the dialog's layer applies only to ConfirmDialog, through its own portal. Other @wordpress/ui dialogs keep their stacking.
  • Review: 0 to fix, 1 low-severity follow-up, carried over from before this change (an action that rejects inside the discard-before-update question goes unhandled). Details are in the collapsed block.

Related

Fixes #658. Part of #622.


Design decisions and alternatives considered
  • Reused askFirst and ConfirmDialog rather than adding a new prompt component or a promise-returning confirm. Every discard caller already had the "ask, then run this" shape that askFirst takes.
  • Set the z-index on the dialog's portal rather than on :root. A global --wp-ui-dialog-z-index would lift the create-site, settings and rename dialogs as well, and would put them above any @wordpress/ui menu or popover opened inside them, which have no z-index of their own.
  • Error notices for the two failures rather than a dialog: neither one asks anything, and the error tone already stays until dismissed and is announced assertively.
  • The question's wording moved from one sentence to a title and a description (Discard all local changes? / This can’t be undone.), to match the deletion questions. docs/guide/submitting-changes.md quotes it, so I updated that line.
Review outcome (required — see AGENTS.md)

0 [fix here] · 1 [follow-up]: nothing fixed, one deferred.

  • [follow-up] 🔵 low, architecture: ConfirmDialog's onConfirm drops the promise its action returns, so if window.api.discardChanges rejects inside dirtyDiscardAndUpdate the rejection goes unhandled and the contributor sees nothing happen. Deferred because it is not new: confirmAnd had the same gap, and fixing it means catching the invoke the way discardAllChanges already does, which changes a failure path this PR does not touch.
  • Noted, not in scope: docs/guide/ticket-branches.md:61 quotes the delete-work question as "This cannot be undone." while the app says "This can’t be undone." That predates this PR.
  • Review: completed. Fresh-context agent, following .github/instructions/code-review.instructions.md step 3, reviewed the working tree against base 4835fba (identical to head a46d316); evidence: npm run lint clean, npm test 2091 pass / 0 fail / 2 skipped, npm run test:electron 2092 pass / 0 fail / 1 skipped, the 7 journeys in review-changes.spec.js + trunk-update.spec.js and the 48 in i18n.spec.js + pr-checkout.spec.js + delete-site.spec.js + ticket-list.spec.js + ticket-branches.spec.js pass; outcome: no blocking findings.
  • Since review: none. The reviewed tree was committed as a46d316 unchanged.
Implementation notes
  • useTrunkUpdate takes askFirst where it took confirmAnd. useDevServer takes confirm, the same way useTrunkUpdate and useApplyPatch already do.
  • acceptConfirms() is removed from tests/e2e/helpers/app.cjs because nothing raises a window.confirm any more. The journeys that used it now click the dialog through ui.confirmDialog / confirmYesButton / confirmNoButton.
  • src/renderer/index.js is not tracked, so there is no bundle in the diff.
Screenshots or recording

To add: the discard question in en-XA over the review dialog, before (the system dialog with English OK and Cancel) and after.

🤖 Generated with Claude Code

…nd alert()

Five places still used the window's confirm() and alert(). Their message
was translated, but Electron draws the dialog and its OK and Cancel
buttons in English whatever the language.

The three discards (all changes, the edits on trunk before a switch, and
the edits before a trunk update) now ask through askFirst, in the same
ConfirmDialog a deletion uses, with a button that says what it does. The
two failures, a path that could not be copied and a dev server started
before a build, are said in the window's error notices. confirmAnd and
the no-alert exceptions are gone.

Two of the discards are asked from inside the older library's modals,
whose overlay is at 100000. The confirm dialog's portal sets
--wp-ui-dialog-z-index to the same height, so it opens over them; the
notices stay above it.

The journeys that answered window.confirm now press the dialog, and the
en-XA journey checks each question's title and buttons are translated.

Fixes #658
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2618baad-bbec-4b4e-a2ea-6b446e17ef58
📥 Commits

Reviewing files that changed from the base of the PR and between 4835fba and a46d316.

📒 Files selected for processing (17)
  • TESTING.md
  • docs/guide/submitting-changes.md
  • src/renderer/changes-note.cjs
  • src/renderer/components/confirm-dialog.jsx
  • src/renderer/hooks/use-dev-server.jsx
  • src/renderer/hooks/use-trunk-update.jsx
  • src/renderer/index.jsx
  • src/renderer/shell.css
  • src/renderer/ticket-actions.cjs
  • tests/e2e/helpers/app.cjs
  • tests/e2e/helpers/ui.cjs
  • tests/e2e/journeys/i18n.spec.js
  • tests/e2e/journeys/pr-checkout.spec.js
  • tests/e2e/journeys/review-changes.spec.js
  • tests/e2e/journeys/trunk-update.spec.js
  • tests/unit/changes-note.test.cjs
  • tests/unit/ticket-actions.test.cjs
💤 Files with no reviewable changes (1)
  • tests/e2e/helpers/app.cjs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The described discard flows now use the application confirmation dialog with localized title, description, and button text. Selected error notices use the application confirmation queue instead of native alerts. End-to-end and unit tests now check the dialog content and discard behavior.

Assessment against linked issues

Objective Addressed Explanation
Replace native confirmation and alert prompts with localized application dialogs and notices, and add en-XA journey checks [#658] ✅

Priority: ➖ Normal

Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to a46d3

The reviewed dialog changes are mergeable after normal checks; the investigated discard failure is reported rather than escaping the workflow.

🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the required sections and provides detailed testing, risks, review outcome, and implementation notes. The required Screenshots or recording section is incomplete and still says … Add before-and-after screenshots or a short recording showing the discard dialog over the review or update modal. Replace the “To add” placeholder before merge.
Full details: Description check

Explanation

The description covers the required sections and provides detailed testing, risks, review outcome, and implementation notes. The required Screenshots or recording section is incomplete and still says “To add,” although this change modifies visible dialogs and notices.

  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ryanwelcher

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ryanwelcher
ryanwelcher requested a review from zaerl October 8, 2026 13:25

@zaerl zaerl left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as expected. Thank you very much.

@ryanwelcher
ryanwelcher merged commit 5fc9767 into trunk Oct 8, 2026
15 checks passed
@ryanwelcher
ryanwelcher deleted the fix/replace-confirm-and-alert branch October 8, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

i18n: Replace the window's confirm() and alert(), whose OK and Cancel Electron draws in English

2 participants