Skip to content

fix(web): ask for confirmations with an in-app dialog instead of window.confirm - #132

Merged
dennismenken merged 8 commits into
mainfrom
fix/web-in-app-confirm
Oct 9, 2026
Merged

dennismenken merged 8 commits into
mainfrom
fix/web-in-app-confirm

Conversation

@dennismenken

@dennismenken dennismenken commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

window.confirm does not work in the desktop app: the Tauri dialog plugin replaces it with an async stub (window.confirm = async function ..., no sync IPC), so !confirm(...) is never true and the guarded action runs without asking. This was found while reviewing #131 and read from the plugin source of the locked crates; it was not run in the desktop app. This PR adds an in-app ConfirmDialog on the shared Modal (no @tauri-apps import) and moves every native dialog in apps/web onto it.

Type of change

  • fix — a bug fix

Affected components

  • apps/web
  • Repository root / build / docs (CHANGELOG, ESLint config)

What changes

  1. ConfirmDialog and useConfirmDialog in ui/system. The hook is promise based and shaped like the calls it replaces (if (!(await confirm(message))) return;); every way of not confirming (cancel, Escape, close, replaced by a newer request, owner unmounted) resolves false.
  2. SessionManagement: revoke one / revoke all others. The alert() for the result is now an inline success notice.
  3. InvitesTab: delete invite.
  4. MemberSettings: remove member. Removing a member used to ask twice (the row and handleRemoveMember both called confirm); the confirmation now lives in the row only.
  5. EditorWindow: delete asset pack (not in the original list of five; found by grep).
  6. ESLint no-alert for apps/web, so native confirm, alert and prompt cannot come back. A grep found no other call in apps/web.
  7. CHANGELOG.
  8. InvitesTab now checks the DELETE response: a rejected delete or a network error shows an error and keeps the row, 404 counts as already deleted.

How was this tested?

  • Vitest per caller (dialog shown, nothing sent before the confirm, nothing sent after cancel, native confirm never called) plus component and hook tests for the dialog itself.
  • Each guard was mutation-checked (guard removed, cancel ignored, dialog not rendered, double ask restored): the matching tests fail, and pass after restoring. The no-alert rule was checked by adding a confirm() and an alert() to a web file: both are reported.
  • scripts/ci-local.sh --full: lint, budgets, typecheck, shared/web/server tests (web 872) and build pass. format:check fails only on the pre-existing .codex/hooks.json.
  • Not checked in a browser or in the desktop app.

Notes

Breaking changes

  • This PR introduces a breaking change.
  • This PR is backwards-compatible.

Licensing checklist

  • All commits are signed off (git commit --signoff).
  • Inbound license grant per CONTRIBUTING.md: left for the author to confirm.
  • No new runtime dependency.

The desktop shell has no usable window.confirm: its dialog plugin swaps it
for an async stub, so a guarded action runs without asking. Add ConfirmDialog
on the shared Modal and useConfirmDialog, a promise wrapper shaped like the
confirm() calls it replaces.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
Revoking one session or all other sessions relied on window.confirm, which
never asks in the desktop shell, and reported the result with alert(). Use the
in-app confirm dialog and show the result inline.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
The invite list asked through window.confirm, which never asks in the desktop
shell. Use the in-app confirm dialog.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
Removing a member asked twice: the member row called window.confirm and then
handleRemoveMember called it again. In the desktop shell neither ever asked.
Ask once, in the row, with the in-app confirm dialog.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
The editor asked through window.confirm, which never asks in the desktop
shell. Use the in-app confirm dialog.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
Native dialogs do not work in the desktop shell. Enable no-alert for apps/web
so the in-app ConfirmDialog stays the only way to ask.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
Signed-off-by: Dennis Menken <dennis@lass-machen.me>
@dennismenken
dennismenken requested a review from a team as a code owner October 9, 2026 12:42
…e silently

The invite list removed a row without looking at the DELETE response, so a
rejected delete made a still valid invite disappear from the screen. Check
the status, show an error and keep the row; 404 counts as already deleted.

Signed-off-by: Dennis Menken <dennis@lass-machen.me>
@dennismenken
dennismenken merged commit e0afe6d into main Oct 9, 2026
6 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