E-Mail-Snnoze (WIP)#589
Conversation
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughDie Änderung ergänzt Snooze- und Unsnooze-Endpunkte, erweitert Mail-Daten und Ansichtsfilter, verarbeitet abgelaufene Snoozes automatisch und integriert eine zeitbasierte Snooze-Auswahl samt Statusanzeige in die E-Mail-Oberfläche. ChangesE-Mail-Snooze
Estimated code review effort: 3 (Moderate) | ~30 minutes Sequence Diagram(s)sequenceDiagram
participant E-Mail-Nutzer
participant EmailSnoozeButton
participant EmailController
participant DropboxMail
E-Mail-Nutzer->>EmailSnoozeButton: Snooze-Zeitpunkt auswählen
EmailSnoozeButton->>EmailController: PUT snooze mit formatiertem Zeitpunkt
EmailController->>DropboxMail: snoozed_until speichern
DropboxMail-->>EmailController: Mail speichern
EmailController-->>EmailSnoozeButton: Zurückleitung
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
resources/js/Pages/App/Email/EmailIndex.tsx (1)
49-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnbenutzten Code und
console.logentfernen.Die Funktionen
midday,afternoon,tomorrowsowie derconsole.log-Aufruf werden nicht verwendet und sind vermutlich Überbleibsel der Auslagerung in die KomponenteEmailSnoozeButton. Sie sollten aus Gründen der Übersichtlichkeit entfernt werden.♻️ Vorgeschlagene Änderung
- const midday = () => { - return setHours(startOfToday(), 12) - } - - const afternoon = () => { - return setHours(startOfToday(), 17) - } - - const tomorrow = () => { - return setHours(startOfTomorrow(), 9) - } - - console.log(tomorrow()) - const handleRestore = async () => {🤖 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 49 - 62, Remove the unused midday, afternoon, and tomorrow helper functions and delete the console.log(tomorrow()) call from the component, leaving the existing EmailSnoozeButton behavior unchanged.resources/js/Components/twc-ui/menu.tsx (1)
78-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnbenutzte Property
simpleShortcutentfernen.Die Property
simpleShortcutwurde in diesem PR neu eingeführt, wird aber im Rendern der Komponente nicht verwendet.
resources/js/Components/twc-ui/menu.tsx#L78-L79: EntfernesimpleShortcut?: booleanaus dem Interface.resources/js/Components/twc-ui/menu.tsx#L101-L104: EntfernesimpleShortcut = false,aus der Destrukturierung der Props.🤖 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/Components/twc-ui/menu.tsx` around lines 78 - 79, Remove the unused simpleShortcut property from the props interface and remove its default value from the component props destructuring in resources/js/Components/twc-ui/menu.tsx at lines 78-79 and 101-104; no other prop behavior needs to change.
🤖 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/Http/Controllers/App/EmailController.php`:
- Around line 195-209: Update snooze() and unsnooze() to enforce the same
Dropbox access and mail-to-Dropbox relationship checks used by archive() and
unarchive() before modifying DropboxMail. Reuse the existing authorization
pattern and ensure mail->dropbox_id matches dropbox->id, while preserving the
current snooze and unsnooze behavior after validation.
In `@app/Http/Requests/DropboxMailSnoozeRequest.php`:
- Line 17: Update the validation rules for snoozed_until in
DropboxMailSnoozeRequest to require a timestamp strictly after the current time,
while preserving the existing required, date, and date_format:d.m.Y H:i
validations.
In `@app/Models/DropboxMail.php`:
- Line 73: Update the archived filter in the query configuration to require both
a non-null archived_at and a null snoozed_until, ensuring snoozed mails appear
only in the snooze view while preserving the existing archive condition for
non-snoozed mails.
- Around line 71-75: Update the status query branches in DropboxMail’s status
filtering logic so only future snoozed_until values remain in the snoozed view,
while expired snoozes are included in the normal inbox/sent views. Use now() for
the time comparison and preserve the existing archived, inbound, and trashed
conditions.
In `@resources/js/Pages/App/Email/EmailSnoozeButton.tsx`:
- Around line 19-22: Erweitere in
resources/js/Pages/App/Email/EmailSnoozeButton.tsx im Interface
EmailSnoozeButtonProps den Typ von mail auf optional sowie null-zulässig. Füge
am Anfang von onSnooze und onUnSnooze jeweils eine Prüfung ein, die bei
fehlendem mail sofort zurückkehrt, bevor auf mail.id zugegriffen wird.
---
Nitpick comments:
In `@resources/js/Components/twc-ui/menu.tsx`:
- Around line 78-79: Remove the unused simpleShortcut property from the props
interface and remove its default value from the component props destructuring in
resources/js/Components/twc-ui/menu.tsx at lines 78-79 and 101-104; no other
prop behavior needs to change.
In `@resources/js/Pages/App/Email/EmailIndex.tsx`:
- Around line 49-62: Remove the unused midday, afternoon, and tomorrow helper
functions and delete the console.log(tomorrow()) call from the component,
leaving the existing EmailSnoozeButton behavior unchanged.
🪄 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: 7fb942d0-543a-494a-be8b-4ba7f53f22b2
📒 Files selected for processing (12)
app/Data/DropboxMailData.phpapp/Http/Controllers/App/EmailController.phpapp/Http/Requests/DropboxMailSnoozeRequest.phpapp/Models/DropboxMail.phpresources/js/Components/twc-ui/menu.tsxresources/js/Pages/App/Email/Email.tsxresources/js/Pages/App/Email/EmailIndex.tsxresources/js/Pages/App/Email/EmailIndexEntry.tsxresources/js/Pages/App/Email/EmailSnoozeButton.tsxresources/js/Types/generated.d.tsresources/typescript-transformer-manifest.jsonroutes/tenant.php
| 'sent' => $query->whereNull('archived_at')->where('is_inbound', false)->whereNull('snoozed_until'), | ||
| 'snoozed' => $query->whereNotNull('snoozed_until'), | ||
| 'archived' => $query->whereNotNull('archived_at'), | ||
| 'trash' => $query->onlyTrashed(), | ||
| default => $query->whereNull('archived_at')->where('is_inbound', true), | ||
| default => $query->whereNull('snoozed_until')->whereNull('archived_at')->where('is_inbound', true), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Abgelaufene Snoozes müssen wieder sichtbar werden.
whereNotNull('snoozed_until') behandelt auch bereits abgelaufene Zeitpunkte als aktiv. Dadurch bleiben solche Mails aus Inbox/Sent ausgeschlossen und erscheinen dauerhaft im Snooze-View. Vergleiche mit now() und berücksichtige abgelaufene Werte wieder in den normalen Ansichten oder räume sie serverseitig auf.
🤖 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/Models/DropboxMail.php` around lines 71 - 75, Update the status query
branches in DropboxMail’s status filtering logic so only future snoozed_until
values remain in the snoozed view, while expired snoozes are included in the
normal inbox/sent views. Use now() for the time comparison and preserve the
existing archived, inbound, and trashed conditions.
| 'sent' => $query->whereNull('archived_at')->where('is_inbound', false), | ||
| 'sent' => $query->whereNull('archived_at')->where('is_inbound', false)->whereNull('snoozed_until'), | ||
| 'snoozed' => $query->whereNotNull('snoozed_until'), | ||
| 'archived' => $query->whereNotNull('archived_at'), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Die Archiv-Ansicht muss Snoozes ausschließen.
Eine Mail mit gesetztem archived_at und snoozed_until erscheint derzeit sowohl unter „Archiv“ als auch unter „Erneut erinnern“. Ergänze im archived-Zweig whereNull('snoozed_until'), sofern die Snooze-Ansicht exklusiv sein soll.
🤖 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/Models/DropboxMail.php` at line 73, Update the archived filter in the
query configuration to require both a non-null archived_at and a null
snoozed_until, ensuring snoozed mails appear only in the snooze view while
preserving the existing archive condition for non-snoozed mails.
There was a problem hiding this comment.
Snoozed und archived dürfte nicht vorkommen. eher button ausblenden oder?
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n "archive" resources/js/Pages/App/Email/*.tsx -i
rg -n "function archive|->archive|archived_at" app/Http/Controllers/App/EmailController.phpLength of output: 1982
🏁 Script executed:
#!/bin/bash
sed -n '195,240p' app/Http/Controllers/App/EmailController.phpLength of output: 1502
Confirmed: archive() neither clears snoozed_until nor checks it, and snooze() doesn't clear archived_at. So the button/UI approach alone won't prevent the inconsistent state, since both actions are independent backend endpoints reachable regardless of which button is currently shown (e.g., a mail could be archived first, then later a snooze action could still be triggered from another view, or vice versa).
@dspangenberg Das UI-Ausblenden ist sinnvoll und verbessert die UX, löst das Problem aber nicht vollständig: archive() prüft/löscht snoozed_until nicht, und snooze()/unsnooze() prüfen/löschen archived_at nicht. Beide Endpunkte sind unabhängig vom aktuell angezeigten Button erreichbar (z. B. via direktem Request oder wenn der Nutzer die Seite zwischen zwei Ansichten wechselt), sodass der inkonsistente Zustand weiterhin entstehen kann.
Ich würde daher beides kombinieren:
- UI: Snooze-/Archiv-Buttons gegenseitig ausblenden, wenn der jeweils andere Zustand aktiv ist (z. B.
EmailSnoozeButtondeaktivieren, wennmail.archived_atgesetzt ist, und den Archiv-Button ausblenden, wennmail.snoozed_untilgesetzt ist). - Backend: Bei
archive()zusätzlichsnoozed_until = nullsetzen und beisnooze()zusätzlicharchived_at = nullsetzen, damit der Zustand auch bei direkten Requests konsistent bleibt.
Damit wäre der Ausgangsvorschlag (Filter in scopeView) dann auch nur noch eine zusätzliche Absicherung und kein Muss – aber ich würde ihn trotzdem behalten, falls es Altdaten oder Edge Cases gibt.
Soll ich das im Detail als `` ausarbeiten (Backend + UI)?
✏️ Learnings added
Learnt from: dspangenberg
Repo: dspangenberg/opsc PR: 589
File: app/Models/DropboxMail.php:73-73
Timestamp: 2026-07-15T13:54:08.762Z
Learning: In app/Http/Controllers/App/EmailController.php, the `archive()` method sets `archived_at = now()` without clearing `snoozed_until`, and `snooze()`/`unsnooze()` set `snoozed_until` without clearing `archived_at`. If both fields should be mutually exclusive on `DropboxMail`, both backend methods need to clear the opposing field, not just UI buttons in resources/js/Pages/App/Email/EmailIndex.tsx and EmailSnoozeButton.tsx.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
The requested changes have been implemented and a pull request has been created: View PR
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/Console/Commands/SnoozeCommand.php`:
- Around line 29-30: Update the SnoozeCommand::handle method return type from
bool to int so it matches the integer exit codes it returns and Laravel/Symfony
command expectations. Preserve the existing 0 and 1 return behavior.
- Around line 62-64: Guard the GeneralNotificationEvent::dispatch call in
SnoozeCommand so it runs only when $mail->dropbox->user is present. Skip
notification dispatch for dropboxes without an associated user, while preserving
the existing “Unsnoozed E-Mail” notification for valid User instances.
In `@resources/js/Pages/App/Email/EmailIndex.tsx`:
- Line 126: Update the EmailSnoozeButton visibility condition in EmailIndex so
it also renders when view === 'snoozed', while preserving its existing
availability for the inbox and sent views.
🪄 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: ea4687ba-1499-4378-bbe0-40a6e47cc56b
📒 Files selected for processing (6)
app/Console/Commands/SnoozeCommand.phpapp/Http/Controllers/App/EmailController.phpapp/Http/Requests/DropboxMailSnoozeRequest.phpresources/js/Pages/App/Email/EmailIndex.tsxresources/js/Pages/App/Email/EmailSnoozeButton.tsxroutes/console.php
🚧 Files skipped from review as they are similar to previous changes (3)
- app/Http/Requests/DropboxMailSnoozeRequest.php
- app/Http/Controllers/App/EmailController.php
- resources/js/Pages/App/Email/EmailSnoozeButton.tsx
Summary by CodeRabbit
Neue Funktionen
Verbesserungen
Bug Fixes
Chores