diff --git a/config/filament-activity-log.php b/config/filament-activity-log.php index 6b2477f..c697115 100644 --- a/config/filament-activity-log.php +++ b/config/filament-activity-log.php @@ -1,6 +1,6 @@ [ diff --git a/docs/002-installation.md b/docs/002-installation.md index e0ab999..c9110ea 100644 --- a/docs/002-installation.md +++ b/docs/002-installation.md @@ -1,11 +1,11 @@ --- title: Installation +permalink: /installation nav_order: 2 --- # Installation -## Install via Composer ____ {: .highlight } @@ -32,21 +32,3 @@ Optionally, you can publish the `translations` file with: ```bash php artisan vendor:publish --tag="filament-activity-log-translations" ``` - -## Adding Activity Page -____ - -Create a page in your pages folder `app/Filament/Pages/` and extends the `ListActivities` class. - -```php -schema([ - 'name', - 'email', - 'email_verified_at' => fn (Field $field) => $field->date()->badge(), - 'roles' => fn (Field $field) => $field->relation('name'), - 'media' => fn (Field $field) => $field->media(), - ]); - } -} -``` +The Logger class is a fundamental component of the "Filament Activity Log" package, responsible for capturing and logging activities related to specific models within your Laravel application. It offers powerful customization options to define precisely which events and data changes should be recorded, making it a flexible and versatile tool for tracking model-related actions. diff --git a/docs/004-fields.md b/docs/004-fields.md index 3d681ce..d2888ce 100644 --- a/docs/004-fields.md +++ b/docs/004-fields.md @@ -1,17 +1,21 @@ --- title: Fields +permalink: /fields nav_order: 4 +has_children: true --- # Fields +___ + In the context of the Logger class, you have the flexibility to define which fields and relations should be logged for your model. This allows you to track changes to specific attributes and related data. ### Badge ```php -$fields->schema([ +$logger->fields([ 'name' => 'badge:danger', // 'name' => fn (Field $field) => $field->badge('danger'), ]) @@ -24,7 +28,7 @@ ____ ### Enum ```php -$fields->schema([ +$logger->fields([ 'status' => fn (Field $field) => $field ->enum(App\Enums\OrderStatus::class) ->label('Status'), @@ -38,7 +42,7 @@ ____ ### Date & Time ```php -$fields->schema([ +$logger->fields([ // 'published_at' => 'date:j F, Y'', // 'published_at' => 'time', // 'published_at' => 'datetime', @@ -55,7 +59,7 @@ ____ ### Boolean ```php -$fields->schema([ +$logger->fields([ // 'is_visible' => 'boolean', 'is_visible' => fn (Field $field) => $field ->boolean() @@ -70,7 +74,7 @@ ____ ### Media ```php -$fields->schema([ +$logger->fields([ // 'media' => 'media', 'media' => fn (Field $field) => $field ->media(gallery: true) @@ -85,7 +89,7 @@ ____ ### Money ```php -$fields->schema([ +$logger->fields([ // 'price' => 'money:EUR', 'price' => fn (Field $field) => $field->money('EUR'), ]) @@ -98,7 +102,7 @@ ____ ### Key-Value ```php -$fields->schema([ +$logger->fields([ 'meta' => fn (Field $field) => $field ->view('key-value') ->label('Attributes'), @@ -112,7 +116,7 @@ ____ ### Relation ```php -$fields->schema([ +$logger->fields([ // 'categories' => 'relation:name', 'categories' => fn (Field $field) => $field ->relation('name') // get names only @@ -128,7 +132,7 @@ ____ ### Table ```php -$fields->schema([ +$logger->fields([ 'items' => fn (Field $field) => $field ->relation() ->table() diff --git a/docs/005-relation-manager.md b/docs/005-relation-manager.md new file mode 100644 index 0000000..6cf8821 --- /dev/null +++ b/docs/005-relation-manager.md @@ -0,0 +1,28 @@ +--- +title: Relation Manager +permalink: /relation-manager +nav_order: 5 +--- + +# Relation Manager + +___ + +In Filament, you can create special "relation managers" for handling related data in your resource. Imagine you have a resource with a relation called `accessories`. Here's a straightforward example of defining such a relation manager: + +```php +$logger->relationManagers([ + 'accessories' => fn (RelationManager $relationManager) => $relationManager + ->label('Accessory') + ->fields([ + 'name' => fn (Field $field) => $field + ->label(__('Label')), + + 'price' => fn (Field $field) => $field + ->label(__('Price')) + ->money('EUR'), + ]), +]); +``` + +By creating relation managers, you can organize and format related data the way you want in your Filament application. diff --git a/docs/005-usage-with-relations.md b/docs/005-usage-with-relations.md deleted file mode 100644 index 986e262..0000000 --- a/docs/005-usage-with-relations.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Usage with Relations -nav_order: 5 ---- - -# Usage with Relations - -If you want to log relations as well, you should comment out the `created` and `updated` events and mark fields as `relation`. - -```php -public static ?array $events = [ - // 'created', - // 'updated', - 'deleted', - 'restored', -]; - -public static function fields(Fields $fields): Fields -{ - return $fields->schema([ - 'roles' => fn (Field $field) => $field - ->relation('name'), - - 'media' => fn (Field $field) => $field - ->media(), - - 'items' => fn (Field $field) => $field - ->relation() - ->table() - ->resolveUsing(function ($model) { - return $model->items->map(fn ($item) => [ - 'Product' => Product::find($item->shop_product_id)->name, - 'Quantity' => $item->qty, - 'Unit Price' => $item->unit_price, - ])->toArray(); - }), - ]); -} -``` - -## Resource with pages - -When your Filament resource uses separate pages for creating and editing records, you can enable activity logging with the following methods: - -### CreateRecord - -To enable activity logging when creating records in Filament, you should use the `LogCreateRecord` trait in your `CreateRecord` class as follows: - -```php -use Noxo\FilamentActivityLog\Concerns\Resource\LogCreateRecord; - -class CreateUser extends CreateRecord -{ - use LogCreateRecord; // Add this trait to your CreateRecord class - - protected static string $resource = UserResource::class; -} -``` - -{: .highlight } -Already have `afterCreate` method? - -If you have custom logic within the `afterCreate` method, ensure to include the call to `logAfterCreate` at the end of your method. This will generate the activity log entry after the creation process is complete. - - -```php -public function afterCreate() -{ - // Your code to create the record... - - // Log the creation event with the activity logger - $this->logAfterCreate(); -} -``` - ---- - -### EditRecord - -To enable activity logging when editing records in Filament, you should use the `LogEditRecord` trait in your `EditRecord` class: - -```php -use Noxo\FilamentActivityLog\Concerns\Resource\LogEditRecord; - -class EditUser extends EditRecord -{ - use LogEditRecord; // Add this trait to your EditRecord class - - protected static string $resource = UserResource::class; -} -``` - -{: .highlight } -Already have `beforeValidate` or `afterSave` method? - -If you have custom logic within the `beforeValidate` method and/or `afterSave` method, make sure to call `logBeforeValidate` at the beginning of the `beforeValidate` method and `logAfterSave` at the end of the `afterSave` method. This ensures that the changes to the record, including any changes in the specified relations, are logged correctly. - -```php -public function beforeValidate() -{ - // Log the changes before validate - $this->logBeforeValidate(); - - // Your custom code for tasks before validate... -} - -public function afterSave() -{ - // Your custom code after the record is saved... - - // Log the changes after saving - $this->logAfterSave(); -} -``` - -_____ - -## Resource with modals - -When your Filament resource uses modals for creating and editing records, you can configure the logger for the `CreateAction` and `EditAction` as follows: - -### CreateAction - -To set the logger for the `CreateAction` on the resource's list page, you can use the `setLogger` method within the `getHeaderActions` method. Here's an example: - -```php -class ListUsers extends ListRecords -{ - protected static string $resource = UserResource::class; - - protected function getHeaderActions(): array - { - return [ - Filament\Actions\CreateAction::make() - ->setLogger(App\Filament\Loggers\UserLogger::class), - ]; - } -} -``` -In this code, the `CreateAction` is configured to use the `UserLogger` to log activity when creating records. - -### EditAction - -To set the logger for the `EditAction` within the resource table's actions, you can use the `setLogger` method as shown in the example below: - -```php -->actions([ - Tables\Actions\EditAction::make() - ->setLogger(App\Filament\Loggers\UserLogger::class), -]), -``` - -This configuration ensures that the `EditAction` logs activity using the `UserLogger` when editing records within your Filament resource. - -___ - -By specifying the logger for these actions, you can seamlessly integrate activity logging into your resource when using modals for creating and editing records. diff --git a/docs/006-resolve-using.md b/docs/006-resolve-using.md index 73ade34..04489cf 100644 --- a/docs/006-resolve-using.md +++ b/docs/006-resolve-using.md @@ -1,33 +1,34 @@ --- title: Resolve Using +permalink: /resolve-using nav_order: 6 --- # Resolve Using +___ + There may be cases in which you have custom fields or complex relations within your models that you wish to log in a structured manner. To achieve this, you can use the `resolveUsing` method. ```php -public static function fields(Fields $fields): Fields -{ - return $fields->schema([ - - 'roles' => fn (Field $field) => $field - ->relation() - ->resolveUsing(static function (Model $model): array { - return $model->roles - ->filter(fn($role) => $role->name !== 'super_secret_admin') - ->toArray(); - }), - // ->resolveUsing(function ($model) { - // return $model->items->map(fn ($item) => [ - // 'Product' => Product::find($item->shop_product_id)->name, - // 'Quantity' => $item->qty, - // 'Unit Price' => $item->unit_price, - // ])->toArray(); - // }) - ]); -} +return $logger->fields([ + + 'roles' => fn (Field $field) => $field + ->relation() + ->resolveUsing(static function (Model $model): array { + return $model->roles + ->filter(fn($role) => $role->name !== 'super_secret_admin') + ->toArray(); + }), + // ->resolveUsing(function ($model) { + // return $model->items->map(fn ($item) => [ + // 'Product' => Product::find($item->shop_product_id)->name, + // 'Quantity' => $item->qty, + // 'Unit Price' => $item->unit_price, + // ])->toArray(); + // }) + +]); ``` diff --git a/docs/007-events.md b/docs/007-events.md index ae26f02..b7b4e1d 100644 --- a/docs/007-events.md +++ b/docs/007-events.md @@ -1,16 +1,12 @@ --- title: Events +permalink: /events nav_order: 7 --- # Events -The Logger class provides an automatic event logging mechanism through the `$events` property, which captures common events like "created," "updated," "deleted," and "restored." Additionally, it allows you to manually trigger these events from anywhere in your code. Here's a brief explanation of how to use these manual event logging methods: - -### Automatic Event Logging: - -The `$events` property specifies the events that will be automatically logged by the Logger class without the need for manual intervention. The class will capture these events and create corresponding logs when they occur. - +___ ### Manual Event Logging: diff --git a/docs/008-link-causer-subject.md b/docs/008-link-causer-subject.md index 908627a..b475f66 100644 --- a/docs/008-link-causer-subject.md +++ b/docs/008-link-causer-subject.md @@ -1,10 +1,13 @@ --- title: Link Causer/Subject +permalink: /link-causer-subject nav_order: 8 --- # Link Causer/Subject +___ + In Filament Activity Log, you have the ability to link the "causer" and "subject" of an activity log entry. The "causer" is typically the user who performed an action, while the "subject" is the item or entity that was acted upon. To create links to these "causer" and "subject" pages, you can use the following code as a reference: ```php diff --git a/docs/_config.yml b/docs/_config.yml index 006f903..59b53aa 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -11,7 +11,7 @@ aux_links: defaults: - scope: - path: "*.md" + path: "**/*.md" values: layout: "default" @@ -48,3 +48,4 @@ gh_edit_view_mode: "edit" exclude: - CNAME + - _includes/ diff --git a/docs/_includes/head_custom.html b/docs/_includes/head_custom.html new file mode 100644 index 0000000..2279360 --- /dev/null +++ b/docs/_includes/head_custom.html @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/assets/favicons/android-chrome-192x192.png b/docs/assets/favicons/android-chrome-192x192.png new file mode 100644 index 0000000..b8859eb Binary files /dev/null and b/docs/assets/favicons/android-chrome-192x192.png differ diff --git a/docs/assets/favicons/apple-touch-icon.png b/docs/assets/favicons/apple-touch-icon.png new file mode 100644 index 0000000..6c51689 Binary files /dev/null and b/docs/assets/favicons/apple-touch-icon.png differ diff --git a/docs/assets/favicons/browserconfig.xml b/docs/assets/favicons/browserconfig.xml new file mode 100644 index 0000000..3eb43c6 --- /dev/null +++ b/docs/assets/favicons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #ffffff + + + diff --git a/docs/assets/favicons/favicon-16x16.png b/docs/assets/favicons/favicon-16x16.png new file mode 100644 index 0000000..8ff74c6 Binary files /dev/null and b/docs/assets/favicons/favicon-16x16.png differ diff --git a/docs/assets/favicons/favicon-32x32.png b/docs/assets/favicons/favicon-32x32.png new file mode 100644 index 0000000..f359e42 Binary files /dev/null and b/docs/assets/favicons/favicon-32x32.png differ diff --git a/docs/assets/favicons/favicon.ico b/docs/assets/favicons/favicon.ico new file mode 100644 index 0000000..7bcefc9 Binary files /dev/null and b/docs/assets/favicons/favicon.ico differ diff --git a/docs/assets/favicons/mstile-150x150.png b/docs/assets/favicons/mstile-150x150.png new file mode 100644 index 0000000..064686c Binary files /dev/null and b/docs/assets/favicons/mstile-150x150.png differ diff --git a/docs/assets/favicons/safari-pinned-tab.svg b/docs/assets/favicons/safari-pinned-tab.svg new file mode 100644 index 0000000..01d8fa5 --- /dev/null +++ b/docs/assets/favicons/safari-pinned-tab.svg @@ -0,0 +1,40 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + + + diff --git a/docs/assets/favicons/site.webmanifest b/docs/assets/favicons/site.webmanifest new file mode 100644 index 0000000..0051363 --- /dev/null +++ b/docs/assets/favicons/site.webmanifest @@ -0,0 +1,14 @@ +{ + "name": "Noxo", + "short_name": "Noxo", + "icons": [ + { + "src": "/assets/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/docs/fields/004.1-badge.md b/docs/fields/004.1-badge.md new file mode 100644 index 0000000..d83f252 --- /dev/null +++ b/docs/fields/004.1-badge.md @@ -0,0 +1,6 @@ +--- +title: Badge +parent: Fields +permalink: /fields#badge +nav_order: 4.1 +--- diff --git a/docs/fields/004.2-enum.md b/docs/fields/004.2-enum.md new file mode 100644 index 0000000..cf990f7 --- /dev/null +++ b/docs/fields/004.2-enum.md @@ -0,0 +1,6 @@ +--- +title: Enum +parent: Fields +permalink: /fields#enum +nav_order: 4.2 +--- diff --git a/docs/fields/004.3-datetime.md b/docs/fields/004.3-datetime.md new file mode 100644 index 0000000..8525bea --- /dev/null +++ b/docs/fields/004.3-datetime.md @@ -0,0 +1,6 @@ +--- +title: Date & Time +parent: Fields +permalink: /fields#date--time +nav_order: 4.3 +--- diff --git a/docs/fields/004.4-boolean.md b/docs/fields/004.4-boolean.md new file mode 100644 index 0000000..9fc3cb1 --- /dev/null +++ b/docs/fields/004.4-boolean.md @@ -0,0 +1,6 @@ +--- +title: Boolean +parent: Fields +permalink: /fields#boolean +nav_order: 4.4 +--- diff --git a/docs/fields/004.5-media.md b/docs/fields/004.5-media.md new file mode 100644 index 0000000..0cd50a5 --- /dev/null +++ b/docs/fields/004.5-media.md @@ -0,0 +1,6 @@ +--- +title: Media +parent: Fields +permalink: /fields#media +nav_order: 4.5 +--- diff --git a/docs/fields/004.6-money.md b/docs/fields/004.6-money.md new file mode 100644 index 0000000..024900d --- /dev/null +++ b/docs/fields/004.6-money.md @@ -0,0 +1,6 @@ +--- +title: Money +parent: Fields +permalink: /fields#money +nav_order: 4.6 +--- diff --git a/docs/fields/004.7-key-value.md b/docs/fields/004.7-key-value.md new file mode 100644 index 0000000..3b18486 --- /dev/null +++ b/docs/fields/004.7-key-value.md @@ -0,0 +1,6 @@ +--- +title: Key-Value +parent: Fields +permalink: /fields#key-value +nav_order: 4.7 +--- diff --git a/docs/fields/004.8-relation.md b/docs/fields/004.8-relation.md new file mode 100644 index 0000000..9b03cfa --- /dev/null +++ b/docs/fields/004.8-relation.md @@ -0,0 +1,6 @@ +--- +title: Relation +parent: Fields +permalink: /fields#relation +nav_order: 4.8 +--- diff --git a/docs/fields/004.9-table.md b/docs/fields/004.9-table.md new file mode 100644 index 0000000..48dad80 --- /dev/null +++ b/docs/fields/004.9-table.md @@ -0,0 +1,6 @@ +--- +title: Table +parent: Fields +permalink: /fields#table +nav_order: 4.9 +--- diff --git a/docs/get-started/003.1-create-activities-page.md b/docs/get-started/003.1-create-activities-page.md new file mode 100644 index 0000000..b4cfc03 --- /dev/null +++ b/docs/get-started/003.1-create-activities-page.md @@ -0,0 +1,27 @@ +--- +title: Create Activity Page +permalink: /get-started/create-activity-page +parent: Get Started +nav_order: 3.1 +--- + +# Create Activity Page + +____ + +Create a page in your pages folder `app/Filament/Pages/` and extends the `ListActivities` class. + +```php +fields([ + 'title' => fn (Field $field) => $field + ->label(__('Title')), + + 'categories' => fn (Field $field) => $field + ->label(__('Categories')) + ->relation('name'), + + 'media' => fn (Field $field) => $field + ->label(__('Images')) + ->media(gallery: true), + + 'price' => fn (Field $field) => $field + ->label(__('Price')) + ->money('EUR'), + + 'status' => fn (Field $field) => $field + ->label(__('Status')) + ->enum(ProductStatus::class), + + 'active' => fn (Field $field) => $field + ->label(__('Visible')) + ->boolean(), + ]) + // Relation Managers + ->relationManagers([ + 'accessories' => fn (RelationManager $relationManager) => $relationManager + ->label('Accessory') + ->fields([ + 'name' => fn (Field $field) => $field + ->label(__('Label')), + + 'price' => fn (Field $field) => $field + ->label(__('Price')) + ->money('EUR'), + ]), + ]); + } +} +``` + diff --git a/docs/get-started/003.4-resource-with-pages.md b/docs/get-started/003.4-resource-with-pages.md new file mode 100644 index 0000000..07b3bfd --- /dev/null +++ b/docs/get-started/003.4-resource-with-pages.md @@ -0,0 +1,80 @@ +--- +title: Resource with pages +permalink: /get-started/resource-with-pages +parent: Get Started +nav_order: 3.4 +--- + +# Resource with pages + +___ + +When your Filament resource uses separate pages for creating and editing records, you need to enable activity logging with the following methods: + +## CreateRecord + +To enable activity logging when creating records in Filament, you should use the `LogCreateRecord` trait in your `CreateRecord` class as follows: + +```php +use Noxo\FilamentActivityLog\Extensions\LogCreateRecord; + +class CreateProduct extends CreateRecord +{ + use LogCreateRecord; // <--- here + + protected static string $resource = ProductResource::class; +} +``` + +{: .highlight } +Already have `afterCreate` method? + +If you have custom logic within the `afterCreate` method, ensure to include the call to `logAfterCreate` at the end of your method. This will generate the activity log entry after the creation process is complete. + + +```php +public function afterCreate() +{ + // your code... + + $this->logRecordCreated($this->record); +} +``` + +--- + +## EditRecord + +To enable activity logging when editing records in Filament, you should use the `LogEditRecord` trait in your `EditRecord` class: + +```php +use Noxo\FilamentActivityLog\Extensions\LogEditRecord; + +class EditProduct extends EditRecord +{ + use LogEditRecord; // <--- here + + protected static string $resource = ProductResource::class; +} +``` + +{: .highlight } +Already have `beforeValidate` or `afterSave` method? + +If you have custom logic within the `beforeValidate` method and/or `afterSave` method, make sure to call `logBeforeValidate` at the beginning of the `beforeValidate` method and `logAfterSave` at the end of the `afterSave` method. This ensures that the changes to the record, including any changes in the specified relations, are logged correctly. + +```php +public function beforeValidate() +{ + $this->logRecordBefore($this->record); + + // your code... +} + +public function afterSave() +{ + // your code... + + $this->logRecordAfter($this->record); +} +``` diff --git a/resources/dist/filament-activity-log.css b/resources/dist/filament-activity-log.css index eaf9644..ea5a30e 100644 --- a/resources/dist/filament-activity-log.css +++ b/resources/dist/filament-activity-log.css @@ -1 +1 @@ -.right-4{right:1rem}.top-1{top:.25rem}.top-20{top:5rem}.\!h-10{height:2.5rem!important}.\!w-10{width:2.5rem!important}.w-fit{width:-moz-fit-content;width:fit-content}.\!whitespace-normal{white-space:normal!important}.break-all{word-break:break-all}.bg-blue-50\/70{background-color:#eff6ffb3}.bg-gray-100\/30{background-color:rgba(var(--gray-100),.3)}.bg-gray-50\/70{background-color:rgba(var(--gray-50),.7)}.bg-green-50\/70{background-color:#f0fdf4b3}.bg-orange-50\/70{background-color:#fff7edb3}.bg-red-50\/70{background-color:#fef2f2b3}.\!py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.align-top{vertical-align:top}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.shadow,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.group:hover .group-hover\:opacity-100{opacity:1}:is([dir=rtl] .rtl\:divide-x-reverse)>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:1}:is(.dark .dark\:divide-white\/20)>:not([hidden])~:not([hidden]){border-color:#fff3}:is(.dark .dark\:border-blue-600){--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgba(var(--gray-600),var(--tw-border-opacity))}:is(.dark .dark\:border-green-600){--tw-border-opacity:1;border-color:rgb(22 163 74/var(--tw-border-opacity))}:is(.dark .dark\:border-orange-600){--tw-border-opacity:1;border-color:rgb(234 88 12/var(--tw-border-opacity))}:is(.dark .dark\:border-red-600){--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}:is(.dark .dark\:bg-blue-100\/10){background-color:#dbeafe1a}:is(.dark .dark\:bg-blue-700){--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-100\/10){background-color:rgba(var(--gray-100),.1)}:is(.dark .dark\:bg-gray-700){--tw-bg-opacity:1;background-color:rgba(var(--gray-700),var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-800){--tw-bg-opacity:1;background-color:rgba(var(--gray-800),var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgba(var(--gray-900),var(--tw-bg-opacity))}:is(.dark .dark\:bg-green-100\/10){background-color:#dcfce71a}:is(.dark .dark\:bg-green-700){--tw-bg-opacity:1;background-color:rgb(21 128 61/var(--tw-bg-opacity))}:is(.dark .dark\:bg-orange-100\/10){background-color:#ffedd51a}:is(.dark .dark\:bg-orange-700){--tw-bg-opacity:1;background-color:rgb(194 65 12/var(--tw-bg-opacity))}:is(.dark .dark\:bg-red-100\/10){background-color:#fee2e21a}:is(.dark .dark\:bg-red-700){--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}:is(.dark .dark\:bg-transparent){background-color:initial}:is(.dark .dark\:text-blue-200){--tw-text-opacity:1;color:rgb(191 219 254/var(--tw-text-opacity))}:is(.dark .dark\:text-blue-300){--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgba(var(--gray-200),var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgba(var(--gray-300),var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgba(var(--gray-400),var(--tw-text-opacity))}:is(.dark .dark\:text-green-200){--tw-text-opacity:1;color:rgb(187 247 208/var(--tw-text-opacity))}:is(.dark .dark\:text-green-300){--tw-text-opacity:1;color:rgb(134 239 172/var(--tw-text-opacity))}:is(.dark .dark\:text-orange-200){--tw-text-opacity:1;color:rgb(254 215 170/var(--tw-text-opacity))}:is(.dark .dark\:text-orange-300){--tw-text-opacity:1;color:rgb(253 186 116/var(--tw-text-opacity))}:is(.dark .dark\:text-red-200){--tw-text-opacity:1;color:rgb(254 202 202/var(--tw-text-opacity))}:is(.dark .dark\:text-red-300){--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity))}:is(.dark .dark\:ring-white\/20){--tw-ring-color:#fff3} \ No newline at end of file +.right-4{right:1rem}.top-1{top:.25rem}.top-20{top:5rem}.\!h-10{height:2.5rem!important}.\!w-10{width:2.5rem!important}.w-fit{width:-moz-fit-content;width:fit-content}.\!whitespace-normal{white-space:normal!important}.break-all{word-break:break-all}.bg-blue-50\/70{background-color:#eff6ffb3}.bg-gray-100\/30{background-color:rgba(var(--gray-100),.3)}.bg-gray-50\/70{background-color:rgba(var(--gray-50),.7)}.bg-green-50\/70{background-color:#f0fdf4b3}.bg-orange-50\/70{background-color:#fff7edb3}.bg-red-50\/70{background-color:#fef2f2b3}.\!py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.align-top{vertical-align:top}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.shadow,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.group:hover .group-hover\:opacity-100{opacity:1}:is([dir=rtl] .rtl\:divide-x-reverse)>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:1}:is(.dark .dark\:divide-white\/20)>:not([hidden])~:not([hidden]){border-color:#fff3}:is(.dark .dark\:border-blue-600){--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgba(var(--gray-600),var(--tw-border-opacity))}:is(.dark .dark\:border-green-600){--tw-border-opacity:1;border-color:rgb(22 163 74/var(--tw-border-opacity))}:is(.dark .dark\:border-orange-600){--tw-border-opacity:1;border-color:rgb(234 88 12/var(--tw-border-opacity))}:is(.dark .dark\:border-red-600){--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}:is(.dark .dark\:bg-blue-100\/10){background-color:#dbeafe1a}:is(.dark .dark\:bg-gray-100\/10){background-color:rgba(var(--gray-100),.1)}:is(.dark .dark\:bg-gray-700){--tw-bg-opacity:1;background-color:rgba(var(--gray-700),var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-800){--tw-bg-opacity:1;background-color:rgba(var(--gray-800),var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgba(var(--gray-900),var(--tw-bg-opacity))}:is(.dark .dark\:bg-green-100\/10){background-color:#dcfce71a}:is(.dark .dark\:bg-orange-100\/10){background-color:#ffedd51a}:is(.dark .dark\:bg-red-100\/10){background-color:#fee2e21a}:is(.dark .dark\:bg-transparent){background-color:initial}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgba(var(--gray-200),var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgba(var(--gray-300),var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgba(var(--gray-400),var(--tw-text-opacity))}:is(.dark .dark\:text-green-400){--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity))}:is(.dark .dark\:text-orange-400){--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity))}:is(.dark .dark\:text-red-400){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity))}:is(.dark .dark\:ring-white\/20){--tw-ring-color:#fff3} \ No newline at end of file diff --git a/resources/lang/en/activities.php b/resources/lang/en/activities.php index f7addb6..f36d273 100644 --- a/resources/lang/en/activities.php +++ b/resources/lang/en/activities.php @@ -21,21 +21,21 @@ 'no_records_yet' => 'There are no entries yet', ], 'events' => [ - 'updated' => [ - 'title' => 'Updated', - 'description' => 'The record was updated at :time', - ], 'created' => [ 'title' => 'Created', - 'description' => 'The record was created at :time', + 'description' => 'Entry created', + ], + 'updated' => [ + 'title' => 'Updated', + 'description' => 'Entry updated', ], 'deleted' => [ 'title' => 'Deleted', - 'description' => 'Record was deleted at :time', + 'description' => 'Entry deleted', ], 'restored' => [ 'title' => 'Restored', - 'description' => 'Record was restored at :time', + 'description' => 'Entry restored', ], // Your custom events... ], diff --git a/resources/lang/uk/activities.php b/resources/lang/uk/activities.php index 3c099ce..0d26221 100644 --- a/resources/lang/uk/activities.php +++ b/resources/lang/uk/activities.php @@ -21,21 +21,21 @@ 'no_records_yet' => 'Поки що немає записів', ], 'events' => [ - 'updated' => [ - 'title' => 'Оновлено', - 'description' => 'Запис було оновлено в :time', - ], 'created' => [ 'title' => 'Створено', - 'description' => 'Запис було створено в :time', + 'description' => 'Запис створено', + ], + 'updated' => [ + 'title' => 'Оновлено', + 'description' => 'Запис оновлено', ], 'deleted' => [ 'title' => 'Видалено', - 'description' => 'Запис було видалено в :time', + 'description' => 'Запис видалено', ], 'restored' => [ 'title' => 'Відновлено', - 'description' => 'Запис було відновлено в :time', + 'description' => 'Запис відновлено', ], // Your custom events... ], diff --git a/resources/views/list/header.blade.php b/resources/views/list/header.blade.php index 8575649..fccd304 100644 --- a/resources/views/list/header.blade.php +++ b/resources/views/list/header.blade.php @@ -1,6 +1,6 @@
{{ $activity->causer?->name }} - @php - $event = $activity->event; - $eventStyle = match ($event) { - 'created' => 'bg-green-50/70 dark:bg-green-100/10 text-green-700 dark:text-green-200 dark:border-green-600 dark:bg-green-700 dark:text-green-300', - 'updated' => 'bg-blue-50/70 dark:bg-blue-100/10 text-blue-700 dark:text-blue-200 dark:border-blue-600 dark:bg-blue-700 dark:text-blue-300', - 'deleted' => 'bg-red-50/70 dark:bg-red-100/10 text-red-700 dark:text-red-200 dark:border-red-600 dark:bg-red-700 dark:text-red-300', - 'restored' => 'bg-orange-50/70 dark:bg-orange-100/10 text-orange-700 dark:text-orange-200 dark:border-orange-600 dark:bg-orange-700 dark:text-orange-300', - default => 'bg-gray-50/70 dark:bg-gray-100/10 text-gray-700 dark:text-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300', - }; - @endphp - - @lang("filament-activity-log::activities.events.{$event}.description", [ - 'time' => $activity->created_at->translatedFormat(__('filament-activity-log::activities.time_format')), - ]) + + {{ $activity->created_at->translatedFormat(__('filament-activity-log::activities.time_format')) }}
+ @php + $subject_label = $logger->getLabel(); + + $event = $activity->event; + $eventStyle = match ($event) { + 'created' => 'bg-green-50/70 dark:bg-green-100/10 text-green-700 dark:text-green-400 dark:border-green-600', + 'updated' => 'bg-blue-50/70 dark:bg-blue-100/10 text-blue-700 dark:text-blue-400 dark:border-blue-600', + 'deleted' => 'bg-red-50/70 dark:bg-red-100/10 text-red-700 dark:text-red-400 dark:border-red-600', + 'restored' => 'bg-orange-50/70 dark:bg-orange-100/10 text-orange-700 dark:text-orange-400 dark:border-orange-600', + default => 'bg-gray-50/70 dark:bg-gray-100/10 text-gray-700 dark:text-gray-400 dark:border-gray-600', + }; + @endphp + + + @lang("filament-activity-log::activities.events.{$event}.description") + + + @if ($logger->relationManager) +
+ {{ $logger->relationManager->getLabel() }} + #{{ $activity->properties['relation_manager']['id'] ?? '–' }} +
+ @endif +
- {{ $this->getSubjectLabel($activity) }} + {{ $subject_label }} #{{ $activity->subject_id }}
diff --git a/resources/views/list/item.blade.php b/resources/views/list/item.blade.php index c832195..03d6ad9 100644 --- a/resources/views/list/item.blade.php +++ b/resources/views/list/item.blade.php @@ -1,6 +1,6 @@
- {{ view('filament-activity-log::list.tables.' . $table, compact('activity', 'changes')) }} + {{ view('filament-activity-log::list.tables.' . $table, compact('changes', 'logger')) }}
@endif
diff --git a/resources/views/list/tables/default.blade.php b/resources/views/list/tables/default.blade.php index 9012d49..05e8c4d 100644 --- a/resources/views/list/tables/default.blade.php +++ b/resources/views/list/tables/default.blade.php @@ -13,7 +13,7 @@ @foreach ($changes['attributes'] as $key => $newValue) @php - $field = $this->getField($activity, $key); + $field = $logger->getFieldByName($key); if (!$field) { continue; } diff --git a/resources/views/list/tables/simple.blade.php b/resources/views/list/tables/simple.blade.php index 33e40af..c08f8e5 100644 --- a/resources/views/list/tables/simple.blade.php +++ b/resources/views/list/tables/simple.blade.php @@ -10,7 +10,7 @@ @foreach ($changes['attributes'] as $key => $value) @php - $field = $this->getField($activity, $key); + $field = $logger->getFieldByName($key); if (!$field) { continue; } diff --git a/src/Commands/MakeLoggerCommand.php b/src/Commands/MakeLoggerCommand.php index 9a9d03a..52f2272 100644 --- a/src/Commands/MakeLoggerCommand.php +++ b/src/Commands/MakeLoggerCommand.php @@ -94,6 +94,7 @@ public function handle(): int 'namespace' => $namespace, 'class' => $loggerClass, 'modelClass' => $modelClass, + 'resourceNamespace' => config('filament-activity-log.loggers.namespace'), 'modelNamespace' => 'App\\Models' . ($modelNamespace !== '' ? "\\{$modelNamespace}" : '') . '\\' . $modelClass, ]); diff --git a/src/Concerns/Resource/LogCreateRecord.php b/src/Concerns/Resource/LogCreateRecord.php deleted file mode 100644 index b217108..0000000 --- a/src/Concerns/Resource/LogCreateRecord.php +++ /dev/null @@ -1,25 +0,0 @@ -logAfterCreate(); - } - - public function logAfterCreate() - { - $logger = Loggers::getLoggerByModel(self::getResource()::getModel()); - - if ($logger && ! $logger::$disabled) { - $relations = $logger::fields(new Fields)->getRelationNames(); - $record = $this->record->load($relations); - $logger::make($record)->created(); - } - } -} diff --git a/src/Concerns/Resource/LogEditRecord.php b/src/Concerns/Resource/LogEditRecord.php deleted file mode 100644 index 32ae35e..0000000 --- a/src/Concerns/Resource/LogEditRecord.php +++ /dev/null @@ -1,44 +0,0 @@ -logBeforeValidate(); - } - - public function afterSave() - { - $this->logAfterSave(); - } - - public function logBeforeValidate() - { - $this->logger = Loggers::getLoggerByModel(self::getResource()::getModel()); - - if ($this->logger && ! $this->logger::$disabled) { - $this->log_model_old = clone $this->record->load( - $this->logger::fields(new Fields)->getRelationNames() - ); - } - } - - public function logAfterSave() - { - if ($this->logger && ! $this->logger::$disabled) { - $log_model_new = $this->record->load( - $this->logger::fields(new Fields)->getRelationNames() - ); - $this->logger::make($this->log_model_old, $log_model_new)->updated(); - } - } -} diff --git a/src/Extensions/Concerns/HasCreated.php b/src/Extensions/Concerns/HasCreated.php new file mode 100644 index 0000000..9aec761 --- /dev/null +++ b/src/Extensions/Concerns/HasCreated.php @@ -0,0 +1,34 @@ +load($logger::getResourceLogger()->getRelationNames()); + $logger::make($record)->created(); + } + + public function logManagerCreated($livewire, $record): void + { + $ownerRecord = $livewire->ownerRecord; + if (! $logger = Helper::resolveLogger($ownerRecord)) { + return; + } + + $manager = $logger::getRelationManager($livewire->getRelationshipName()); + $record->load($manager->getRelationNames()); + + $logger::make($record) + ->relationManager($manager) + ->ownerRecord($ownerRecord) + ->created(); + } +} diff --git a/src/Extensions/Concerns/HasDeleted.php b/src/Extensions/Concerns/HasDeleted.php new file mode 100644 index 0000000..612970a --- /dev/null +++ b/src/Extensions/Concerns/HasDeleted.php @@ -0,0 +1,34 @@ +load($logger::getResourceLogger()->getRelationNames()); + $logger::make($record)->deleted(); + } + + public function logManagerDeleted($livewire, $record): void + { + $ownerRecord = $livewire->ownerRecord; + if (! $logger = Helper::resolveLogger($ownerRecord)) { + return; + } + + $manager = $logger::getRelationManager($livewire->getRelationshipName()); + $record->load($manager->getRelationNames()); + + $logger::make($record) + ->relationManager($manager) + ->ownerRecord($ownerRecord) + ->deleted(); + } +} diff --git a/src/Extensions/Concerns/HasRestored.php b/src/Extensions/Concerns/HasRestored.php new file mode 100644 index 0000000..433ece5 --- /dev/null +++ b/src/Extensions/Concerns/HasRestored.php @@ -0,0 +1,34 @@ +load($logger::getResourceLogger()->getRelationNames()); + $logger::make($record)->restored(); + } + + public function logManagerRestored($livewire, $record): void + { + $ownerRecord = $livewire->ownerRecord; + if (! $logger = Helper::resolveLogger($ownerRecord)) { + return; + } + + $manager = $logger::getRelationManager($livewire->getRelationshipName()); + $record->load($manager->getRelationNames()); + + $logger::make($record) + ->relationManager($manager) + ->ownerRecord($ownerRecord) + ->restored(); + } +} diff --git a/src/Extensions/Concerns/HasUpdated.php b/src/Extensions/Concerns/HasUpdated.php new file mode 100644 index 0000000..51595dc --- /dev/null +++ b/src/Extensions/Concerns/HasUpdated.php @@ -0,0 +1,60 @@ +logger = Helper::resolveLogger($record)) { + return; + } + + $this->model_old = clone $record->load( + $this->logger::getResourceLogger()->getRelationNames() + ); + } + + public function logRecordAfter($record): void + { + if (! $this->logger) { + return; + } + + $record->load($this->logger::getResourceLogger()->getRelationNames()); + $this->logger::make($this->model_old, $record)->updated(); + } + + public function logManagerBefore($livewire, $record): void + { + $ownerRecord = $livewire->ownerRecord; + if (! $this->logger = Helper::resolveLogger($ownerRecord)) { + return; + } + + $manager = $this->logger::getRelationManager($livewire->getRelationshipName()); + $this->model_old = clone $record->load($manager->getRelationNames()); + } + + public function logManagerAfter($livewire, $record): void + { + if (! $this->logger) { + return; + } + + $manager = $this->logger::getRelationManager($livewire->getRelationshipName()); + $record->load($manager->getRelationNames()); + + $this->logger::make($this->model_old, $record) + ->relationManager($manager) + ->ownerRecord($livewire->ownerRecord) + ->updated(); + } +} diff --git a/src/Extensions/LogActions.php b/src/Extensions/LogActions.php new file mode 100644 index 0000000..8bde3a7 --- /dev/null +++ b/src/Extensions/LogActions.php @@ -0,0 +1,82 @@ + $self->associate($action)); + // TableActions\AttachAction::configureUsing(fn ($action) => $self->attach($action)); + TableActions\CreateAction::configureUsing(fn ($action) => $self->create($action)); + TableActions\DeleteAction::configureUsing(fn ($action) => $self->delete($action)); + // TableActions\DetachAction::configureUsing(fn ($action) => $self->detach($action)); + // TableActions\DissociateAction::configureUsing(fn ($action) => $self->dissociate($action)); + TableActions\EditAction::configureUsing(fn ($action) => $self->edit($action)); + TableActions\ForceDeleteAction::configureUsing(fn ($action) => $self->delete($action)); + TableActions\ReplicateAction::configureUsing(fn ($action) => $self->create($action)); + TableActions\RestoreAction::configureUsing(fn ($action) => $self->restore($action)); + + // * Page Actions + PageActions\CreateAction::configureUsing(fn ($action) => $self->create($action)); + PageActions\DeleteAction::configureUsing(fn ($action) => $self->delete($action)); + PageActions\EditAction::configureUsing(fn ($action) => $self->edit($action)); + PageActions\ForceDeleteAction::configureUsing(fn ($action) => $self->delete($action)); + PageActions\ReplicateAction::configureUsing(fn ($action) => $self->create($action)); + PageActions\RestoreAction::configureUsing(fn ($action) => $self->restore($action)); + } + + public function create($action): void + { + $action->after(function ($livewire, $record): void { + $livewire instanceof RelationManager + ? $this->logManagerCreated($livewire, $record) + : $this->logRecordCreated($record); + }); + } + + public function delete($action): void + { + $action->before(function ($livewire, $record): void { + $livewire instanceof RelationManager + ? $this->logManagerDeleted($livewire, $record) + : $this->logRecordDeleted($record); + }); + } + + public function edit($action): void + { + $action->beforeFormValidated(function ($livewire, $record): void { + $livewire instanceof RelationManager + ? $this->logManagerBefore($livewire, $record) + : $this->logRecordBefore($record); + }); + + $action->after(function ($livewire, $record): void { + $livewire instanceof RelationManager + ? $this->logManagerAfter($livewire, $record) + : $this->logRecordAfter($record); + }); + } + + public function restore($action): void + { + $action->after(function ($livewire, $record): void { + $livewire instanceof RelationManager + ? $this->logManagerRestored($livewire, $record) + : $this->logRecordRestored($record); + }); + } +} diff --git a/src/Extensions/LogCreateRecord.php b/src/Extensions/LogCreateRecord.php new file mode 100644 index 0000000..0edcc52 --- /dev/null +++ b/src/Extensions/LogCreateRecord.php @@ -0,0 +1,13 @@ +logRecordCreated($this->record); + } +} diff --git a/src/Extensions/LogEditRecord.php b/src/Extensions/LogEditRecord.php new file mode 100644 index 0000000..c50987a --- /dev/null +++ b/src/Extensions/LogEditRecord.php @@ -0,0 +1,18 @@ +logRecordBefore($this->record); + } + + public function afterSave() + { + $this->logRecordAfter($this->record); + } +} diff --git a/src/Fields/Fields.php b/src/Fields/Fields.php deleted file mode 100644 index e8ee069..0000000 --- a/src/Fields/Fields.php +++ /dev/null @@ -1,8 +0,0 @@ -getOriginal()); - $new = $model::make($model->getAttributes()); - $old->id = $model->id; - static::make($old, $new)->updated(); - } else { - static::make($model)->{$event}(); - } - }); - } - } - /** * Log when a model is created. */ diff --git a/src/Loggers/Concerns/HasLabel.php b/src/Loggers/Concerns/HasLabel.php new file mode 100644 index 0000000..e727b3e --- /dev/null +++ b/src/Loggers/Concerns/HasLabel.php @@ -0,0 +1,18 @@ +afterLast('\\') + ->kebab() + ->replace(['-', '_'], ' ') + ->ucfirst(); + } +} diff --git a/src/Loggers/Concerns/HasRelationManager.php b/src/Loggers/Concerns/HasRelationManager.php new file mode 100644 index 0000000..ac731b8 --- /dev/null +++ b/src/Loggers/Concerns/HasRelationManager.php @@ -0,0 +1,36 @@ +relationManager = $manager; + + return $this; + } + + public function ownerRecord(Model $model): static + { + $this->ownerRecord = $model; + + return $this; + } + + public static function getRelationManager(string $name): ?RelationManager + { + return static::getResourceLogger()->getRelationManager($name); + } +} diff --git a/src/Loggers/Concerns/HasResourceLogger.php b/src/Loggers/Concerns/HasResourceLogger.php new file mode 100644 index 0000000..912e849 --- /dev/null +++ b/src/Loggers/Concerns/HasResourceLogger.php @@ -0,0 +1,37 @@ +relationManager) { + return $this->relationManager->getFields(); + } + + return $this->getResourceLogger()->getFields(); + } + + public function getFieldByName(string $name): ?Field + { + if ($this->relationManager) { + return $this->relationManager->getFieldByName($name); + } + + return $this->getResourceLogger()->getFieldByName($name); + } +} diff --git a/src/Loggers/Concerns/Loggable.php b/src/Loggers/Concerns/Loggable.php index 225a3d4..0590005 100644 --- a/src/Loggers/Concerns/Loggable.php +++ b/src/Loggers/Concerns/Loggable.php @@ -2,38 +2,50 @@ namespace Noxo\FilamentActivityLog\Loggers\Concerns; +use Illuminate\Database\Eloquent\Model; + trait Loggable { /** * Log the properties if the condition is met. */ - public function logIf(bool $condition, array $properties, string $event): void + public function logIf(bool $condition, ...$args): void { if ($condition) { - $this->log($properties, $event); + $this->log(...$args); } } /** * Log the properties Unless the condition is met. */ - public function logUnless(bool $condition, array $properties, string $event): void + public function logUnless(bool $condition, ...$args): void { if (! $condition) { - $this->log($properties, $event); + $this->log(...$args); } } /** * Log the properties. */ - public function log(array $properties, string $event): void + public function log(array $properties, string $event, Model $modelOn = null): void { + $modelOn ??= $this->newModel; + + if ($this->relationManager && $this->ownerRecord) { + $modelOn = $this->ownerRecord; + $properties['relation_manager'] = [ + 'name' => $this->relationManager->name, + 'id' => $this->newModel->id, + ]; + } + // $this?->beforeLog(); $activity = activity() ->event($event) - ->on($this->newModel) + ->on($modelOn) ->withProperties($properties) ->log($event); diff --git a/src/Loggers/Logger.php b/src/Loggers/Logger.php index 37115f0..117731f 100644 --- a/src/Loggers/Logger.php +++ b/src/Loggers/Logger.php @@ -4,13 +4,14 @@ use Closure; use DragonCode\Support\Concerns\Makeable; -use Illuminate\Contracts\Support\Htmlable; use Illuminate\Database\Eloquent\Model; -use Noxo\FilamentActivityLog\Fields; class Logger { use Concerns\HasEvents; + use Concerns\HasLabel; + use Concerns\HasRelationManager; + use Concerns\HasResourceLogger; use Concerns\Loggable; use Makeable; @@ -18,11 +19,11 @@ class Logger public static ?string $model; - protected Model $newModel; + protected ?Model $newModel; protected ?Model $oldModel; - public function __construct(Model $newModel, Model $oldModel = null) + public function __construct(Model $newModel = null, Model $oldModel = null) { if (is_null($oldModel)) { $this->newModel = $newModel; @@ -33,17 +34,8 @@ public function __construct(Model $newModel, Model $oldModel = null) } } - public static function getLabel(): string | Htmlable | null - { - return (string) str(static::$model) - ->afterLast('\\') - ->kebab() - ->replace(['-', '_'], ' ') - ->ucfirst(); - } - /** - * Perform actions through a closure and update the "modelAfter." + * @deprecated */ public function through(Closure $callback): static { @@ -53,17 +45,4 @@ public function through(Closure $callback): static return $this; } - - public static function fields(Fields\Fields $fields): Fields\Fields - { - return $fields; - } - - /** - * @return array - */ - public function getFields(): array - { - return static::fields(new Fields\Fields)->getFields(); - } } diff --git a/src/Loggers/Loggers.php b/src/Loggers/Loggers.php index ae6e9b5..30b7b95 100644 --- a/src/Loggers/Loggers.php +++ b/src/Loggers/Loggers.php @@ -10,12 +10,12 @@ class Loggers public static array $loggers = []; /** - * Get a logger by model class. + * @return class-string */ - public static function getLoggerByModel(string $model): ?string + public static function getLoggerByModel(string $model, bool $force = false): ?string { foreach (self::$loggers as $logger) { - if ($logger::$model === $model) { + if ($logger::$model === $model && (! $logger::$disabled || $force)) { return $logger; } } @@ -79,11 +79,4 @@ public static function discover(): void self::$loggers[] = $class; } } - - public static function registerEvents(): void - { - foreach (self::$loggers as $logger) { - $logger::registerEvents(); - } - } } diff --git a/src/Macros/CreateAction.php b/src/Macros/CreateAction.php deleted file mode 100644 index 4e264c1..0000000 --- a/src/Macros/CreateAction.php +++ /dev/null @@ -1,24 +0,0 @@ -after(function ($record) use ($logger) { - $record = $record->load( - $logger::fields(new Fields)->getRelationNames() - ); - $logger::make($record)->created(); - }); - } - - return $this; - }; - } -} diff --git a/src/Macros/EditAction.php b/src/Macros/EditAction.php deleted file mode 100644 index 15494c7..0000000 --- a/src/Macros/EditAction.php +++ /dev/null @@ -1,32 +0,0 @@ -beforeFormValidated(function ($record) use (&$model_old, $logger) { - $model_old = clone $record->load( - $logger::fields(new Fields)->getRelationNames() - ); - }); - - $this->after(function ($record) use (&$model_old, $logger) { - $model_new = $record->load( - $logger::fields(new Fields)->getRelationNames() - ); - $logger::make($model_old, $model_new)->updated(); - }); - } - - return $this; - }; - } -} diff --git a/src/Pages/Concerns/HasLogger.php b/src/Pages/Concerns/HasLogger.php new file mode 100644 index 0000000..9721e68 --- /dev/null +++ b/src/Pages/Concerns/HasLogger.php @@ -0,0 +1,23 @@ +subject_type, force: true); + $loggerInstance = $logger::make(); + + $manager = $activity->properties['relation_manager']['name'] ?? null; + if ($manager) { + $loggerInstance->relationManager($manager); + } + + return $loggerInstance; + } +} diff --git a/src/Pages/Concerns/LogFormatting.php b/src/Pages/Concerns/LogFormatting.php deleted file mode 100644 index c2ceccf..0000000 --- a/src/Pages/Concerns/LogFormatting.php +++ /dev/null @@ -1,25 +0,0 @@ -subject_type); - - return $logger::getLabel(); - } - - public function getField(Activity $activity, string $name): ?Field - { - $logger = Loggers::getLoggerByModel($activity->subject_type); - - return $logger::fields(new Fields)->getFieldByName($name); - } -} diff --git a/src/Pages/ListActivities.php b/src/Pages/ListActivities.php index 6560c39..6ac0a07 100644 --- a/src/Pages/ListActivities.php +++ b/src/Pages/ListActivities.php @@ -14,7 +14,7 @@ abstract class ListActivities extends Page implements HasForms { use CanPaginateRecords; - use Concerns\LogFormatting; + use Concerns\HasLogger; use Concerns\UrlHandling; use InteractsWithForms; use WithPagination; diff --git a/src/Fields/Concerns/CanDisplay.php b/src/ResourceLogger/Concerns/CanDisplay.php similarity index 90% rename from src/Fields/Concerns/CanDisplay.php rename to src/ResourceLogger/Concerns/CanDisplay.php index 782d757..e266b3b 100644 --- a/src/Fields/Concerns/CanDisplay.php +++ b/src/ResourceLogger/Concerns/CanDisplay.php @@ -1,6 +1,6 @@ $fields - */ - public function schema(array $fields): static + public function fields(array $fields): static { $this->fields = array_map(function ($field, $key) { if (is_int($key)) { diff --git a/src/Fields/Concerns/HasLabel.php b/src/ResourceLogger/Concerns/HasLabel.php similarity index 71% rename from src/Fields/Concerns/HasLabel.php rename to src/ResourceLogger/Concerns/HasLabel.php index 17f194a..ca47815 100644 --- a/src/Fields/Concerns/HasLabel.php +++ b/src/ResourceLogger/Concerns/HasLabel.php @@ -1,14 +1,14 @@ label = $key; + $this->label = $label; return $this; } diff --git a/src/Fields/Concerns/HasName.php b/src/ResourceLogger/Concerns/HasName.php similarity index 73% rename from src/Fields/Concerns/HasName.php rename to src/ResourceLogger/Concerns/HasName.php index b0454ba..fc3447f 100644 --- a/src/Fields/Concerns/HasName.php +++ b/src/ResourceLogger/Concerns/HasName.php @@ -1,6 +1,6 @@ + */ + protected array $relationManagers = []; + + public function relationManagers(array $relationManagers): static + { + $this->relationManagers = array_map( + static fn (Closure $closure, string $name) => $closure(new RelationManager($name)), + $relationManagers, + array_keys($relationManagers), + ); + + return $this; + } + + /** + * @return array + */ + public function getRelationManagers(): array + { + return $this->relationManagers; + } + + public function getRelationManager(string $name): ?RelationManager + { + foreach ($this->relationManagers as $manager) { + if ($manager->name === $name) { + return $manager; + } + } + + return null; + } +} diff --git a/src/Fields/Concerns/HasType.php b/src/ResourceLogger/Concerns/HasType.php similarity index 85% rename from src/Fields/Concerns/HasType.php rename to src/ResourceLogger/Concerns/HasType.php index 6c6b65a..9944e81 100644 --- a/src/Fields/Concerns/HasType.php +++ b/src/ResourceLogger/Concerns/HasType.php @@ -1,6 +1,6 @@ name($name); + } +} diff --git a/src/ResourceLogger/ResourceLogger.php b/src/ResourceLogger/ResourceLogger.php new file mode 100644 index 0000000..205d716 --- /dev/null +++ b/src/ResourceLogger/ResourceLogger.php @@ -0,0 +1,9 @@ + + */ + public static function resolveLogger(string | Model $record, bool $force = false): ?string + { + $name = is_string($record) ? $record : get_class($record); + + return Loggers::getLoggerByModel($name, $force); + } } diff --git a/stubs/Logger.stub b/stubs/Logger.stub index f98a116..cbb0c3c 100644 --- a/stubs/Logger.stub +++ b/stubs/Logger.stub @@ -3,33 +3,30 @@ namespace {{ namespace }}; use {{ modelNamespace }}; -use Noxo\FilamentActivityLog\Fields; +use {{ resourceNamespace }}\{{ modelClass }}Resource; +use Illuminate\Contracts\Support\Htmlable; use Noxo\FilamentActivityLog\Loggers\Logger; +use Noxo\FilamentActivityLog\ResourceLogger\Field; +use Noxo\FilamentActivityLog\ResourceLogger\RelationManager; +use Noxo\FilamentActivityLog\ResourceLogger\ResourceLogger; class {{ class }} extends Logger { - /** - * @var string - */ public static ?string $model = {{ modelClass }}::class; - /** - * @var array - */ - public static ?array $events = [ - 'created', - 'updated', - 'deleted', - 'restored', - ]; + public static function getLabel(): string | Htmlable | null + { + return {{ modelClass }}Resource::getModelLabel(); + } - /** - * @return Fields\Fields - */ - public static function fields(Fields\Fields $fields): Fields\Fields + public static function resource(ResourceLogger $logger): ResourceLogger { - return $fields->schema([ - // - ]); + return $logger + ->fields([ + // + ]) + ->relationManagers([ + // + ]); } }