Skip to content

fix(ui-react): migrate raw overlay wrappers to BaseDialog and ConfirmDialog#6381

Merged
gustavosbarreto merged 1 commit into
masterfrom
fix/migrate-to-base-dialog
May 29, 2026
Merged

fix(ui-react): migrate raw overlay wrappers to BaseDialog and ConfirmDialog#6381
gustavosbarreto merged 1 commit into
masterfrom
fix/migrate-to-base-dialog

Conversation

@luannmoreira
Copy link
Copy Markdown
Member

@luannmoreira luannmoreira commented May 26, 2026

Summary

  • Five components were building dialogs with fixed inset-0 div wrappers — no focus trap, no native ESC handling, no consistent backdrop-click semantics
  • Migrate to shared primitives:
    • MfaDisableDialogBaseDialog (size="sm")
    • MfaRecoveryCodesModalBaseDialog (size="md")
    • MfaRecoveryTimeoutModalBaseDialog with canClose={() => false} — blocks both ESC and backdrop click, user must use the explicit Close button
    • Profile (DeleteAccountWarningDialog) → BaseDialog (size="md")
    • SessionDetails (Delete Recording + Close Session) → ConfirmDialog with per-dialog error state that clears on re-open
  • Update tests:
    • Add HTMLDialogElement.showModal/close stubs to global src/test/setup.ts so all BaseDialog-using components work under jsdom
    • Add vi.mock("@/hooks/useFocusTrap", ...) to MfaDisableDialog, MfaRecoveryTimeoutModal, and MfaRecover test files
    • Replace old DOM-traversal backdrop tests (.relative/previousElementSibling) with fireEvent on the native <dialog> element

Test plan

  • Open Disable MFA dialog → verify ESC and backdrop click dismiss it
  • Open Recovery Codes modal → verify ESC and backdrop click dismiss it
  • After using a recovery code, the recovery window modal appears → verify ESC and backdrop click do not dismiss it; only the Close button does
  • Delete account warning in Profile → verify backdrop click and ESC dismiss it
  • Delete Recording dialog in SessionDetails → delete fails with error → error shown in dialog; re-open clears the error
  • Close Session dialog in SessionDetails — same error-state behavior
  • Run npx vitest run — all 1904 tests pass

@luannmoreira luannmoreira requested a review from a team as a code owner May 26, 2026 19:06
@luannmoreira luannmoreira force-pushed the refactor/device-details-decompose branch from ac6720f to e4e7373 Compare May 26, 2026 19:30
@luannmoreira luannmoreira force-pushed the fix/migrate-to-base-dialog branch from 4260fbe to 251ffb2 Compare May 26, 2026 19:30
@luannmoreira luannmoreira self-assigned this May 26, 2026
@luannmoreira luannmoreira force-pushed the refactor/device-details-decompose branch from e4e7373 to 3a67dbd Compare May 28, 2026 14:00
Base automatically changed from refactor/device-details-decompose to master May 28, 2026 14:28
@luannmoreira luannmoreira force-pushed the fix/migrate-to-base-dialog branch 2 times, most recently from 453cc9c to d3ec964 Compare May 28, 2026 20:21
Five components were implementing dialogs with `fixed inset-0` div
wrappers instead of using the shared BaseDialog/ConfirmDialog primitives.
This meant no focus trap, no native ESC handling, and no backdrop-click
semantics — each component reinvented the wheel differently.

Migrate:
- MfaDisableDialog → BaseDialog (size="sm")
- MfaRecoveryCodesModal → BaseDialog (size="md")
- MfaRecoveryTimeoutModal → BaseDialog (canClose={() => false}) to block
  both ESC and backdrop click — user must use the explicit Close button
- Profile (DeleteAccountWarningDialog) → BaseDialog (size="md")
- SessionDetails (Delete Recording, Close Session) → ConfirmDialog with
  per-dialog error state so errors are cleared on re-open

Update tests:
- Add HTMLDialogElement.showModal/close stubs to global test/setup.ts
  so all BaseDialog-using components work under jsdom
- Mock useFocusTrap in MfaDisableDialog, MfaRecoveryTimeoutModal, and
  MfaRecover test files
- Replace old DOM-traversal backdrop tests (`.relative`/previousSibling)
  with fireEvent on the native <dialog> element
@luannmoreira luannmoreira force-pushed the fix/migrate-to-base-dialog branch from d3ec964 to c601ea6 Compare May 28, 2026 20:23
@gustavosbarreto
Copy link
Copy Markdown
Member

/review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

Claude finished @gustavosbarreto's task in 7m 2s —— View job


Code Review Complete

Reviewed 21 files across code quality, security, testing, TypeScript/React patterns, and architecture — no issues found. The code looks good as-is.

The migration is consistent and well-executed: all five components follow the same pattern (replace fixed inset-0 wrapper with BaseDialog/ConfirmDialog, add proper aria-label, wrap content in p-6 div). The SessionDetails refactor is particularly clean — replacing ~110 lines of inline dialog markup with two concise ConfirmDialog usages with proper error-state management. The type="button" additions across 13 files are a solid defensive improvement, and the test updates correctly adapt to the new <dialog>-based DOM structure.


If you push additional changes and want a new review, tag @shellhub-io/admin and a team member can trigger it.

@gustavosbarreto gustavosbarreto merged commit a3966ff into master May 29, 2026
12 checks passed
@gustavosbarreto gustavosbarreto deleted the fix/migrate-to-base-dialog branch May 29, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants