From 675ab057b09ecb77447855908c8b31d773fc01f9 Mon Sep 17 00:00:00 2001 From: PalmarHealer Date: Thu, 15 Jan 2026 18:32:50 +0100 Subject: [PATCH] fix: Enhance feedback notifications for egg actions (#2042) Co-authored-by: Charles --- .../Admin/Resources/Eggs/Pages/EditEgg.php | 10 ++++ .../Admin/Resources/Eggs/Pages/ListEggs.php | 48 +++++++++++++++---- .../Components/Actions/ImportEggAction.php | 24 +++++----- .../Components/Actions/UpdateEggAction.php | 8 ++-- .../Actions/UpdateEggBulkAction.php | 29 +++++------ lang/en/admin/egg.php | 18 +++++++ 6 files changed, 100 insertions(+), 37 deletions(-) diff --git a/app/Filament/Admin/Resources/Eggs/Pages/EditEgg.php b/app/Filament/Admin/Resources/Eggs/Pages/EditEgg.php index e57af1c3d..f9407fff8 100644 --- a/app/Filament/Admin/Resources/Eggs/Pages/EditEgg.php +++ b/app/Filament/Admin/Resources/Eggs/Pages/EditEgg.php @@ -441,6 +441,16 @@ class EditEgg extends EditRecord DeleteAction::make() ->disabled(fn (Egg $egg): bool => $egg->servers()->count() > 0) ->label(fn (Egg $egg): string => $egg->servers()->count() <= 0 ? trans('filament-actions::delete.single.label') : trans('admin/egg.in_use')) + ->successNotification(fn (Egg $egg) => Notification::make() + ->success() + ->title(trans('admin/egg.delete_success')) + ->body(trans('admin/egg.deleted', ['egg' => $egg->name])) + ) + ->failureNotification(fn (Egg $egg) => Notification::make() + ->danger() + ->title(trans('admin/egg.delete_failed')) + ->body(trans('admin/egg.could_not_delete', ['egg' => $egg->name])) + ) ->iconButton()->iconSize(IconSize::ExtraLarge), ExportEggAction::make(), ImportEggAction::make() diff --git a/app/Filament/Admin/Resources/Eggs/Pages/ListEggs.php b/app/Filament/Admin/Resources/Eggs/Pages/ListEggs.php index cf7bed2f7..0f4dbe176 100644 --- a/app/Filament/Admin/Resources/Eggs/Pages/ListEggs.php +++ b/app/Filament/Admin/Resources/Eggs/Pages/ListEggs.php @@ -18,11 +18,13 @@ use Filament\Actions\CreateAction; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; use Filament\Actions\ReplicateAction; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ListRecords; use Filament\Support\Enums\IconSize; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; +use Illuminate\Support\Collection; use Illuminate\Support\Str; class ListEggs extends ListRecords @@ -88,15 +90,45 @@ class ListEggs extends ListRecords ]) ->groupedBulkActions([ DeleteBulkAction::make() - ->before(fn (&$records) => $records = $records->filter(function ($egg) { - /** @var Egg $egg */ - return $egg->servers_count <= 0; - })), + ->before(function (Collection &$records) { + $eggsWithServers = $records->filter(fn (Egg $egg) => $egg->servers_count > 0); + + if ($eggsWithServers->isNotEmpty()) { + $eggNames = $eggsWithServers->map(fn (Egg $egg) => sprintf('%s (%d server%s)', $egg->name, $egg->servers_count, $egg->servers_count > 1 ? 's' : '')) + ->join(', '); + Notification::make() + ->danger() + ->title(trans('admin/egg.cannot_delete', ['count' => $eggsWithServers->count()])) + ->body(trans('admin/egg.eggs_have_servers', ['eggs' => $eggNames])) + ->send(); + } + + $records = $records->filter(fn (Egg $egg) => $egg->servers_count <= 0); + + if ($records->isEmpty()) { + $this->halt(); + } + }), UpdateEggBulkAction::make() - ->before(fn (&$records) => $records = $records->filter(function ($egg) { - /** @var Egg $egg */ - return cache()->get("eggs.$egg->uuid.update", false); - })), + ->before(function (Collection &$records) { + $eggsWithoutUpdateUrl = $records->filter(fn (Egg $egg) => $egg->update_url === null); + + if ($eggsWithoutUpdateUrl->isNotEmpty()) { + $eggNames = $eggsWithoutUpdateUrl->pluck('name')->join(', '); + + Notification::make() + ->warning() + ->title(trans('admin/egg.cannot_update', ['count' => $eggsWithoutUpdateUrl->count()])) + ->body(trans('admin/egg.no_update_url', ['eggs' => $eggNames])) + ->send(); + } + + $records = $records->filter(fn (Egg $egg) => $egg->update_url !== null); + + if ($records->isEmpty()) { + $this->halt(); + } + }), ]) ->emptyStateIcon('tabler-eggs') ->emptyStateDescription('') diff --git a/app/Filament/Components/Actions/ImportEggAction.php b/app/Filament/Components/Actions/ImportEggAction.php index c97a79f83..a3ed53345 100644 --- a/app/Filament/Components/Actions/ImportEggAction.php +++ b/app/Filament/Components/Actions/ImportEggAction.php @@ -89,18 +89,20 @@ class ImportEggAction extends Action } } - if ($failed->count() > 0) { + $bodyParts = collect([ + $success->isNotEmpty() ? trans('admin/egg.import.imported_eggs', ['eggs' => $success->join(', ')]) : null, + $failed->isNotEmpty() ? trans('admin/egg.import.failed_import_eggs', ['eggs' => $failed->join(', ')]) : null, + ])->filter(); + + if ($bodyParts->isNotEmpty()) { Notification::make() - ->title(trans('admin/egg.import.import_failed')) - ->body($failed->join(', ')) - ->danger() - ->send(); - } - if ($success->count() > 0) { - Notification::make() - ->title(trans('admin/egg.import.import_success')) - ->body($success->join(', ')) - ->success() + ->title(trans('admin/egg.import.import_result', [ + 'success' => $success->count(), + 'failed' => $failed->count(), + 'total' => $success->count() + $failed->count(), + ])) + ->body($bodyParts->join(' | ')) + ->status($failed->isEmpty() ? 'success' : ($success->isEmpty() ? 'danger' : 'warning')) ->send(); } }); diff --git a/app/Filament/Components/Actions/UpdateEggAction.php b/app/Filament/Components/Actions/UpdateEggAction.php index 188472b21..a315831d7 100644 --- a/app/Filament/Components/Actions/UpdateEggAction.php +++ b/app/Filament/Components/Actions/UpdateEggAction.php @@ -47,8 +47,8 @@ class UpdateEggAction extends Action cache()->forget("eggs.$egg->uuid.update"); } catch (Exception $exception) { Notification::make() - ->title(trans('admin/egg.update_failed')) - ->body($exception->getMessage()) + ->title(trans('admin/egg.update_failed', ['egg' => $egg->name])) + ->body(trans('admin/egg.update_error', ['error' => $exception->getMessage()])) ->danger() ->send(); @@ -58,8 +58,8 @@ class UpdateEggAction extends Action } Notification::make() - ->title(trans_choice('admin/egg.updated', 1)) - ->body($egg->name) + ->title(trans('admin/egg.update_success', ['egg' => $egg->name])) + ->body(trans('admin/egg.updated_from', ['url' => $egg->update_url])) ->success() ->send(); }); diff --git a/app/Filament/Components/Actions/UpdateEggBulkAction.php b/app/Filament/Components/Actions/UpdateEggBulkAction.php index 19fa89ced..7b16626d7 100644 --- a/app/Filament/Components/Actions/UpdateEggBulkAction.php +++ b/app/Filament/Components/Actions/UpdateEggBulkAction.php @@ -47,39 +47,40 @@ class UpdateEggBulkAction extends BulkAction return; } - $success = 0; - $failed = 0; - $skipped = 0; + $successEggs = collect(); + $failedEggs = collect(); + $skippedEggs = collect(); /** @var Egg $egg */ foreach ($records as $egg) { if ($egg->update_url === null) { - $skipped++; + $skippedEggs->push($egg->name); continue; } try { $eggImporterService->fromUrl($egg->update_url, $egg); - $success++; + $successEggs->push($egg->name); cache()->forget("eggs.$egg->uuid.update"); } catch (Exception $exception) { - $failed++; + $failedEggs->push($egg->name); report($exception); } } + $bodyParts = collect([ + $successEggs->isNotEmpty() ? trans('admin/egg.updated_eggs', ['eggs' => $successEggs->join(', ')]) : null, + $failedEggs->isNotEmpty() ? trans('admin/egg.failed_eggs', ['eggs' => $failedEggs->join(', ')]) : null, + $skippedEggs->isNotEmpty() ? trans('admin/egg.skipped_eggs', ['eggs' => $skippedEggs->join(', ')]) : null, + ])->filter(); + Notification::make() - ->title(trans_choice('admin/egg.updated', 2, ['count' => $success, 'total' => $records->count()])) - ->body( - collect([ - $failed > 0 ? trans('admin/egg.updated_failed', ['count' => $failed]) : null, - $skipped > 0 ? trans('admin/egg.updated_skipped', ['count' => $skipped]) : null, - ])->filter()->join(' ') - ) - ->status($failed > 0 ? 'warning' : 'success') + ->title(trans_choice('admin/egg.updated', 2, ['count' => $successEggs->count(), 'total' => $records->count()])) + ->body($bodyParts->join(' | ')) + ->status($failedEggs->isNotEmpty() ? 'warning' : 'success') ->persistent() ->send(); }); diff --git a/lang/en/admin/egg.php b/lang/en/admin/egg.php index 69532e399..99e05bc0c 100644 --- a/lang/en/admin/egg.php +++ b/lang/en/admin/egg.php @@ -21,6 +21,9 @@ return [ 'add_url' => 'New URL', 'import_failed' => 'Import Failed', 'import_success' => 'Import Success', + 'import_result' => 'Imported :success of :total eggs', + 'imported_eggs' => 'Imported: :eggs', + 'failed_import_eggs' => 'Failed: :eggs', 'github' => 'Add from Github', 'refresh' => 'Refresh', 'import_image' => 'Import Image', @@ -102,7 +105,22 @@ return [ 'updated' => 'Egg updated|:count/:total Eggs updated', 'updated_failed' => ':count failed', 'updated_skipped' => ':count skipped', + 'update_success' => ':egg updated successfully', + 'update_failed' => 'Failed to update :egg', 'update_question' => 'Are you sure you want to update this egg?|Are you sure you want to update the selected eggs?', 'update_description' => 'If you made any changes to the egg they will be overwritten!|If you made any changes to the eggs they will be overwritten!', 'no_updates' => 'No updates for the selected eggs available', + 'cannot_update' => 'Cannot update :count egg(s)', + 'no_update_url' => 'The following eggs do not have a working update URL set: :eggs', + 'cannot_delete' => 'Cannot delete :count egg(s)', + 'eggs_have_servers' => 'The following eggs have servers and cannot be deleted: :eggs', + 'delete_success' => 'Egg deleted successfully', + 'deleted' => 'Deleted: :egg', + 'delete_failed' => 'Failed to delete egg', + 'could_not_delete' => 'Could not delete: :egg', + 'updated_from' => 'Successfully updated from: :url', + 'update_error' => 'Error: :error', + 'updated_eggs' => 'Updated: :eggs', + 'failed_eggs' => 'Failed: :eggs', + 'skipped_eggs' => 'Skipped: :eggs', ];