Skip to content

Mail widerherstellen, Snooze-Funktion (WIP)#588

Merged
dspangenberg merged 1 commit into
mainfrom
develop
Jul 14, 2026
Merged

Mail widerherstellen, Snooze-Funktion (WIP)#588
dspangenberg merged 1 commit into
mainfrom
develop

Conversation

@dspangenberg

@dspangenberg dspangenberg commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Neue Funktionen

    • Neue E-Mail-Ansicht „Zurückgestellt“ für Nachrichten mit Erinnerungszeitpunkt.
    • Gelöschte Nachrichten können wiederhergestellt werden.
    • E-Mails werden nun gezielt in den Papierkorb verschoben.
    • Nach dem Verschieben steht eine Rückgängig-Aktion zur Verfügung.
  • Verbesserungen

    • Seitenleiste und Aktionsleiste passen sich an die ausgewählte Ansicht an.
    • Archiv-, Papierkorb- und Wiederherstellungsaktionen sind übersichtlicher verfügbar.
    • Gelöschte Nachrichten können weiterhin in passenden Ansichten angezeigt werden.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Die E-Mail-Verwaltung erhält eine Snoozed-Ansicht, lädt Soft-Deleted-Mails und trennt das Verschieben in den Papierkorb von der Wiederherstellung. Die React-Oberfläche bietet dafür neue Navigationseinträge, ansichtsabhängige Aktionen und einen Undo-Workflow.

Changes

E-Mail-Lebenszyklus

