Skip to content

Conversation

@illia1f
Copy link
Contributor

@illia1f illia1f commented Dec 26, 2025

Description

Fixes #270

  • Fixes focus trap breaking after using window.confirm() in the Recycle Bin dialog
  • Replaced native browser confirm dialogs with React-based ConfirmDialog and DeleteConfirmDialog components
  • Refactored trash dialog state management to reduce prop drilling
  • Added error handling for restore and empty trash operations

Test plan

  1. Open Recycle Bin dialog with trashed projects
    2, Click "Delete from disk" and verify confirmation dialog appears
  2. Confirm or cancel deletion and verify focus remains functional
  3. Click "Empty Recycle Bin" and verify confirmation dialog appears
  4. Confirm or cancel and verify app remains responsive
  5. Close and reopen the Recycle Bin dialog to verify state resets properly

Summary by CodeRabbit

  • New Features

    • Delete-from-disk and Empty Recycle Bin now use separate confirmation modal dialogs for clearer, step-by-step confirmation.
    • Confirmation dialogs reset when the Trash view is closed to avoid stale prompts.
  • Bug Fixes

    • Improved error handling for restore, delete-from-disk, and empty-trash actions with user-facing notifications when operations fail.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Dialog state was moved from a removed useTrashDialog hook into the Sidebar component, replaced native browser confirmations with React modal confirmations, and added error handling around trash operations in useTrashOperations.

Changes

Cohort / File(s) Summary
Sidebar component
apps/ui/src/components/layout/sidebar.tsx
Replaces useTrashDialog import with useTrashOperations; adds local const [showTrashDialog, setShowTrashDialog] = useState(false); uses local state to control TrashDialog open/onOpenChange.
Trash dialog UI
apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx
Adds internal confirmation state and handlers for "delete from disk" and "empty trash"; renders DeleteConfirmDialog and ConfirmDialog instead of native confirm; resets confirmations when main dialog closes.
Hook barrel
apps/ui/src/components/layout/sidebar/hooks/index.ts
Removes re-export of useTrashDialog from the hooks index.
Removed hook
apps/ui/src/components/layout/sidebar/hooks/use-trash-dialog.ts
Entire useTrashDialog hook deleted (it formerly combined dialog state with operations).
Trash operations hook
apps/ui/src/components/layout/sidebar/hooks/use-trash-operations.ts
Removes trashedProjects prop; eliminates window.confirm() usage from delete/empty flows; adds try/catch error handling and toast logging for restore/delete/empty operations; adjusts effect dependencies accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant Sidebar
  participant TrashDialog
  participant ConfirmModal
  participant useTrashOperations

  Note over Sidebar,TrashDialog: Open Recycle Bin
  User->>Sidebar: click "Recycle Bin"
  Sidebar->>TrashDialog: open (showTrashDialog = true)

  Note over TrashDialog: User triggers action
  User->>TrashDialog: click "Delete from disk"
  TrashDialog->>ConfirmModal: show DeleteConfirmDialog
  User->>ConfirmModal: confirm
  ConfirmModal->>useTrashOperations: handleDeleteProjectFromDisk(projectId)
  useTrashOperations-->>ConfirmModal: success / error
  ConfirmModal-->>TrashDialog: close confirm
  TrashDialog-->>Sidebar: optionally update UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I nudged the dialog, soft and light,

No native box to steal the night,
Now modals hop where confirms once trod,
Focus mended, tidy and odd,
A little rabbit cheers the code.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing window.confirm dialogs with React-based confirmation dialogs for trash operations.
Linked Issues check ✅ Passed The PR successfully addresses issue #270 by replacing window.confirm() with React-based dialogs (ConfirmDialog, DeleteConfirmDialog), fixing the focus trap corruption issue in the Recycle Bin dialog.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the focus trap issue by refactoring trash dialog state management and replacing native confirm dialogs with React components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04a5ae4 and 3bb9d27.

📒 Files selected for processing (1)
  • apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx (2)
apps/ui/src/lib/electron.ts (1)
  • TrashedProject (2802-2805)
