Skip to content

fix(ui): ask about unsaved term changes in an in-app dialog - #335

Merged
HugoFara merged 1 commit into
developfrom
fix/in-app-unsaved-prompt
Nov 4, 2026
Merged

HugoFara merged 1 commit into
developfrom
fix/in-app-unsaved-prompt

Conversation

@HugoFara

@HugoFara HugoFara commented Nov 4, 2026

Copy link
Copy Markdown
Owner

The term dialogs asked about unsaved changes with window.confirm(), which stops the whole page, ignores the theme and was English in every locale.

Changes

  • New confirmDialog() and confirmDiscardChanges() in shared/components/confirm_dialog.ts: a promise-based Bulma dialog above the term dialogs, translated in all 11 locales.
  • Used by the three unsaved-changes prompts: word_modal, word_edit_form and multi_word_form_store.
  • Escape, clicking outside and "Keep editing" all keep the changes. "Keep editing" has the focus, so a stray Enter loses nothing. Escape stays inside the dialog, so the term dialog underneath does not close too.
  • window.confirm() remains only as a fallback if the dialog cannot be built. The browser's own leave-page warning stays native, because pages cannot replace it.
  • close() and cancel() are now asynchronous. The multi-word modal used to release its focus trap before closing, which would have left it without one after "Keep editing", so it now releases after closing.

Not changed

35 other confirm() calls remain, such as "Delete this term?". Moving them would be a separate change.

Tests

confirm_dialog.test.ts covers each way of answering, Escape not reaching the dialog underneath, Tab, focus restoring, stacking and the native fallback. The three call sites' tests and the focus trap order are updated.

I also ran it in the real reader, in the dark theme, using the steps that froze the browser during production testing: an unsaved edit, then Cancel. Escape and a click outside kept the draft, and the X button then Discard closed both dialogs without saving. The translations are mine and were not reviewed by native speakers. Only the English text was seen on screen.

PHPUnit, Vitest, ESLint and TypeScript pass. Cypress passes except 24-anki-live.cy.ts, which needs npm run anki:up and was not run.

The term dialogs used window.confirm(), which stops the page, ignores the
theme and shows English text in every locale.

confirmDialog() is a promise-based Bulma dialog that sits above the term
dialogs. Escape and clicks outside keep the changes, and the safe button
has the focus. window.confirm() remains only for when the dialog cannot be
built, and the browser's own leave-page warning is unchanged.

Closing is now asynchronous, so the multi-word modal releases its focus
trap after closing rather than before: the user may keep editing.
@HugoFara
HugoFara merged commit 47443bf into develop Nov 4, 2026
8 checks passed
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.

1 participant