Layer / File(s) Summary
Snoozed-Daten und Listenfilter
database/migrations/tenant/..., app/Models/DropboxMail.php, app/Http/Controllers/App/EmailController.php
snoozed_until wird gespeichert, als Datum gecastet und über die neue snoozed-Ansicht gefiltert; die Index-Abfrage berücksichtigt Soft-Deleted-Mails.
Trash- und Restore-Endpunkte
routes/tenant.php, app/Http/Controllers/App/EmailController.php
Die bisherige Destroy-Aktion wird in trash und restore aufgeteilt und über separate DELETE- und PUT-Routen erreichbar gemacht.
Ansichtsnavigation und Aktionen
resources/js/Pages/App/Email/*
Die Oberfläche ergänzt Snoozed, rendert Ansichten über EmailView, passt Toolbar-Aktionen an den aktuellen View an und unterstützt Undo nach dem Verschieben in den Papierkorb.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EmailIndex
  participant EmailRoutes
  participant EmailController
  participant DropboxMail
  EmailIndex->>EmailRoutes: Papierkorb- oder Restore-Aktion
  EmailRoutes->>EmailController: trash() oder restore()
  EmailController->>DropboxMail: delete() oder restore()
  EmailController-->>EmailIndex: Weiterleitung zur Mail-Ansicht
Loading

Possibly related PRs

Poem

Hopp, hopp, die Mail geht in den Trash,
ein Undo macht sie wieder frisch.
Snoozed ruht sie, fein und sacht,
Restore bringt sie heim bei Nacht.
Das Kaninchen klopft: Welch schöner Flash!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel nennt die beiden Hauptänderungen – Mail-Wiederherstellung und Snooze-Funktion – und passt damit zum Changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.2.5)

PHPStan was skipped because the config uses disallowed bootstrapFiles, bootstrapFile, or includes directives.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/Http/Controllers/App/EmailController.php (1)

222-246: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Verwende redirect()->back() um die aktuelle Ansicht beizubehalten.

Derzeit leiten restore und trash hart auf app.email.index weiter. Dadurch geht der aktuelle view-Query-Parameter verloren und der Benutzer wird unfreiwillig in den Posteingang (inbox) zurückgeworfen (z. B. wenn er sich im Papierkorb befindet und auf "Undo" klickt).
Um konsistent zu den bestehenden Methoden wie archive() zu bleiben und die aktuelle Ansicht des Nutzers intakt zu lassen, nutze stattdessen redirect()->back().

💡 Lösungsvorschlag
    public function restore(Dropbox $dropbox, DropboxMail $mail): RedirectResponse
    {
        if (
            (! $dropbox->is_shared && $dropbox->user_id !== auth()->id())
            || $mail->dropbox_id !== $dropbox->id
        ) {
            abort(403);
        }
        $mail->restore();

-       return redirect(route('app.email.index', ['dropbox' => $dropbox->id]));
+       return redirect()->back();
    }

    public function trash(Dropbox $dropbox, DropboxMail $mail): RedirectResponse
    {
        if (
            (! $dropbox->is_shared && $dropbox->user_id !== auth()->id())
            || $mail->dropbox_id !== $dropbox->id
        ) {
            abort(403);
        }
        $mail->delete();

-       return redirect(route('app.email.index', ['dropbox' => $dropbox->id]));
+       return redirect()->back();
    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Http/Controllers/App/EmailController.php` around lines 222 - 246, Update
the restore and trash methods in EmailController to return redirect()->back()
after completing their mail operation, preserving the current view query
parameter and matching the behavior of archive(). Keep the existing
authorization checks and restore/delete calls unchanged.
🧹 Nitpick comments (3)
resources/js/Pages/App/Email/EmailIndex.tsx (3)

35-45: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Entferne ungenutzten Code (handleDelete).

Nach der Einführung von handleTrash scheint diese Methode redundant zu sein. Sie wird im bereitgestellten Codeausschnitt nicht mehr für den Toolbar verwendet. Da handleTrash einen komfortableren Undo-Toast anstelle eines Bestätigungsdialogs bietet, kann handleDelete wahrscheinlich restlos entfernt werden.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/js/Pages/App/Email/EmailIndex.tsx` around lines 35 - 45, Remove the
unused handleDelete function from EmailIndex, including its confirmation-dialog
logic, and retain the existing handleTrash flow as the sole deletion action.

47-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Memoisiere handleRestore mit useCallback.

Da handleRestore innerhalb des onSuccess-Callbacks von handleTrash (Zeile 74) referenziert wird, sollte die Methode mit useCallback memoisiert und als Abhängigkeit registriert werden. Das vermeidet veraltete Closures und erfüllt die React-Hooks-Regeln.

♻️ Refactoring-Vorschlag
-  const handleRestore = async () => {
-    if (!mail) return
-    router.put(route('app.email.restore', { dropbox: dropbox.id, mail: mail.id }))
-  }
+  const handleRestore = useCallback(async () => {
+    if (!mail) return
+    router.put(route('app.email.restore', { dropbox: dropbox.id, mail: mail.id }))
+  }, [mail, dropbox.id])

Vergiss nicht, handleRestore danach im Dependency-Array von handleTrash (Zeile 80) hinzuzufügen:

  }, [mail?.id, dropbox.id, handleRestore])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/js/Pages/App/Email/EmailIndex.tsx` around lines 47 - 50, Memoize
handleRestore with useCallback, preserving its existing mail guard and restore
navigation while declaring the values it uses as dependencies. Add handleRestore
to handleTrash’s dependency array so the onSuccess callback uses the current
restore handler and satisfies the Hooks rules.

33-33: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Setze einen Fallback für die aktuelle Ansicht.

Wenn kein view-Parameter in der URL existiert (wie beim direkten Aufruf von /app/emails/...), ist route().params.view undefined. Ein expliziter Fallback auf 'inbox' stellt sicher, dass der Wert konsistent ist und Typ-Fehler in Folgekomponenten wie EmailIndexEntry vermieden werden.

💡 Lösungsvorschlag
-  const view = route().params.view
+  const view = (route().params.view as string) ?? 'inbox'

Anschließend kannst du in Zeile 205 bei EmailIndexEntry ebenfalls den gesicherten Wert nutzen: view={view as 'inbox' | ...}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/js/Pages/App/Email/EmailIndex.tsx` at line 33, Set a default of
'inbox' when assigning the current view from route().params.view, and update the
EmailIndexEntry usage to pass this normalized view value rather than the
potentially undefined route parameter. Preserve the existing view typing for
other supported values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/Models/DropboxMail.php`:
- Line 75: Update the default branch of the query in DropboxMail to exclude
emails with an active snooze: retain only records whose snoozed_until is null or
has already elapsed, while preserving the existing archived_at and is_inbound
filters.

---

Outside diff comments:
In `@app/Http/Controllers/App/EmailController.php`:
- Around line 222-246: Update the restore and trash methods in EmailController
to return redirect()->back() after completing their mail operation, preserving
the current view query parameter and matching the behavior of archive(). Keep
the existing authorization checks and restore/delete calls unchanged.

---

Nitpick comments:
In `@resources/js/Pages/App/Email/EmailIndex.tsx`:
- Around line 35-45: Remove the unused handleDelete function from EmailIndex,
including its confirmation-dialog logic, and retain the existing handleTrash
flow as the sole deletion action.
- Around line 47-50: Memoize handleRestore with useCallback, preserving its
existing mail guard and restore navigation while declaring the values it uses as
dependencies. Add handleRestore to handleTrash’s dependency array so the
onSuccess callback uses the current restore handler and satisfies the Hooks
rules.
- Line 33: Set a default of 'inbox' when assigning the current view from
route().params.view, and update the EmailIndexEntry usage to pass this
normalized view value rather than the potentially undefined route parameter.
Preserve the existing view typing for other supported values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dcfb9c08-32d7-419b-a545-8d4e2eef7440

📥 Commits

Reviewing files that changed from the base of the PR and between ae45697 and 6928557.

📒 Files selected for processing (6)
  • app/Http/Controllers/App/EmailController.php
  • app/Models/DropboxMail.php
  • database/migrations/tenant/2026_07_14_131215_add_snoozed_to_dropbox_mails.php
  • resources/js/Pages/App/Email/EmailIndex.tsx
  • resources/js/Pages/App/Email/EmailView.tsx
  • routes/tenant.php

Comment thread app/Models/DropboxMail.php
@dspangenberg
dspangenberg merged commit 19e17bc into main Jul 14, 2026
3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 15, 2026
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