apps/ui/src/components/ui/confirm-dialog.tsx (1)
  • ConfirmDialog (34-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (7)
apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx (7)

1-1: LGTM! Clean import additions.

The new imports support the confirmation dialog state management and React-based confirmation flows that replace the native browser dialogs.

Also applies to: 12-13


39-41: LGTM! Appropriate internal state management.

Managing confirmation state locally avoids unnecessary prop drilling and keeps the transient UI state encapsulated within the component.


43-50: LGTM! Proper cleanup on dialog close.

The wrapper correctly resets confirmation state when the main dialog closes, preventing stale confirmation dialogs from appearing on subsequent opens.


52-70: LGTM! Well-structured confirmation handlers.

The handlers follow a clean pattern: click handlers set confirmation state, and confirm handlers execute the action then reset. The defensive null check on line 57 is appropriate.


72-151: LGTM! Main dialog correctly integrated with confirmation flows.

The existing UI structure is preserved while cleanly wiring in the new confirmation dialogs. The fragment wrapper enables rendering multiple dialogs, and the handlers now trigger confirmations instead of immediate actions.


153-165: LGTM! Addresses previous review feedback correctly.

The conditional rendering on line 154 ensures the dialog only renders when deleteFromDiskProject is not null, preventing undefined values in props. This directly addresses the concern raised in the previous review. The hardcoded open prop (line 156) combined with conditional rendering is a standard React pattern and is more efficient than always rendering the component.


167-179: LGTM! Clear and well-configured empty trash confirmation.

The confirmation dialog appropriately uses the destructive variant and provides a helpful description clarifying that this action clears the list without deleting folders from disk. The visual styling correctly signals the action's severity.


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

@illia1f illia1f changed the title refactor: replace window.confirm with React dialogs in trash operations fix: replace window.confirm with React dialogs in trash operations Dec 26, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @illia1f, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the Recycle Bin functionality by replacing native browser confirmation prompts with custom React dialogs. This change not only resolves a critical accessibility issue related to focus management but also enhances the overall user experience with a more integrated and visually consistent interface. Additionally, the underlying state management for trash operations has been optimized, and comprehensive error handling has been introduced to make the feature more robust.

Highlights

  • Improved User Experience: Replaced native browser window.confirm() dialogs with custom React-based ConfirmDialog and DeleteConfirmDialog components for a more consistent and accessible UI.
  • Focus Trap Fix: Addressed an issue where the focus trap would break after using window.confirm() in the Recycle Bin dialog, ensuring better accessibility.
  • Refactored State Management: Streamlined trash dialog state management to reduce prop drilling, improving code organization and maintainability.
  • Enhanced Error Handling: Implemented robust error handling for restore and empty trash operations, providing better feedback to the user in case of failures.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively replaces the native window.confirm dialogs with React-based components for trash operations, which resolves the focus trap issue. The refactoring of state management for the trash dialog is well-executed, reducing prop drilling and improving component encapsulation. The addition of error handling for restore and empty trash operations is a great improvement for robustness. I have one suggestion to improve the conditional rendering of the delete confirmation dialog to prevent passing malformed props.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx (1)

52-70: Consider consolidating confirmation state management.

The confirmation handlers follow a consistent pattern, which is good. However, the defensive null check in onConfirmDeleteFromDisk (lines 57-60) is redundant since the dialog's open prop is controlled by deleteFromDiskProject !== null (line 155). The dialog cannot be confirmed if the project is null.

🔎 Simplified version without redundant null check
 const onConfirmDeleteFromDisk = () => {
-  if (deleteFromDiskProject) {
-    handleDeleteProjectFromDisk(deleteFromDiskProject);
-    setDeleteFromDiskProject(null);
-  }
+  handleDeleteProjectFromDisk(deleteFromDiskProject!);
+  setDeleteFromDiskProject(null);
 };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f952820 and 04a5ae4.

📒 Files selected for processing (5)
  • apps/ui/src/components/layout/sidebar.tsx
  • apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx
  • apps/ui/src/components/layout/sidebar/hooks/index.ts
  • apps/ui/src/components/layout/sidebar/hooks/use-trash-dialog.ts
  • apps/ui/src/components/layout/sidebar/hooks/use-trash-operations.ts
💤 Files with no reviewable changes (2)
  • apps/ui/src/components/layout/sidebar/hooks/use-trash-dialog.ts
  • apps/ui/src/components/layout/sidebar/hooks/index.ts
🧰 Additional context used
🧬 Code graph analysis (1)
apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx (2)
apps/ui/src/lib/electron.ts (1)
  • TrashedProject (2802-2805)
apps/ui/src/components/ui/confirm-dialog.tsx (1)
  • ConfirmDialog (34-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (6)
apps/ui/src/components/layout/sidebar/hooks/use-trash-operations.ts (2)

21-31: LGTM! Error handling properly added.

The try-catch block correctly wraps the restore operation and provides user feedback via toast notifications. The error handling pattern is consistent with the other operations in this file.


66-79: The emptyTrash() function is synchronous. Its implementation in the store simply calls set({ trashedProjects: [] }), which updates state synchronously with no async operations or unhandled promises. The isEmptyingTrash state is correctly reset in the finally block.

apps/ui/src/components/layout/sidebar/dialogs/trash-dialog.tsx (2)

39-50: Good defensive cleanup of confirmation state.

The cleanup logic in handleOpenChange properly resets both confirmation dialog states when the main Trash dialog closes, preventing stale state from persisting across dialog re-opens.


154-176: Add explicit focus management to nested confirmation dialogs.

The implementation correctly uses Radix Dialog components to keep nested dialogs within React/Radix control. However, each dialog instance activates its own independent modal focus trap by default, which can cause focus management issues when multiple dialogs are simultaneously active. When the user confirms a nested dialog action and it closes, focus may not properly return to the main TrashDialog.

Add one of these fixes:

  • Use modal={false} on nested dialog's DialogPrimitive.Root (trade-off: disables default scroll lock)
  • Implement explicit focus restoration with openAutoFocus and closeAutoFocus props on DialogContent
  • Or add custom focus trap coordination in TrashDialog's state handlers

Test the three scenarios from the original review to confirm focus behavior is correct.

apps/ui/src/components/layout/sidebar.tsx (2)

31-31: Clean refactoring of dialog state management.

The separation of concerns is well-executed:

  • useTrashOperations focuses purely on trash operations without UI state
  • Dialog visibility is managed locally in the component
  • Props are cleanly passed to both the hook and the TrashDialog component

This refactoring aligns well with React best practices and makes the code more maintainable.

Also applies to: 71-72, 137-148


313-323: TrashDialog integration looks correct.

The dialog receives all necessary props and the state management changes don't affect the data flow. The trashedProjects data continues to come directly from the store, while the operations come from the useTrashOperations hook.

@illia1f
Copy link
Contributor Author

illia1f commented Dec 26, 2025

image image

@Shironex Shironex added the Enhancement Improvements to existing functionality or UI. label Dec 26, 2025
@webdevcody webdevcody merged commit d4b2a3e into AutoMaker-Org:main Dec 26, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Improvements to existing functionality or UI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Focus Trap Breaks After Deleting Project from Disk

3 participants