├── LICENSE.md ├── README.md ├── composer.json ├── config └── filament-spatie-laravel-activitylog.php ├── resources └── lang │ ├── ar │ └── activity.php │ ├── de │ └── activity.php │ ├── en │ └── activity.php │ ├── es │ └── activity.php │ └── pt_BR │ └── activity.php └── src ├── Contracts └── IsActivitySubject.php ├── FilamentSpatieLaravelActivitylogPlugin.php ├── FilamentSpatieLaravelActivitylogServiceProvider.php ├── RelationManagers └── ActivitiesRelationManager.php ├── ResourceFinder.php └── Resources ├── ActivityResource.php └── ActivityResource └── Pages ├── ListActivities.php └── ViewActivity.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) alexjustesen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # View your activity logs inside of Filament. 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/alexjustesen/filament-spatie-laravel-activitylog.svg?style=flat-square)](https://packagist.org/packages/alexjustesen/filament-spatie-laravel-activitylog) 4 | [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/alexjustesen/filament-spatie-laravel-activitylog/run-tests?label=tests)](https://github.com/alexjustesen/filament-spatie-laravel-activitylog/actions?query=workflow%3Arun-tests+branch%3Amain) 5 | [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/alexjustesen/filament-spatie-laravel-activitylog/Check%20&%20fix%20styling?label=code%20style)](https://github.com/alexjustesen/filament-spatie-laravel-activitylog/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) 6 | [![Total Downloads](https://img.shields.io/packagist/dt/alexjustesen/filament-spatie-laravel-activitylog.svg?style=flat-square)](https://packagist.org/packages/alexjustesen/filament-spatie-laravel-activitylog) 7 | 8 | This package provides a Filament resource that shows you all of the activity logs created using the `spatie/laravel-activitylog` package. It also provides a relationship manager for related models. 9 | 10 | ## Installation 11 | 12 | > [!WARNING] 13 | > Version ^0.7 supports Filament v3. 14 | 15 | You can install the package via composer: 16 | 17 | ```bash 18 | // For Filament v3 19 | composer require alexjustesen/filament-spatie-laravel-activitylog:^0.7 20 | 21 | // For Filament v2 22 | composer require alexjustesen/filament-spatie-laravel-activitylog:^0.6 23 | ``` 24 | 25 | You can publish the config file with: 26 | 27 | ```bash 28 | php artisan vendor:publish --tag="filament-spatie-activitylog-config" 29 | ``` 30 | 31 | This is the contents of the published config file: 32 | 33 | ```php 34 | return [ 35 | 36 | 'resource' => [ 37 | 'filament-resource' => AlexJustesen\FilamentSpatieLaravelActivitylog\Resources\ActivityResource::class, 38 | 'group' => null, 39 | 'sort' => null, 40 | ], 41 | 42 | 'paginate' => [5, 10, 25, 50], 43 | 44 | ]; 45 | ``` 46 | 47 | ## Usage 48 | 49 | This package will automatically register the `ActivityResource` class specified in the configuration `resource.filament-resource`. You'll be able to see it when you visit your Filament admin panel. 50 | 51 | ## Customising the ActivityResource 52 | 53 | You can swap out the `ActivityResource` used by publishing the configuration file and updating the `resource.filament-resource` value. Use this to create your own `ActivityResource` class and extend the original at `AlexJustesen\FilamentSpatieLaravelActivitylog\Resources\ActivityResource::class`. This will allow you to customise everything such as the views, table, form and permissions. If you wish to change the resource on List and View page be sure to replace the `getPages` method on the new resource and create your own version of the `ListPage` and `ViewPage` classes to reference the custom `ActivityResource`. 54 | 55 | ## Customising the group 56 | 57 | You can customise the navigation group for the `ActivityResource` by publishing the configuration file and updating the `resource.group` value. 58 | 59 | ## Customising the sorting 60 | 61 | You can customise the navigation group for the `ActivityResource` by publishing the configuration file and updating the `resource.sort` value. 62 | 63 | ## Relationship manager 64 | 65 | If you have a model that uses the `Spatie\Activitylog\Traits\LogsActivity` trait, you can add the `AlexJustesen\FilamentSpatieLaravelActivitylog\RelationManagers\ActivitiesRelationManager` relationship manager to your Filament resource to display all of the activity logs that are performed on your model. 66 | 67 | ### Show the `subject` column on custom relation managers 68 | 69 | When using the relationship manager the `subject` column isn't shown because the subject is the parent record. There are some cases (like when aggregating activities from child records) where the subject might be another record, and you want to show this column. In those cases you can add the next code to your relation manager: 70 | 71 | ```php 72 | public function hideSubjectColumn(): bool 73 | { 74 | return false; 75 | } 76 | ``` 77 | 78 | ## Testing 79 | 80 | ```bash 81 | composer test 82 | ``` 83 | 84 | ## Changelog 85 | 86 | Please see [RELEASES](https://github.com/alexjustesen/filament-spatie-laravel-activitylog/releases) for more information on what has changed recently. 87 | 88 | ## Contributing 89 | 90 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 91 | 92 | ## Security Vulnerabilities 93 | 94 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 95 | 96 | ## Credits 97 | 98 | - [Alex Justesen](https://github.com/alexjustesen) 99 | - [Ryan Chandler](https://github.com/ryangjchandler) (Original creator) 100 | - [All Contributors](../../contributors) 101 | 102 | ## License 103 | 104 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 105 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alexjustesen/filament-spatie-laravel-activitylog", 3 | "description": "View your activity logs inside of Filament.", 4 | "keywords": [ 5 | "alexjustesen", 6 | "laravel", 7 | "filament-spatie-laravel-activitylog" 8 | ], 9 | "homepage": "https://github.com/alexjustesen/filament-spatie-laravel-activitylog", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Alex Justesen", 14 | "email": "support@alexjustesen.com", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.0 || ^8.1 || ^8.2", 20 | "filament/filament": "^3.0", 21 | "illuminate/contracts": "^8.0 || ^9.0 || ^10.0", 22 | "spatie/laravel-activitylog": "^4.3", 23 | "spatie/laravel-package-tools": "^1.9.2" 24 | }, 25 | "require-dev": { 26 | "nunomaduro/collision": "^5.10 || ^6.0", 27 | "nunomaduro/larastan": "^1.0 || ^2.0.1", 28 | "orchestra/testbench": "^6.22 || ^7.0", 29 | "pestphp/pest": "^1.21", 30 | "pestphp/pest-plugin-laravel": "^1.1", 31 | "phpstan/extension-installer": "^1.1", 32 | "phpstan/phpstan-deprecation-rules": "^1.0", 33 | "phpstan/phpstan-phpunit": "^1.0", 34 | "phpunit/phpunit": "^9.5", 35 | "spatie/laravel-ray": "^1.26" 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "AlexJustesen\\FilamentSpatieLaravelActivitylog\\": "src", 40 | "AlexJustesen\\FilamentSpatieLaravelActivitylog\\Database\\Factories\\": "database/factories" 41 | } 42 | }, 43 | "autoload-dev": { 44 | "psr-4": { 45 | "AlexJustesen\\FilamentSpatieLaravelActivitylog\\Tests\\": "tests" 46 | } 47 | }, 48 | "scripts": { 49 | "analyse": "vendor/bin/phpstan analyse", 50 | "test": "vendor/bin/pest", 51 | "test-coverage": "vendor/bin/pest coverage" 52 | }, 53 | "config": { 54 | "allow-plugins": { 55 | "pestphp/pest-plugin": true, 56 | "phpstan/extension-installer": true 57 | }, 58 | "sort-packages": true 59 | }, 60 | "extra": { 61 | "laravel": { 62 | "providers": [ 63 | "AlexJustesen\\FilamentSpatieLaravelActivitylog\\FilamentSpatieLaravelActivitylogServiceProvider" 64 | ], 65 | "aliases": { 66 | "FilamentSpatieLaravelActivitylog": "AlexJustesen\\FilamentSpatieLaravelActivitylog\\Facades\\FilamentSpatieLaravelActivitylog" 67 | } 68 | } 69 | }, 70 | "minimum-stability": "dev", 71 | "prefer-stable": true 72 | } 73 | -------------------------------------------------------------------------------- /config/filament-spatie-laravel-activitylog.php: -------------------------------------------------------------------------------- 1 | [ 6 | 'filament-resource' => AlexJustesen\FilamentSpatieLaravelActivitylog\Resources\ActivityResource::class, 7 | 'group' => null, 8 | 'sort' => null, 9 | ], 10 | 11 | 'paginate' => [5, 10, 25, 50], 12 | 13 | ]; 14 | -------------------------------------------------------------------------------- /resources/lang/ar/activity.php: -------------------------------------------------------------------------------- 1 | 'نوع المستخدم', 5 | 'causer_id' => 'معرف المستخدم', 6 | 'subject_type' => 'نوع الموضوع', 7 | 'subject_id' => 'معرف الموضوع', 8 | 'description' => 'الوصف', 9 | 'attributes' => 'السمات', 10 | 'old' => 'القيمة القديمة', 11 | 'subject' => 'الموضوع', 12 | 'logged_at' => 'وقت التسجيل', 13 | 'log' => 'سجل', 14 | 'plural_log' => 'سجلات', 15 | 'has_subject' => 'يحتوي على موضوع', 16 | 'label' => 'النشاط', 17 | 'plural_label' => 'النشاطات', 18 | ]; 19 | -------------------------------------------------------------------------------- /resources/lang/de/activity.php: -------------------------------------------------------------------------------- 1 | 'Auslösender Typ', 5 | 'causer_id' => 'Id des Auslösers', 6 | 'subject_type' => 'Typ des Subjekts', 7 | 'subject_id' => 'Id des Subjekts', 8 | 'description' => 'Beschreibung', 9 | 'attributes' => 'Neue Werte', 10 | 'old' => 'Alte Werte', 11 | 'subject' => 'Subjekt', 12 | 'logged_at' => 'Änderungszeit', 13 | 'log' => 'Log', 14 | 'plural_log' => 'Logs', 15 | 'has_subject' => 'besitzt Subjekt', 16 | 'label' => 'Aktivität', 17 | 'plural_label' => 'Aktivitäten', 18 | ]; 19 | -------------------------------------------------------------------------------- /resources/lang/en/activity.php: -------------------------------------------------------------------------------- 1 | 'Causer Type', 5 | 'causer_id' => 'Causer Id', 6 | 'subject_type' => 'Subject type', 7 | 'subject_id' => 'Subject Id', 8 | 'description' => 'Description', 9 | 'attributes' => 'Attributes', 10 | 'old' => 'Old', 11 | 'subject' => 'Subject', 12 | 'logged_at' => 'Logged at', 13 | 'log' => 'Log', 14 | 'plural_log' => 'Logs', 15 | 'has_subject' => 'Has Subject', 16 | 'label' => 'Activity', 17 | 'plural_label' => 'Activity', 18 | ]; 19 | -------------------------------------------------------------------------------- /resources/lang/es/activity.php: -------------------------------------------------------------------------------- 1 | 'Tipo de causante', 5 | 'causer_id' => 'Id del causante', 6 | 'subject_type' => 'Tipo de objeto sometido', 7 | 'subject_id' => 'Id del objeto sometido', 8 | 'description' => 'Descripción', 9 | 'attributes' => 'Atributos / valor(es) actual(es) o nuevo(s)', 10 | 'old' => 'Valor(es) anterior(es)', 11 | 'subject' => 'Asunto', 12 | 'logged_at' => 'Registrado el', 13 | 'log' => 'Log', 14 | 'plural_log' => 'Logs', 15 | 'has_subject' => 'Tiene objeto sometido', 16 | 'label' => 'Actividad', 17 | 'plural_label' => 'Registros de actividad' 18 | ]; 19 | -------------------------------------------------------------------------------- /resources/lang/pt_BR/activity.php: -------------------------------------------------------------------------------- 1 | 'Tipo de causa', 5 | 'causer_id' => 'ID do causador', 6 | 'subject_type' => 'Tipo do Sujeito', 7 | 'subject_id' => 'ID do Sujeito', 8 | 'description' => 'Descrição', 9 | 'attributes' => 'Atributos', 10 | 'old' => 'Antigo', 11 | 'subject' => 'Sujeito', 12 | 'logged_at' => 'Conectado em', 13 | 'log' => 'Log', 14 | 'plural_log' => 'Logs', 15 | 'has_subject' => 'Tem Sujeito', 16 | 'label' => 'Atividade', 17 | 'plural_label' => 'Atividades', 18 | ]; 19 | -------------------------------------------------------------------------------- /src/Contracts/IsActivitySubject.php: -------------------------------------------------------------------------------- 1 | resources([ 19 | config('filament-spatie-laravel-activitylog.resource.filament-resource') ?? ActivityResource::class, 20 | ]); 21 | } 22 | 23 | public function boot(Panel $panel): void 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/FilamentSpatieLaravelActivitylogServiceProvider.php: -------------------------------------------------------------------------------- 1 | name(self::$name) 17 | ->hasConfigFile('filament-spatie-laravel-activitylog') 18 | ->hasTranslations(); 19 | } 20 | 21 | public function packageBooted(): void 22 | { 23 | Livewire::component(ActivitiesRelationManager::class, ActivitiesRelationManager::class); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/RelationManagers/ActivitiesRelationManager.php: -------------------------------------------------------------------------------- 1 | schema([ 33 | Forms\Components\TextInput::make('causer_type') 34 | ->label(__('filament-spatie-activitylog::activity.causer_type')) 35 | ->columnSpan([ 36 | 'default' => 2, 37 | 'sm' => 1, 38 | ]), 39 | Forms\Components\TextInput::make('causer_id') 40 | ->label(__('filament-spatie-activitylog::activity.causer_id')) 41 | ->columnSpan([ 42 | 'default' => 2, 43 | 'sm' => 1, 44 | ]), 45 | Forms\Components\TextInput::make('subject_type') 46 | ->label(__('filament-spatie-activitylog::activity.subject_type')) 47 | ->columnSpan([ 48 | 'default' => 2, 49 | 'sm' => 1, 50 | ]), 51 | Forms\Components\TextInput::make('subject_id') 52 | ->label(__('filament-spatie-activitylog::activity.subject_id')) 53 | ->columnSpan([ 54 | 'default' => 2, 55 | 'sm' => 1, 56 | ]), 57 | Forms\Components\TextInput::make('description') 58 | ->label(__('filament-spatie-activitylog::activity.description'))->columnSpan(2), 59 | Forms\Components\KeyValue::make('properties.attributes') 60 | ->label(__('filament-spatie-activitylog::activity.attributes')) 61 | ->columnSpan([ 62 | 'default' => 2, 63 | 'sm' => 1, 64 | ]), 65 | Forms\Components\KeyValue::make('properties.old') 66 | ->label(__('filament-spatie-activitylog::activity.old')) 67 | ->columnSpan([ 68 | 'default' => 2, 69 | 'sm' => 1, 70 | ]), 71 | ]); 72 | } 73 | 74 | public static function table(Tables\Table $table): Tables\Table 75 | { 76 | return $table 77 | ->columns([ 78 | Tables\Columns\TextColumn::make('id') 79 | ->label('ID') 80 | ->sortable(), 81 | Tables\Columns\TextColumn::make('subject_type') 82 | ->label(__('filament-spatie-activitylog::activity.subject')) 83 | ->searchable(), 84 | Tables\Columns\TextColumn::make('description') 85 | ->label(__('filament-spatie-activitylog::activity.description')) 86 | ->searchable(), 87 | Tables\Columns\TextColumn::make('log_name') 88 | ->label(__('filament-spatie-activitylog::activity.log')), 89 | Tables\Columns\TextColumn::make('created_at') 90 | ->label(__('filament-spatie-activitylog::activity.logged_at')) 91 | ->dateTime(), 92 | ]) 93 | ->filters([ 94 | Tables\Filters\SelectFilter::make('event') 95 | ->multiple() 96 | ->options([ 97 | 'created' => 'Created', 98 | 'updated' => 'Updated', 99 | 'deleted' => 'Deleted', 100 | ]), 101 | Tables\Filters\Filter::make('created_at') 102 | ->form([ 103 | Forms\Components\DatePicker::make('logged_from') 104 | ->label('Logged from'), 105 | Forms\Components\DatePicker::make('logged_until') 106 | ->label('Logged until'), 107 | ]) 108 | ->query(function (Builder $query, array $data): Builder { 109 | return $query 110 | ->when( 111 | $data['logged_from'], 112 | fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date), 113 | ) 114 | ->when( 115 | $data['logged_until'], 116 | fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date), 117 | ); 118 | }) 119 | ->indicateUsing(function (array $data): array { 120 | $indicators = []; 121 | 122 | if ($data['logged_from'] ?? null) { 123 | $indicators['logged_from'] = 'Created from ' . Carbon::parse($data['logged_from'])->toFormattedDateString(); 124 | } 125 | 126 | if ($data['logged_until'] ?? null) { 127 | $indicators['logged_until'] = 'Created until ' . Carbon::parse($data['logged_until'])->toFormattedDateString(); 128 | } 129 | 130 | return $indicators; 131 | }), 132 | ]) 133 | ->bulkActions([]) 134 | ->defaultSort('id', 'DESC'); 135 | } 136 | 137 | public static function getNavigationGroup(): ?string 138 | { 139 | return config('filament-spatie-laravel-activitylog.resource.group') ?? parent::getNavigationGroup(); 140 | } 141 | 142 | public static function getNavigationSort(): ?int 143 | { 144 | return config('filament-spatie-laravel-activitylog.resource.sort') ?? parent::getNavigationSort(); 145 | } 146 | 147 | public static function getRelations(): array 148 | { 149 | return [ 150 | // 151 | ]; 152 | } 153 | 154 | public static function getPages(): array 155 | { 156 | return [ 157 | 'index' => Pages\ListActivities::route('/'), 158 | 'view' => Pages\ViewActivity::route('/{record}'), 159 | ]; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/Resources/ActivityResource/Pages/ListActivities.php: -------------------------------------------------------------------------------- 1 |