Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppressions list #11

Merged
merged 14 commits into from
Jan 23, 2025
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ return [
'resources' => [
'mail' => \App\Filament\Resources\MailResource::class,
'event' => \App\Filament\Resources\EventResource::class,
'suppressions' => \App\Filament\Resources\SuppressionResource::class
],
];
```
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}
2 changes: 2 additions & 0 deletions config/filament-mails.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

use Vormkracht10\FilamentMails\Resources\EventResource;
use Vormkracht10\FilamentMails\Resources\MailResource;
use Vormkracht10\FilamentMails\Resources\SuppressionResource;

return [
'resources' => [
'mail' => MailResource::class,
'event' => EventResource::class,
'suppressions' => SuppressionResource::class,
],
];
1 change: 1 addition & 0 deletions src/FilamentMailsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function register(Panel $panel): void
->resources([
config('filament-mails.resources.mail'),
config('filament-mails.resources.event'),
config('filament-mails.resources.suppressions'),
]);
}

Expand Down
141 changes: 141 additions & 0 deletions src/Resources/SuppressionResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php

namespace Vormkracht10\FilamentMails\Resources;

use Filament\Infolists\Infolist;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Vormkracht10\FilamentMails\Resources\SuppressionResource\Pages\ListSuppressions;
use Vormkracht10\Mails\Enums\EventType;
use Vormkracht10\Mails\Events\MailUnsuppressed;
use Vormkracht10\Mails\Models\MailEvent;

class SuppressionResource extends Resource
{
protected static ?string $model = MailEvent::class;

protected static ?string $slug = 'mails/suppressions';

protected static bool $isScopedToTenant = false;

protected static bool $shouldRegisterNavigation = true;

public function getTitle(): string
{
return __('Suppressions');
}

public static function getNavigationParentItem(): ?string
{
return __('Mails');
}

public static function getNavigationGroup(): ?string
{
return __('Mails');
}

public static function getNavigationLabel(): string
{
return __('Suppressions');
}

public static function getLabel(): ?string
{
return __('Suppression');
}

public static function getPluralModelLabel(): string
{
return __('Suppressions');
}

public static function getNavigationIcon(): string
{
return 'heroicon-o-no-symbol';
}

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->join('mails', 'mail_events.mail_id', '=', 'mails.id')
->where(function ($query) {
$query->where('type', EventType::HARD_BOUNCED)
->orWhere('type', EventType::COMPLAINED);
})
->whereNull('unsuppressed_at')
->whereIn('mails.to', function ($query) {
$query->select('to')
->from('mail_events')
->where('type', EventType::HARD_BOUNCED)
->whereNull('unsuppressed_at')
->groupBy('to');
})
->select('mail_events.*', 'mails.to')
->addSelect([
'has_complained' => MailEvent::select('m.id')
->from('mail_events AS me')
->leftJoin('mails As m', function ($join) {
$join->on('me.mail_id', '=', 'm.id')
->where('me.type', '=', EventType::COMPLAINED);
})
->take(1),
])
->latest('occurred_at')
->orderBy('occurred_at', 'desc');
}

public static function table(Table $table): Table
{
return $table
->defaultSort('occurred_at', 'desc')
->columns([
Tables\Columns\TextColumn::make('to')
->label(__('Email address'))
->formatStateUsing(fn ($record) => key(json_decode($record->to ?? [])))
->searchable(['to']),

Tables\Columns\TextColumn::make('id')
->label(__('Reason'))
->badge()
->formatStateUsing(fn ($record) => $record->type->value == EventType::COMPLAINED->value ? 'Complained' : 'Bounced')
->color(fn ($record): string => match ($record->type->value == EventType::COMPLAINED->value) {
true => 'danger',
default => 'gray',
}),

Tables\Columns\TextColumn::make('occurred_at')
->label(__('Occurred At'))
->dateTime('d-m-Y H:i')
->since()
->tooltip(fn (MailEvent $record) => $record->occurred_at->format('d-m-Y H:i'))
->sortable()
->searchable(),
])
->actions([
Tables\Actions\Action::make('unsuppress')
->label(__('Unsuppress'))
->action(function (MailEvent $record) {
event(new MailUnsuppressed(key($record->to), $record->mail->driver, $record->mail->stream_id ?? null));
}),

Tables\Actions\ViewAction::make()
->url(null)
->modal()
->slideOver()
->label(__('View'))
->hiddenLabel()
->tooltip(__('View'))
->infolist(fn (Infolist $infolist) => EventResource::infolist($infolist)),
]);
}

public static function getPages(): array
{
return [
'index' => ListSuppressions::route('/'),
];
}
}
16 changes: 16 additions & 0 deletions src/Resources/SuppressionResource/Pages/ListSuppressions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Vormkracht10\FilamentMails\Resources\SuppressionResource\Pages;

use Filament\Resources\Pages\ListRecords;
use Vormkracht10\FilamentMails\Resources\SuppressionResource;

class ListSuppressions extends ListRecords
{
protected static string $resource = SuppressionResource::class;

public function getTitle(): string
{
return __('Suppressions');
}
}