Repository: rmsramos/activitylog
Branch: main
Commit: 428eb3183305
Files: 107
Total size: 131.3 KB
Directory structure:
gitextract_nvk_dftn/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yml
│ │ └── config.yml
│ └── workflows/
│ └── fix-php-code-style-issues.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── composer.json
├── config/
│ └── filament-activitylog.php
├── package.json
├── pint.json
├── postcss.config.js
├── resources/
│ ├── css/
│ │ └── plugin.css
│ ├── dist/
│ │ └── activitylog.css
│ ├── lang/
│ │ ├── ar/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── de/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── en/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── infolists.php
│ │ │ ├── notifications.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── es/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── infolists.php
│ │ │ ├── notifications.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── fa/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── infolists.php
│ │ │ ├── notifications.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── fr/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── he/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── id/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── it/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── lv/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── nl/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── pl/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── pt_BR/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── infolists.php
│ │ │ ├── notifications.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ ├── pt_PT/
│ │ │ ├── action.php
│ │ │ ├── forms.php
│ │ │ ├── tables.php
│ │ │ └── timeline.php
│ │ └── tr/
│ │ ├── action.php
│ │ ├── forms.php
│ │ ├── tables.php
│ │ └── timeline.php
│ └── views/
│ ├── .gitkeep
│ └── filament/
│ ├── infolists/
│ │ └── components/
│ │ ├── time-line-icon-entry.blade.php
│ │ ├── time-line-propertie-entry.blade.php
│ │ ├── time-line-repeatable-entry.blade.php
│ │ └── time-line-title-entry.blade.php
│ └── tables/
│ └── columns/
│ └── activity-logs-properties.blade.php
├── src/
│ ├── Actions/
│ │ ├── ActivityLogTimelineSimpleAction.php
│ │ ├── ActivityLogTimelineTableAction.php
│ │ └── Concerns/
│ │ └── ActionContent.php
│ ├── ActivitylogPlugin.php
│ ├── ActivitylogServiceProvider.php
│ ├── Helpers/
│ │ └── ActivityLogHelper.php
│ ├── Infolists/
│ │ ├── Components/
│ │ │ ├── TimeLineIconEntry.php
│ │ │ ├── TimeLinePropertiesEntry.php
│ │ │ ├── TimeLineRepeatableEntry.php
│ │ │ └── TimeLineTitleEntry.php
│ │ └── Concerns/
│ │ └── HasModifyState.php
│ ├── RelationManagers/
│ │ └── ActivitylogRelationManager.php
│ ├── Resources/
│ │ └── ActivitylogResource/
│ │ ├── ActivitylogResource.php
│ │ ├── Pages/
│ │ │ ├── ListActivitylog.php
│ │ │ └── ViewActivitylog.php
│ │ └── Schemas/
│ │ └── ActivitylogForm.php
│ └── Traits/
│ └── HasCustomActivityResource.php
└── tailwind.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
================================================
FILE: .gitattributes
================================================
# Path-based git attributes
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# Ignore all test and documentation with "export-ignore".
/.github export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/phpunit.xml.dist export-ignore
/art export-ignore
/docs export-ignore
/tests export-ignore
/workbench export-ignore
/.editorconfig export-ignore
/.php_cs.dist.php export-ignore
/psalm.xml export-ignore
/psalm.xml.dist export-ignore
/testbench.yaml export-ignore
/UPGRADING.md export-ignore
/phpstan.neon.dist export-ignore
/phpstan-baseline.neon export-ignore
================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug report
description: Report a problem you're experiencing
labels: bug,unconfirmed
body:
- type: markdown
attributes:
value: |
Before opening a bug report, please search the existing issues (both open and closed).
---
Thank you for taking the time to file a bug report. To address this bug as fast as possible, we need some information.
- type: input
id: package-version
attributes:
label: Package Version
description: Please provide the full version of the package you have installed.
placeholder: v1.0.0
validations:
required: true
- type: input
id: laravel-version
attributes:
label: Laravel Version
description: Please provide the full Laravel version of your project.
placeholder: v10.0.0
validations:
required: true
- type: input
id: php-version
attributes:
label: PHP Version
description: Please provide the full PHP version of your server.
placeholder: PHP 8.3.0
validations:
required: true
- type: textarea
id: description
attributes:
label: Problem description
description: What happened when you experienced the problem?
validations:
required: true
- type: textarea
id: expectation
attributes:
label: Expected behavior
description: What did you expect to happen instead?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: Which steps do we need to take to reproduce the problem? Any code examples need to be **as short as possible**, remove any code that is unrelated to the bug. **This issue will be automatically closed and not reviewed if detailed replication steps are missing.**
validations:
required: true
- type: input
id: reproduction
attributes:
label: Reproduction repository (issue will be closed if this is not valid)
description: The URL of a public GitHub repository which reproduces the problem. **Please do not link to your actual project**, what we need instead is a _minimal_ reproduction in a fresh project without any unnecessary code. This means it doesn\'t matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. This allows us to fix the problem much quicker. **This issue will be automatically closed and not reviewed if this is missing. Please make sure to format the URL starting with `https://github.com` - only repositories hosted on GitHub are accepted.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: If applicable, provide relevant log output. No need for backticks here.
render: shell
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Ask a question
url: https://github.com/Rmsramos/activitylog/discussions/new?category=q-a
about: Ask the community for help
- name: Request a feature
url: https://github.com/Rmsramos/activitylog/discussions/new?category=ideas
about: Share ideas for new features
- name: Report a security issue
url: https://github.com/Rmsramos/activitylog/security/policy
about: Learn how to notify us for sensitive bugs
================================================
FILE: .github/workflows/fix-php-code-style-issues.yml
================================================
name: Fix PHP code style issues
on:
push:
paths:
- '**.php'
permissions:
contents: write
jobs:
php-code-styling:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: Fix PHP code style issues
uses: aglipanci/laravel-pint-action@2.3.0
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Fix styling
================================================
FILE: .gitignore
================================================
.idea
.phpunit.cache
build
composer.lock
coverage
docs
phpunit.xml
phpstan.neon
testbench.yaml
vendor
node_modules
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) Rmsramos <rmsramos@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# ActivityLog
### Spatie/Laravel-activitylog for Filament
[](https://packagist.org/packages/rmsramos/activitylog)
[](LICENSE.md)
[](https://github.com/rmsramos/activitylog/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[](https://packagist.org/packages/rmsramos/activitylog/stats)
<div class="filament-hidden">

</div>
This package provides a Filament resource that shows you all of the activity logs and detailed view of each log created using the `spatie/laravel-activitylog` package. It also provides a relationship manager for related models.
## Requirements
- Laravel v12
- Filament v3
- Spatie/Laravel-activitylog v4
## Languages Supported
ActivityLog Plugin is translated for :
- 🇧🇷 Brazilian Portuguese
- 🇺🇸 English
- 🇩🇪 German
- 🇪🇸 Spanish
- 🇫🇷 French
- 🇮🇷 Persian
- 🇦🇪 Arabic
- 🇵🇹 Portuguese
- 🇮🇱 Hebrew
- 🇳🇱 Dutch
- 🇱🇻 Latvian
## Installation
You can install the package via composer:
```bash
composer require rmsramos/activitylog
```
After that run the install command:
```bash
php artisan activitylog:install
```
This will publish the config & migrations from `spatie/laravel-activitylog`
And run migrates
```bash
php artisan migrate
```
You can manually publish the configuration file with:
```bash
php artisan vendor:publish --tag="activitylog-config"
```
This is the contents of the published config file:
```php
return [
'resources' => [
'label' => 'Activity Log',
'plural_label' => 'Activity Logs',
'hide_restore_action' => false,
'restore_action_label' => 'Restore',
'hide_resource_action' => false,
'hide_restore_model_action' => true,
'resource_action_label' => 'View',
'navigation_item' => true,
'navigation_group' => null,
'navigation_icon' => 'heroicon-o-shield-check',
'navigation_sort' => null,
'default_sort_column' => 'id',
'default_sort_direction' => 'desc',
'navigation_count_badge' => false,
'resource' => \Rmsramos\Activitylog\Resources\ActivitylogResource::class,
],
'date_format' => 'd/m/Y',
'datetime_format' => 'd/m/Y H:i:s',
];
```
Optionally, you can publish the views using
```bash
php artisan vendor:publish --tag="activitylog-views"
```
## Usage
### Basic Spatie ActivityLog usage
In you `Model` add `Spatie\Activitylog\Traits\LogsActivity` trait, and configure `getActivitylogOption` function
For more configuration, Please review [Spatie Docs](https://spatie.be/docs/laravel-activitylog/v4)
```php
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class NewsItem extends Model
{
use LogsActivity;
protected $fillable = ['name', 'text'];
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'text']);
}
}
```
## Plugin usage

In your Panel ServiceProvider `(App\Providers\Filament)` active the plugin
Add the `Rmsramos\Activitylog\ActivitylogPlugin` to your panel config
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make(),
]);
}
```
## Customising the ActivitylogResource
You can swap out the `ActivitylogResource` used by updating the `->resource()` value. Use this to create your own `CustomResource` class and extend the original at `\Rmsramos\Activitylog\Resources\ActivitylogResource::class`. This will allow you to customise everything such as the views, table, form and permissions.
> [!NOTE]
> 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 `CustomResource`.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->resource(\Path\For\Your\CustomResource::class),
]);
}
```
## Customising label Resource
You can swap out the `Resource label` used by updating the `->label()` and `->pluralLabel()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->label('Log')
->pluralLabel('Logs'),
]);
}
```
## Displaying the resource in the navigation
You can enable or disable the `Resource navigation item` by updating the `->navigationItem()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->navigationItem(false), // by default is true
]);
}
```
## Grouping resource navigation items
You can add a `Resource navigation group` updating the `->navigationGroup()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->navigationGroup('Activity Log'),
]);
}
```
## Customising a resource navigation icon
You can swap out the `Resource navigation icon` used by updating the `->navigationIcon()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->navigationIcon('heroicon-o-shield-check'),
]);
}
```
## Active a count badge
You can active `Count Badge` updating the `->navigationCountBadge()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->navigationCountBadge(true),
]);
}
```
## Set navigation sort
You can set the `Resource navigation sort` used by updating the `->navigationSort()` value.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->navigationSort(3),
]);
}
```
## Authorization
If you would like to prevent certain users from accessing the logs resource, you should add a authorize callback in the `ActivitylogPlugin` chain.
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->authorize(
fn () => auth()->user()->id === 1
),
]);
}
```
## Translate Resource Names
To translate resource names in the activity log, add a `translateSubject` callback within the `ActivitylogPlugin` chain
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->translateSubject(fn($label) => __("yourCustomLangFile.".$label)),
]);
}
```
## Translate Activity log key Names
To translate the names of the keys in the activity log, add a `translateLogKey` callback within the `ActivitylogPlugin` chain
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->translateLogKey(fn($label) => __("yourCustomLangFile.".$label)),
]);
}
```
## Customize Date Parsing
To customize how dates are parsed, depending on user preferences or settings:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
use Morilog\Jalali\Jalalian;
use Carbon\Carbon;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->dateParser(
fn($date) => auth()->user()->isJalaliCalendar() ?
Jalalian::fromDateTime($date) :
Carbon::parse($date)
)
]);
}
```
## Customize Date and DateTime Formats
To customize the format of dates and datetime columns based on user settings:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->dateFormat('Y-m-d')
->datetimeFormat(fn() => auth()->user()->getFilamentDateTimeFormat())
]);
}
```
## Customize DateTime Columns
To conditionally customize datetime columns in the UI, depending on the user's calendar preference:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->customizeDatetimeColumn(function ($column) {
return $column->when(
auth()->user()->isJalaliCalendar(),
function ($column) {
return $column->jalaliDateTime();
}
);
})
]);
}
```
## Customize Date Picker Fields
To customize date picker fields in forms, depending on user preferences:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->customizeDatePicker(function ($field) {
return $field->when(
auth()->user()->isJalaliCalendar(),
function ($field) {
return $field->jalali();
}
);
})
]);
}
```
## Manipulate View Action Using Custom Activity Resource Trait
Implement `getFilamentActualResourceModel` in the trait `HasCustomActivityResource` to determine the actual model related to the activity record for generating valid URLs.
```php
use Rmsramos\Activitylog\Traits\HasCustomActivityResource;
trait HasCustomActivityResource
{
public function getFilamentActualResourceModel($record)
{
$record = $record->subject->translatable;
$model = null;
switch ($record::class) {
case FirstTranslatableModel::class:
$model = $record->firstModel;
break;
case SecondTranslatableModel::class:
$model = $record->secondModel;
break;
default:
throw new Exception("Error Translatable subject model not found. record = ".$record::class, 1);
break;
}
return $model;
}
}
```
### Hide Restore / View Action
To hide the restore / view action globally for a resource within the `ActivitylogPlugin`, you can use the `isRestoreActionHidden` and `isResourceActionHidden` method. these are particularly useful in scenarios where you do not want users to have the ability to restore or view entries from the activity log. you can also customize the label of view action:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->isRestoreActionHidden(true)
->isResourceActionHidden(true)
->resourceActionLabel("Sample Label")
]);
}
```
### Show Restore (Soft Deletes)
In the `laravel-activitylog` configuration file `config/activitylog.php`:
```php
return [
'subject_returns_soft_deleted_models' => true,
]
```
To globally display the restore (soft delete) action of a resource within the `ActivitylogPlugin`, you can use the `isRestoreModelActionHidden` method. This is particularly useful in scenarios where you do not want users to have the ability to restore activity log entries:
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->isRestoreModelActionHidden(false)
]);
}
```
### Role Policy
To ensure ActivitylogResource access via RolePolicy you would need to add the following to your AppServiceProvider:
```php
use App\Policies\ActivityPolicy;
use Illuminate\Support\Facades\Gate;
use Spatie\Activitylog\Models\Activity;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Gate::policy(Activity::class, ActivityPolicy::class);
}
}
```
## Full configuration
```php
use Rmsramos\Activitylog\ActivitylogPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
ActivitylogPlugin::make()
->resource(\Path\For\Your\CustomResource::class)
->label('Log')
->pluralLabel('Logs')
->navigationItem(true)
->navigationGroup('Activity Log')
->navigationIcon('heroicon-o-shield-check')
->navigationCountBadge(true)
->navigationSort(2)
->authorize(
fn () => auth()->user()->id === 1
)
->translateSubject(fn($label) => __("yourCustomLangFile.".$label)),
->dateParser(
fn($date) => auth()->user()->isJalaliCalendar() ?
Jalalian::fromDateTime($date) :
Carbon::parse($date)
)
->dateFormat('Y-m-d')
->datetimeFormat(fn() => auth()->user()->getFilamentDateTimeFormat())
->customizeDatetimeColumn(function ($column) {
return $column->when(
auth()->user()->isJalaliCalendar(),
function ($column) {
return $column->jalaliDateTime();
}
);
})
->customizeDatePicker(function ($field) {
return $field->when(
auth()->user()->isJalaliCalendar(),
function ($field) {
return $field->jalali();
}
);
})
->isRestoreActionHidden(true)
->isResourceActionHidden(true)
->isRestoreModelActionHidden(false)
->resourceActionLabel("Sample Label"),
]);
}
```
## Relationship manager
If you have a model that uses the `Spatie\Activitylog\Traits\LogsActivity` trait, you can add the `Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager` relationship manager to your Filament resource to display all of the activity logs that are performed on your model.

```php
use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager;
public static function getRelations(): array
{
return [
ActivitylogRelationManager::class,
];
}
```
## Timeline Action

To make viewing activity logs easier, you can use a custom action. In your UserResource in the table function, add the `ActivityLogTimelineTableAction`.
```php
use Rmsramos\Activitylog\Actions\ActivityLogTimelineTableAction;
public static function table(Table $table): Table
{
return $table
->actions([
ActivityLogTimelineTableAction::make('Activities'),
]);
}
```
you can pass a matrix with the relationships, remember to configure your `Models`.
```php
public static function table(Table $table): Table
{
return $table
->actions([
ActivityLogTimelineTableAction::make('Activities')
->withRelations(['profile', 'address']), //opcional
]);
}
```
You can configure the icons and colors, by default the `'heroicon-m-check'` icon and the `'primary'` color are used.
```php
use Rmsramos\Activitylog\Actions\ActivityLogTimelineTableAction;
public static function table(Table $table): Table
{
return $table
->actions([
ActivityLogTimelineTableAction::make('Activities')
->timelineIcons([
'created' => 'heroicon-m-check-badge',
'updated' => 'heroicon-m-pencil-square',
])
->timelineIconColors([
'created' => 'info',
'updated' => 'warning',
])
]);
}
```
You can limit the number of results in the query by passing a limit, by default the last 10 records are returned.
```php
use Rmsramos\Activitylog\Actions\ActivityLogTimelineTableAction;
public static function table(Table $table): Table
{
return $table
->actions([
ActivityLogTimelineTableAction::make('Activities')
->limit(30),
]);
}
```
## Full Timeline configuration
```php
use Rmsramos\Activitylog\Actions\ActivityLogTimelineTableAction;
public static function table(Table $table): Table
{
return $table
->actions([
ActivityLogTimelineTableAction::make('Activities')
->withRelations(['profile', 'address'])
->timelineIcons([
'created' => 'heroicon-m-check-badge',
'updated' => 'heroicon-m-pencil-square',
])
->timelineIconColors([
'created' => 'info',
'updated' => 'warning',
])
->limit(10),
]);
}
```
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security Vulnerabilities
Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
## Acknowledgements
Special acknowledgment goes to these remarkable tools and people (developers), the Activity Log plugin only exists due to the inspiration and at some point the use of these people's codes.
- [Jay-Are Ocero](https://github.com/199ocero/activity-timeline)
- [Alex Justesen](https://github.com/alexjustesen)
- [z3d0x](https://github.com/z3d0x/filament-logger)
- [Filament](https://github.com/filamentphp/filament)
- [Spatie Activitylog Contributors](https://github.com/spatie/laravel-activitylog#credits)
## Credits
- [Rômulo Ramos](https://github.com/rmsramos)
- [All Contributors](../../contributors)
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
================================================
FILE: composer.json
================================================
{
"name": "rmsramos/activitylog",
"description": "This is my package activitylog",
"keywords": [
"Rmsramos",
"laravel",
"activitylog"
],
"homepage": "https://github.com/rmsramos/activitylog",
"license": "MIT",
"authors": [
{
"name": "Rômulo Ramos",
"email": "rmsramos@gmail.com",
"role": "Developer"
}
],
"require": {
"php": "^8.2",
"illuminate/contracts": "^11.0||^12.0",
"spatie/laravel-activitylog": "^4.8",
"spatie/laravel-package-tools": "^1.16"
},
"require-dev": {
"larastan/larastan": "^2.9",
"laravel/pint": "^1.16",
"nunomaduro/collision": "^8.1.1||^7.10.0",
"orchestra/testbench": "^9.0.0||^8.22.0",
"pestphp/pest": "^2.34",
"pestphp/pest-plugin-arch": "^2.7",
"pestphp/pest-plugin-laravel": "^2.3",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3"
},
"autoload": {
"psr-4": {
"Rmsramos\\Activitylog\\": "src/",
"Rmsramos\\Activitylog\\Database\\Factories\\": "database/factories/"
}
},
"autoload-dev": {
"psr-4": {
"Rmsramos\\Activitylog\\Tests\\": "tests/",
"Workbench\\App\\": "workbench/app/"
}
},
"scripts": {
"post-autoload-dump": "@composer run prepare",
"clear": "@php vendor/bin/testbench package:purge-activitylog --ansi",
"prepare": "@php vendor/bin/testbench package:discover --ansi",
"build": [
"@composer run prepare",
"@php vendor/bin/testbench workbench:build --ansi"
],
"start": [
"Composer\\Config::disableProcessTimeout",
"@composer run build",
"@php vendor/bin/testbench serve"
],
"analyse": "vendor/bin/phpstan analyse",
"test": "vendor/bin/pest",
"test-coverage": "vendor/bin/pest --coverage",
"format": "vendor/bin/pint"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true,
"phpstan/extension-installer": true
}
},
"extra": {
"laravel": {
"providers": [
"Rmsramos\\Activitylog\\ActivitylogServiceProvider"
],
"aliases": {
"Activitylog": "Rmsramos\\Activitylog\\Facades\\Activitylog"
}
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
================================================
FILE: config/filament-activitylog.php
================================================
<?php
return [
'resources' => [
'label' => 'Activity Log',
'plural_label' => 'Activity Logs',
'hide_restore_action' => false,
'restore_action_label' => 'Restore',
'hide_resource_action' => false,
'hide_restore_model_action' => true,
'resource_action_label' => 'View',
'navigation_item' => true,
'navigation_group' => null,
'navigation_icon' => 'heroicon-o-shield-check',
'navigation_sort' => null,
'default_sort_column' => 'id',
'default_sort_direction' => 'desc',
'navigation_count_badge' => false,
'resource' => \Rmsramos\Activitylog\Resources\ActivitylogResource\ActivitylogResource::class,
],
'date_format' => 'd/m/Y',
'datetime_format' => 'd/m/Y H:i:s',
];
================================================
FILE: package.json
================================================
{
"private": true,
"type": "module",
"scripts": {
"dev:styles": "npx tailwindcss -i resources/css/plugin.css -o resources/dist/activitylog.css --postcss --watch",
"build:styles": "npx tailwindcss -i resources/css/plugin.css -o resources/dist/activitylog.css --postcss --minify && npm run purge",
"purge": "filament-purge -i resources/dist/activitylog.css -o resources/dist/activitylog.css -v 3.x",
"dev": "npm-run-all --parallel dev:*",
"build": "npm-run-all build:*"
},
"devDependencies": {
"@awcodes/filament-plugin-purge": "^1.1.0",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/typography": "^0.5.9",
"alpinejs": "^3.10.5",
"autoprefixer": "^10.4.7",
"esbuild": "^0.17.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.14",
"postcss-import": "^15.1.0",
"tailwindcss": "^3.1.6"
}
}
================================================
FILE: pint.json
================================================
{
"preset": "laravel",
"rules": {
"method_chaining_indentation": true,
"group_import": false,
"single_import_per_statement": false,
"no_unused_imports": true,
"array_indentation": true,
"array_syntax": {
"syntax": "short"
},
"binary_operator_spaces": {
"default": "single_space",
"operators": {
"=": "align_single_space_minimal",
"=>": "align_single_space_minimal"
}
},
"blank_line_after_namespace": true,
"blank_line_after_opening_tag": false,
"class_attributes_separation": {
"elements": {
"property": "one"
}
},
"concat_space": {
"spacing": "one"
},
"declare_equal_normalize": {
"space": "single"
},
"elseif": false,
"encoding": true,
"indentation_type": true,
"no_useless_else": false,
"no_useless_return": true,
"ordered_imports": true,
"ternary_operator_spaces": true,
"no_extra_blank_lines": true,
"no_multiline_whitespace_around_double_arrow": true,
"multiline_whitespace_before_semicolons": true,
"no_singleline_whitespace_before_semicolons": true,
"no_spaces_around_offset": true,
"ternary_to_null_coalescing": true,
"whitespace_after_comma_in_array": true,
"trim_array_spaces": true,
"trailing_comma_in_multiline": true,
"unary_operator_spaces": true,
"blank_line_before_statement": {
"statements": [
"break",
"continue",
"declare",
"return",
"throw",
"try",
"continue",
"do",
"exit",
"for",
"foreach",
"if",
"include",
"include_once",
"require",
"require_once"
]
}
}
}
================================================
FILE: postcss.config.js
================================================
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
================================================
FILE: resources/css/plugin.css
================================================
@tailwind components;
@tailwind utilities;
================================================
FILE: resources/dist/activitylog.css
================================================
.-start-3{inset-inline-start:-.75rem}.mr-1{margin-right:.25rem}.divide-solid>:not([hidden])~:not([hidden]){border-style:solid}.bg-gray-500\/10{background-color:#6b72801a}.ring-1,.ring-4{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}:is(.dark .dark\:divide-gray-700)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(55 65 81/var(--tw-divide-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:bg-gray-700){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:bg-white\/5){background-color:#ffffff0d}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-500){--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}:is(.dark .dark\:ring-gray-900){--tw-ring-opacity:1;--tw-ring-color:rgb(17 24 39/var(--tw-ring-opacity))}:is(.dark .dark\:ring-white\/10){--tw-ring-color:#ffffff1a}
================================================
FILE: resources/lang/ar/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'سجل نشاط المستخدم',
'description' => 'تتبع جميع أنشطة المستخدم',
'tooltip' => 'أنشطة المستخدم',
],
];
================================================
FILE: resources/lang/ar/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'النوع',
],
'event' => [
'label' => 'الحدث',
],
'subject_type' => [
'label' => 'الموضوع',
],
'causer' => [
'label' => 'المستخدم',
],
'description' => [
'label' => 'الوصف',
],
'properties' => [
'label' => 'الخصائص',
],
'created_at' => [
'label' => 'تاريخ التسجيل',
],
'old' => [
'label' => 'القديم',
],
'attributes' => [
'label' => 'الجديد',
],
],
];
================================================
FILE: resources/lang/ar/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'النوع',
],
'event' => [
'label' => 'الحدث',
],
'subject_type' => [
'label' => 'الموضوع',
],
'causer' => [
'label' => 'المستخدم',
],
'properties' => [
'label' => 'الخصائص',
],
'created_at' => [
'label' => 'تاريخ التسجيل',
],
],
'filters' => [
'created_at' => [
'label' => 'تاريخ التسجيل',
'created_from' => 'تاريخ الإنشاء من',
'created_until' => 'تاريخ الإنشاء حتى',
],
'event' => [
'label' => 'الحدث',
],
],
];
================================================
FILE: resources/lang/ar/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'تم تعديل <strong>%s</strong> بواسطة <strong>%s</strong>. <br><small> تم التحديث في: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => 'تم تعديل الخصائص التالية بواسطة %s: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s من <strong>%s</strong> إلى <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/de/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'User Aktivitäten Log',
'description' => 'Tracke alle Aktivitäten, die von Benutzern in der Anwendung durchgeführt werden.',
'tooltip' => 'User Aktivitäten',
],
];
================================================
FILE: resources/lang/de/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Typ',
],
'event' => [
'label' => 'Ereigniss',
],
'subject_type' => [
'label' => 'Betreff',
],
'causer' => [
'label' => 'Benutzer',
],
'description' => [
'label' => 'Beschreibung',
],
'properties' => [
'label' => 'Attribute',
],
'created_at' => [
'label' => 'Logzeitpunkt',
],
'old' => [
'label' => 'Alt',
],
'attributes' => [
'label' => 'Neu',
],
],
];
================================================
FILE: resources/lang/de/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Typ',
],
'event' => [
'label' => 'Ereignis',
],
'subject_type' => [
'label' => 'Betreff',
],
'causer' => [
'label' => 'Benutzer',
],
'properties' => [
'label' => 'Attribute',
],
'created_at' => [
'label' => 'Logzeitpunkt',
],
],
'filters' => [
'created_at' => [
'label' => 'Logzeitpunkt',
'created_from' => 'Geloggt von ',
'created_until' => 'Geloggt bis',
],
'event' => [
'label' => 'Ereignis',
],
],
];
================================================
FILE: resources/lang/de/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => '<strong>%s</strong> wurde <strong>%s</strong> von <strong>%s</strong>. <br><small> Änderung am: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s das folgende: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s von <strong>%s</strong> auf <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/en/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'User Activity Log',
'description' => 'Track all user activities',
'tooltip' => 'User Activities',
],
'event' => [
'created' => 'created',
'deleted' => 'deleted',
'updated' => 'updated',
'restored' => 'restored',
],
'view' => 'View',
'edit' => 'Edit',
'restore' => 'Restore',
'restore_soft_delete' => [
'label' => 'Restore Model',
'modal_heading' => 'Restore Deleted Model',
'modal_description' => 'This will restore the model that was deleted (soft delete).',
],
];
================================================
FILE: resources/lang/en/forms.php
================================================
<?php
return [
'changes' => 'Changes',
'fields' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Event',
],
'subject_type' => [
'label' => 'Subject',
],
'causer' => [
'label' => 'User',
],
'description' => [
'label' => 'Description',
],
'properties' => [
'label' => 'Properties',
],
'created_at' => [
'label' => 'Logged at',
],
'old' => [
'label' => 'Old',
],
'attributes' => [
'label' => 'New',
],
],
];
================================================
FILE: resources/lang/en/infolists.php
================================================
<?php
return [
'components' => [
'created_by_at' => 'The <strong>:subject</strong> was <strong>:event</strong> by <strong>:causer</strong>. <br><small> Updated at: <strong>:update_at</strong></small>',
'updater_updated' => ':causer :event the following: <br>:changes',
'from_oldvalue_to_newvalue' => '- :key from <strong>:old_value</strong> to <strong>:new_value</strong>',
'to_newvalue' => '- :key <strong>:new_value</strong>',
'unknown' => 'Unknown',
],
];
================================================
FILE: resources/lang/en/notifications.php
================================================
<?php
return [
'no_properties_to_restore' => 'No properties to restore.',
'activity_restored' => 'Activity restored.',
'activity_restored_successfully' => 'Activity restored successfully.',
'failed_to_restore_activity' => 'Failed to restore activity : :error.',
'subject_not_found' => 'Subject not found.',
'unable_to_restore_this_model' => 'Unable to restore this model',
'model_successfully_restored' => 'Model successfully restored',
'error_restoring_model' => 'Erro ao restaurar modelo',
];
================================================
FILE: resources/lang/en/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Event',
],
'subject_type' => [
'label' => 'Subject',
'soft_deleted' => ' (Soft Deleted)',
'deleted' => ' (Deleted)',
],
'causer' => [
'label' => 'User',
],
'properties' => [
'label' => 'Properties',
],
'created_at' => [
'label' => 'Logged at',
],
],
'filters' => [
'created_at' => [
'label' => 'Logged at',
'created_from' => 'Created from ',
'created_from_indicator' => 'Created from : :created_from',
'created_until' => 'Created until ',
'created_until_indicator' => 'Created until : :created_until',
],
'event' => [
'label' => 'Event',
],
'log_name' => [
'label' => 'Log name',
],
],
];
================================================
FILE: resources/lang/en/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/es/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Registro de actividad de usuario',
'description' => 'Realizar un seguimiento de todas las actividades de los usuarios',
'tooltip' => 'Actividades de usuario',
],
'event' => [
'created' => 'creado',
'deleted' => 'eliminado',
'updated' => 'actualizado',
'restored' => 'restaurado',
],
'view' => 'Ver',
'edit' => 'Editar',
'restore' => 'Restaurar',
'restore_soft_delete' => [
'label' => 'Restaurar modelo',
'modal_heading' => 'Restaurar modelo eliminado',
'modal_description' => 'Esto restaurará el modelo que fue eliminado (borrado lógico).',
],
];
================================================
FILE: resources/lang/es/forms.php
================================================
<?php
return [
'changes' => 'Cambios',
'fields' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Sujeto',
],
'causer' => [
'label' => 'Usuario',
],
'description' => [
'label' => 'Descripción',
],
'properties' => [
'label' => 'Propiedades',
],
'created_at' => [
'label' => 'Registrado en',
],
'old' => [
'label' => 'Anterior',
],
'attributes' => [
'label' => 'Nuevo',
],
],
];
================================================
FILE: resources/lang/es/infolists.php
================================================
<?php
return [
'components' => [
'created_by_at' => 'El <strong>:subject</strong> fue <strong>:event</strong> por <strong>:causer</strong>. <br><small> Actualizado en: <strong>:update_at</strong></small>',
'updater_updated' => ':causer :event lo siguiente: <br>:changes',
'from_oldvalue_to_newvalue' => '- :key de <strong>:old_value</strong> a <strong>:new_value</strong>',
'to_newvalue' => '- :key <strong>:new_value</strong>',
'unknown' => 'Desconocido',
],
];
================================================
FILE: resources/lang/es/notifications.php
================================================
<?php
return [
'no_properties_to_restore' => 'No hay propiedades para restaurar.',
'activity_restored' => 'Actividad restaurada.',
'activity_restored_successfully' => 'Actividad restaurada con éxito.',
'failed_to_restore_activity' => 'Error al restaurar la actividad: :error.',
'subject_not_found' => 'Sujeto no encontrado.',
'unable_to_restore_this_model' => 'No se puede restaurar este modelo.',
'model_successfully_restored' => 'Modelo restaurado con éxito.',
'error_restoring_model' => 'Error al restaurar modelo',
];
================================================
FILE: resources/lang/es/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Sujeto',
'soft_deleted' => ' (borrado lógico)',
'deleted' => ' (eliminado)',
],
'causer' => [
'label' => 'Usuario',
],
'properties' => [
'label' => 'Propiedades',
],
'created_at' => [
'label' => 'Registrado en',
],
],
'filters' => [
'created_at' => [
'label' => 'Registrado en',
'created_from' => 'Creado desde ',
'created_from_indicator' => 'Creado desde: :created_from',
'created_until' => 'Creado hasta ',
'created_until_indicator' => 'Creado hasta: :created_until',
],
'event' => [
'label' => 'Evento',
],
],
];
================================================
FILE: resources/lang/es/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'El <strong>%s</strong> fue <strong>%s</strong> por <strong>%s</strong>. <br><small> Actualizado en: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s lo siguiente: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s de <strong>%s</strong> a <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/fa/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'سیاههفعالیتکاربر',
'description' => 'ردیابی تمام فعالیت های کاربر',
'tooltip' => 'فعالیت های کاربر',
],
'event' => [
'created' => 'ایجاد شد',
'deleted' => 'حذف شد',
'updated' => 'بروزرسانی شد',
'restored' => 'بازیابی شد',
],
'view' => 'نمایش',
'edit' => 'ویرایش',
'restore' => 'بازیابی',
];
================================================
FILE: resources/lang/fa/forms.php
================================================
<?php
return [
'changes' => 'تغییرات',
'fields' => [
'log_name' => [
'label' => 'نوع',
],
'event' => [
'label' => 'رویداد',
],
'subject_type' => [
'label' => 'موضوع مورد سیاهه',
],
'causer' => [
'label' => 'کاربر',
],
'description' => [
'label' => 'توضیحات',
],
'properties' => [
'label' => 'تغییرات',
],
'created_at' => [
'label' => 'ورود به سیستم در',
],
'old' => [
'label' => 'قدیمی',
],
'attributes' => [
'label' => 'جدید',
],
],
];
================================================
FILE: resources/lang/fa/infolists.php
================================================
<?php
return [
'components' => [
'created_by_at' => '<strong>:subject</strong> توسط <strong>:causer</strong> در تاریخ <strong>:update_at</strong> <strong>:event</strong>.',
'updater_updated' => 'ویژگی های زیر توسط <strong>:causer</strong> :event :<br> :changes ',
'from_oldvalue_to_newvalue' => 'مقدار ویژگی :key از <strong>:old_value</strong> به <strong>:new_value</strong> تغییر کرد.',
'to_newvalue' => 'ویژگی :key به <strong>:new_value</strong> مقدار دهی شد.',
'unknown' => 'ناشناس',
],
];
================================================
FILE: resources/lang/fa/notifications.php
================================================
<?php
return [
'no_properties_to_restore' => 'مقادیری برای بازگردانی وجود ندارد.',
'activity_restored' => 'فعالیت بازگردانی شد.',
'activity_restored_successfully' => 'فعالیت با موفقیت بازگردانی شد.',
'failed_to_restore_activity' => 'بازگردانی فعالیت ناموفق بود. خطا : :error',
];
================================================
FILE: resources/lang/fa/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'نوع',
],
'event' => [
'label' => 'رویداد',
],
'subject_type' => [
'label' => 'مفعول',
],
'causer' => [
'label' => 'کاربر',
],
'properties' => [
'label' => 'تغییرات',
],
'created_at' => [
'label' => 'ورود به سیستم در',
],
],
'filters' => [
'created_at' => [
'label' => 'ورود به سیستم در',
'created_from' => 'ایجاد شده از ',
'created_from_indicator' => 'ایجاد شده از تاریخ : :created_from',
'created_until' => 'ایجاد شده تا ',
'created_until_indicator' => 'ایجاد شده تا تاریخ : :created_until',
],
'event' => [
'label' => 'رویداد',
],
],
];
================================================
FILE: resources/lang/fa/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/fr/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Journal d\'activité des utilisateurs',
'description' => 'Suivre toutes les activités des utilisateurs',
'tooltip' => 'Activités des utilisateurs',
],
];
================================================
FILE: resources/lang/fr/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Événement',
],
'subject_type' => [
'label' => 'Sujet',
],
'causer' => [
'label' => 'Utilisateur',
],
'description' => [
'label' => 'Description',
],
'properties' => [
'label' => 'Propriétés',
],
'created_at' => [
'label' => 'Enregistré à',
],
'old' => [
'label' => 'Ancien',
],
'attributes' => [
'label' => 'Nouveau',
],
],
];
================================================
FILE: resources/lang/fr/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Événement',
],
'subject_type' => [
'label' => 'Sujet',
],
'causer' => [
'label' => 'Utilisateur',
],
'properties' => [
'label' => 'Propriétés',
],
'created_at' => [
'label' => 'Enregistré à',
],
],
'filters' => [
'created_at' => [
'label' => 'Enregistré à',
'created_from' => 'Créé à partir de ',
'created_until' => 'Créé jusqu\'à ',
],
'event' => [
'label' => 'Événement',
],
],
];
================================================
FILE: resources/lang/fr/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/he/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'יומן פעילות משתמש',
'description' => 'הצגת כל פעילויות המשתמש',
'tooltip' => 'פעילויות משתמש',
],
];
================================================
FILE: resources/lang/he/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'סוג',
],
'event' => [
'label' => 'אירוע',
],
'subject_type' => [
'label' => 'נושא',
],
'causer' => [
'label' => 'משתמש',
],
'description' => [
'label' => 'תיאור',
],
'properties' => [
'label' => 'מאפיינים',
],
'created_at' => [
'label' => 'נוצר',
],
'old' => [
'label' => 'ישן',
],
'attributes' => [
'label' => 'חדש',
],
],
];
================================================
FILE: resources/lang/he/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'סוג',
],
'event' => [
'label' => 'אירוע',
],
'subject_type' => [
'label' => 'נושא',
],
'causer' => [
'label' => 'משתמש',
],
'properties' => [
'label' => 'מאפיינים',
],
'created_at' => [
'label' => 'נוצר',
],
],
'filters' => [
'created_at' => [
'label' => 'נוצר',
'created_from' => 'נוצר מ',
'created_until' => 'נוצר עד',
],
'event' => [
'label' => 'אירוע',
],
],
];
================================================
FILE: resources/lang/he/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/id/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Log Aktivitas Pengguna',
'description' => 'Lacak semua aktivitas pengguna',
'tooltip' => 'Aktivitas Pengguna',
],
];
================================================
FILE: resources/lang/id/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Jenis',
],
'event' => [
'label' => 'Peristiwa',
],
'subject_type' => [
'label' => 'Subjek',
],
'causer' => [
'label' => 'Pengguna',
],
'description' => [
'label' => 'Keterangan',
],
'properties' => [
'label' => 'Properti',
],
'created_at' => [
'label' => 'Masuk di',
],
'old' => [
'label' => 'Tua',
],
'attributes' => [
'label' => 'Baru',
],
],
];
================================================
FILE: resources/lang/id/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Jenis',
],
'event' => [
'label' => 'Peristiwa',
],
'subject_type' => [
'label' => 'Subjek',
],
'causer' => [
'label' => 'Pengguna',
],
'properties' => [
'label' => 'Properti',
],
'created_at' => [
'label' => 'Masuk di',
],
],
'filters' => [
'created_at' => [
'label' => 'Masuk di',
'created_from' => 'Dibuat dari',
'created_until' => 'Dibuat sampai',
],
'event' => [
'label' => 'Peristiwa',
],
],
];
================================================
FILE: resources/lang/id/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/it/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Log Attività Utente',
'description' => 'Traccia tutte le attività dell\'utente',
'tooltip' => 'Attività dell\'utente',
],
];
================================================
FILE: resources/lang/it/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Soggetto',
],
'causer' => [
'label' => 'Utente',
],
'description' => [
'label' => 'Descrizione',
],
'properties' => [
'label' => 'Proprietà',
],
'created_at' => [
'label' => 'Loggato il',
],
'old' => [
'label' => 'Vecchio',
],
'attributes' => [
'label' => 'Nuovo',
],
],
];
================================================
FILE: resources/lang/it/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Soggetto',
],
'causer' => [
'label' => 'Utente',
],
'properties' => [
'label' => 'Proprietà',
],
'created_at' => [
'label' => 'Loggato il',
],
],
'filters' => [
'created_at' => [
'label' => 'Loggato il',
'created_from' => 'Creato da ',
'created_until' => 'Creato fino al ',
],
'event' => [
'label' => 'Evento',
],
],
];
================================================
FILE: resources/lang/it/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/lv/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Lietotāju darbību žurnāls',
'description' => 'Sekojiet līdzi visām lietotāju darbībām',
'tooltip' => 'Lietotāju darbības',
],
];
================================================
FILE: resources/lang/lv/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Tips',
],
'event' => [
'label' => 'Notikums',
],
'subject_type' => [
'label' => 'Objekts',
],
'causer' => [
'label' => 'Lietotājs',
],
'description' => [
'label' => 'Apraksts',
],
'properties' => [
'label' => 'Īpašības',
],
'created_at' => [
'label' => 'Ierakstīts',
],
'old' => [
'label' => 'Vecs',
],
'attributes' => [
'label' => 'Jauns',
],
],
];
================================================
FILE: resources/lang/lv/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tips',
],
'event' => [
'label' => 'Notikums',
],
'subject_type' => [
'label' => 'Objekts',
],
'causer' => [
'label' => 'Lietotājs',
],
'properties' => [
'label' => 'Īpašības',
],
'created_at' => [
'label' => 'Ierakstīts',
],
],
'filters' => [
'created_at' => [
'label' => 'Ierakstīts',
'created_from' => 'Izveidots no ',
'created_until' => 'Izveidots līdz ',
],
'event' => [
'label' => 'Notikums',
],
],
];
================================================
FILE: resources/lang/lv/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => '<strong>%s</strong> tika <strong>%s</strong> ar lietotāju <strong>%s</strong>. <br><small> Atjaunots: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s sekojošu: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s no <strong>%s</strong> uz <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/nl/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Gebruikersctiviteiten Log',
'description' => 'Volg alle gebruikersactiviteiten',
'tooltip' => 'Gebruikersctiviteiten',
],
];
================================================
FILE: resources/lang/nl/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Event',
],
'subject_type' => [
'label' => 'Onderwerp',
],
'causer' => [
'label' => 'Gebruiker',
],
'description' => [
'label' => 'Omschrijving',
],
'properties' => [
'label' => 'Velden',
],
'created_at' => [
'label' => 'Gelogd op',
],
'old' => [
'label' => 'Oud',
],
'attributes' => [
'label' => 'Nieuw',
],
],
];
================================================
FILE: resources/lang/nl/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Type',
],
'event' => [
'label' => 'Event',
],
'subject_type' => [
'label' => 'Onderwerp',
],
'causer' => [
'label' => 'Gebruiker',
],
'properties' => [
'label' => 'Velden',
],
'created_at' => [
'label' => 'Gelogd op',
],
],
'filters' => [
'created_at' => [
'label' => 'Gelogd op',
'created_from' => 'Aangemaakt van ',
'created_until' => 'Aangemaakt tot ',
],
'event' => [
'label' => 'Event',
],
],
];
================================================
FILE: resources/lang/nl/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'De <strong>%s</strong> is <strong>%s</strong> door <strong>%s</strong>. <br><small> Geupdate om: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s het volgende: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s van <strong>%s</strong> tot <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/pl/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Dziennik zdarzeń',
'description' => 'Sprawdź historię wszystkich zmian',
'tooltip' => 'Historia zmian',
],
];
================================================
FILE: resources/lang/pl/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Typ',
],
'event' => [
'label' => 'Zdarzenie',
],
'subject_type' => [
'label' => 'Element',
],
'causer' => [
'label' => 'Użytkownik',
],
'description' => [
'label' => 'Opis',
],
'properties' => [
'label' => 'Właściwości',
],
'created_at' => [
'label' => 'Data zdarzenia',
],
'old' => [
'label' => 'Przed zmianą',
],
'attributes' => [
'label' => 'Po zmianie',
],
],
];
================================================
FILE: resources/lang/pl/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Typ',
],
'event' => [
'label' => 'Zdarzenie',
],
'subject_type' => [
'label' => 'Element',
],
'causer' => [
'label' => 'Użytkownik',
],
'properties' => [
'label' => 'Właściwości',
],
'created_at' => [
'label' => 'Data zdarzenia',
],
],
'filters' => [
'created_at' => [
'label' => 'Data zdarzenia',
'created_from' => 'Utworzony od ',
'created_until' => 'Utworzony do ',
],
'event' => [
'label' => 'Zdarzenie',
],
],
];
================================================
FILE: resources/lang/pl/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/pt_BR/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Registro de Logs do usuário',
'description' => 'Acompanhe todas as atividades do usuário',
'tooltip' => 'Atividades do usuário',
],
'event' => [
'created' => 'criado',
'deleted' => 'excluído',
'updated' => 'atualizado',
'restored' => 'restaurado',
],
'view' => 'Visualizar',
'edit' => 'Editar',
'restore' => 'Restaurar',
'restore_soft_delete' => [
'label' => 'Restaurar Modelo',
'modal_heading' => 'Restaurar Modelo Excluído',
'modal_description' => 'Isso irá restaurar o modelo que foi excluído (soft delete).',
],
];
================================================
FILE: resources/lang/pt_BR/forms.php
================================================
<?php
return [
'changes' => 'Mudanças',
'fields' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Assunto',
],
'causer' => [
'label' => 'Usuário',
],
'description' => [
'label' => 'Descrição',
],
'properties' => [
'label' => 'Propriedades',
],
'created_at' => [
'label' => 'Criando em',
],
'old' => [
'label' => 'Antigo',
],
'attributes' => [
'label' => 'Novo',
],
],
];
================================================
FILE: resources/lang/pt_BR/infolists.php
================================================
<?php
return [
'components' => [
'created_by_at' => 'O <strong>:subject</strong> foi <strong>:event</strong> por <strong>:causer</strong>. <br><small> Atualizado em: <strong>:update_at</strong></small>',
'updater_updated' => ':causer :event o seguinte: <br>:changes',
'from_oldvalue_to_newvalue' => '- :key de <strong>:old_value</strong> para <strong>:new_value</strong>',
'to_newvalue' => '- :key <strong>:new_value</strong>',
'unknown' => 'Desconhecido',
],
];
================================================
FILE: resources/lang/pt_BR/notifications.php
================================================
<?php
return [
'no_properties_to_restore' => 'Nenhuma propriedade para restaurar.',
'activity_restored' => 'Atividade restaurada.',
'activity_restored_successfully' => 'Atividade restaurada com sucesso.',
'failed_to_restore_activity' => 'Falha ao restaurar a atividade: :error.',
'subject_not_found' => 'Registro não encontrado.',
'unable_to_restore_this_model' => 'Não é possível restaurar este modelo',
'model_successfully_restored' => 'Modelo restaurado com sucesso',
'error_restoring_model' => 'Erro ao restaurar modelo',
];
================================================
FILE: resources/lang/pt_BR/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Assunto',
'soft_deleted' => ' (Delete suave)',
'deleted' => ' (Deletado)',
],
'causer' => [
'label' => 'Usuário',
],
'properties' => [
'label' => 'Propriedades',
],
'created_at' => [
'label' => 'Criado em',
],
],
'filters' => [
'created_at' => [
'label' => 'Criado em',
'created_from' => 'Criado a partir de ',
'created_from_indicator' => 'Criado a partir de : :created_from',
'created_until' => 'Criado até ',
'created_until_indicator' => 'Criado até : :created_until',
],
'event' => [
'label' => 'Eventos',
],
],
];
================================================
FILE: resources/lang/pt_BR/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'O <strong>%s</strong> foi <strong>%s</strong> por <strong>%s</strong>. <br><small> Atualizado em: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s o seguinte: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s de <strong>%s</strong> para <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/pt_PT/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Registro de Logs do utilizador',
'description' => 'Acompanhe todas as atividades do utilizador.',
'tooltip' => 'Atividades do utilizador',
],
];
================================================
FILE: resources/lang/pt_PT/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Assunto',
],
'causer' => [
'label' => 'Utilizador',
],
'description' => [
'label' => 'Descrição',
],
'properties' => [
'label' => 'Propriedades',
],
'created_at' => [
'label' => 'Criando em',
],
'old' => [
'label' => 'Antigo',
],
'attributes' => [
'label' => 'Novo',
],
],
];
================================================
FILE: resources/lang/pt_PT/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tipo',
],
'event' => [
'label' => 'Evento',
],
'subject_type' => [
'label' => 'Assunto',
],
'causer' => [
'label' => 'Utilizador',
],
'properties' => [
'label' => 'Propriedades',
],
'created_at' => [
'label' => 'Criado em',
],
],
'filters' => [
'created_at' => [
'label' => 'Criado em',
'created_from' => 'Criado a partir de ',
'created_until' => 'Criado até ',
],
'event' => [
'label' => 'Eventos',
],
],
];
================================================
FILE: resources/lang/pt_PT/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/lang/tr/action.php
================================================
<?php
return [
'modal' => [
'heading' => 'Kullanıcı Aktivite Günlüğü',
'description' => 'Tüm kullanıcı aktivitelerini takip edin',
'tooltip' => 'Kullanıcı Aktiviteleri',
],
];
================================================
FILE: resources/lang/tr/forms.php
================================================
<?php
return [
'fields' => [
'log_name' => [
'label' => 'Tip',
],
'event' => [
'label' => 'Olay',
],
'subject_type' => [
'label' => 'Konu',
],
'causer' => [
'label' => 'Kullanıcı',
],
'description' => [
'label' => 'Açıklama',
],
'properties' => [
'label' => 'Özellikler',
],
'created_at' => [
'label' => 'Kayıt Tarihi',
],
'old' => [
'label' => 'Eski',
],
'attributes' => [
'label' => 'Yeni',
],
],
];
================================================
FILE: resources/lang/tr/tables.php
================================================
<?php
return [
'columns' => [
'log_name' => [
'label' => 'Tip',
],
'event' => [
'label' => 'Olay',
],
'subject_type' => [
'label' => 'Konu',
],
'causer' => [
'label' => 'Kullanıcı',
],
'properties' => [
'label' => 'Özellikler',
],
'created_at' => [
'label' => 'Kayıt Tarihi',
],
],
'filters' => [
'created_at' => [
'label' => 'Kayıt Tarihi',
'created_from' => 'Kayıt tarihinden ',
'created_until' => 'Kayıt tarihine ',
],
'event' => [
'label' => 'Olay',
],
],
];
================================================
FILE: resources/lang/tr/timeline.php
================================================
<?php
return [
'title' => [
'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%s</strong>. <br><small> Updated at: <strong>%s</strong></small>',
],
'properties' => [
'modifiedProperties' => '%s %s the following: <br>%s',
'compareOldAndNewValues' => [
'notEquals' => '- %s from <strong>%s</strong> to <strong>%s</strong>',
'equals' => '- %s <strong>%s</strong>',
],
'getNewValues' => '- %s <strong>%s</strong>',
],
];
================================================
FILE: resources/views/.gitkeep
================================================
================================================
FILE: resources/views/filament/infolists/components/time-line-icon-entry.blade.php
================================================
@php
use Filament\Infolists\Components\IconEntry\IconEntrySize;
@endphp
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'absolute flex items-center justify-center w-6 h-6 bg-gray-200 rounded-full -start-3 ring-4 ring-white dark:bg-gray-700 dark:ring-gray-900',
])
}}
>
@if (count($arrayState = \Illuminate\Support\Arr::wrap($getState())))
@foreach ($arrayState as $state)
@if ($icon = $getIcon($state))
@php
$color = $getColor($state) ?? 'gray';
$size = $getSize($state) ?? IconEntrySize::Large;
@endphp
<x-filament::icon
:icon="$icon"
@class([
'fi-in-icon-item',
match ($size) {
IconEntrySize::ExtraSmall, 'xs' => 'fi-in-icon-item-size-xs h-3 w-3',
IconEntrySize::Small, 'sm' => 'fi-in-icon-item-size-sm h-4 w-4',
IconEntrySize::Medium, 'md' => 'fi-in-icon-item-size-md h-5 w-5',
IconEntrySize::Large, 'lg' => 'fi-in-icon-item-size-lg h-6 w-6',
IconEntrySize::ExtraLarge, 'xl' => 'fi-in-icon-item-size-xl h-7 w-7',
IconEntrySize::TwoExtraLarge, IconEntrySize::ExtraExtraLarge, '2xl' => 'fi-in-icon-item-size-2xl h-8 w-8',
default => $size,
},
match ($color) {
'gray' => 'fi-color-gray text-gray-400 dark:text-gray-500',
default => 'fi-color-custom text-custom-500 dark:text-custom-400',
},
])
@style([
\Filament\Support\get_color_css_variables(
$color,
shades: [400, 500],
alias: 'infolists::components.icon-entry.item',
) => $color !== 'gray',
])
/>
@endif
@endforeach
@elseif (($placeholder = $getPlaceholder()) !== null)
<x-filament-infolists::entries.placeholder>
{{ $placeholder }}
</x-filament-infolists::entries.placeholder>
@endif
</div>
</x-dynamic-component>
================================================
FILE: resources/views/filament/infolists/components/time-line-propertie-entry.blade.php
================================================
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div>
{{ $getModifiedState() ?? (!is_array($getState()) ? $getState() ?? $getPlaceholder() : null) }}
</div>
</x-dynamic-component>
================================================
FILE: resources/views/filament/infolists/components/time-line-repeatable-entry.blade.php
================================================
@php
$isContained = $isContained();
@endphp
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div
{{
$attributes
->merge([
'id' => $getId(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->class([
'fi-in-repeatable',
'fi-contained' => $isContained,
])
}}
>
@if (count($childComponentContainers = $getChildComponentContainers()))
<ol class="relative border-gray-200 border-s dark:border-gray-700">
<x-filament::grid
:default="$getGridColumns('default')"
:sm="$getGridColumns('sm')"
:md="$getGridColumns('md')"
:lg="$getGridColumns('lg')"
:xl="$getGridColumns('xl')"
:two-xl="$getGridColumns('2xl')"
class="gap-2"
>
@foreach ($childComponentContainers as $container)
<li
@class([
'mb-4 ms-6',
'fi-in-repeatable-item block',
'rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-950/5 dark:bg-white/5 dark:ring-white/10' => $isContained,
])
>
{{ $container }}
</li>
@endforeach
</x-filament::grid>
</ol>
@elseif (($placeholder = $getPlaceholder()) !== null)
<x-filament-infolists::entries.placeholder>
{{ $placeholder }}
</x-filament-infolists::entries.placeholder>
@endif
</div>
</x-dynamic-component>
================================================
FILE: resources/views/filament/infolists/components/time-line-title-entry.blade.php
================================================
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class(['fi-in-text w-full -mt-6'])
}}
>
{{ $getModifiedState() }}
</div>
</x-dynamic-component>
================================================
FILE: resources/views/filament/tables/columns/activity-logs-properties.blade.php
================================================
<div class="my-2 text-sm tracking-tight">
@foreach($getState() ?? [] as $key => $value)
<span class="inline-block p-1 mr-1 font-medium text-gray-700 whitespace-normal rounded-md dark:text-gray-200 bg-gray-500/10">
{{ $key }}
</span>
@if(is_array($value))
<span class="whitespace-normal divide-x divide-gray-200 divide-solid dark:divide-gray-700">
@foreach ($value as $nestedKey => $nestedValue)
<span class="inline-block mr-1">
{{ $nestedKey }}: {{ is_array($nestedValue) ? json_encode($nestedValue) : $nestedValue }}
</span>
@endforeach
</span>
@else
<span class="whitespace-normal">{{ $value }}</span>
@endif
@endforeach
</div>
================================================
FILE: src/Actions/ActivityLogTimelineSimpleAction.php
================================================
<?php
namespace Rmsramos\Activitylog\Actions;
use Filament\Actions\Action;
use Rmsramos\Activitylog\Actions\Concerns\ActionContent;
class ActivityLogTimelineSimpleAction extends Action
{
use ActionContent;
}
================================================
FILE: src/Actions/ActivityLogTimelineTableAction.php
================================================
<?php
namespace Rmsramos\Activitylog\Actions;
use Filament\Tables\Actions\Action;
use Rmsramos\Activitylog\Actions\Concerns\ActionContent;
class ActivityLogTimelineTableAction extends Action
{
use ActionContent;
}
================================================
FILE: src/Actions/Concerns/ActionContent.php
================================================
<?php
namespace Rmsramos\Activitylog\Actions\Concerns;
use Carbon\Exceptions\InvalidFormatException;
use Closure;
use Filament\Actions\StaticAction;
use Filament\Infolists\Components\TextEntry;
use Filament\Infolists\Infolist;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Rmsramos\Activitylog\ActivitylogPlugin;
use Rmsramos\Activitylog\Infolists\Components\TimeLineIconEntry;
use Rmsramos\Activitylog\Infolists\Components\TimeLinePropertiesEntry;
use Rmsramos\Activitylog\Infolists\Components\TimeLineRepeatableEntry;
use Rmsramos\Activitylog\Infolists\Components\TimeLineTitleEntry;
use Spatie\Activitylog\Models\Activity;
trait ActionContent
{
protected ?array $withRelations = null;
protected ?array $timelineIcons = [
'created' => 'heroicon-m-plus',
'updated' => 'heroicon-m-pencil-square',
'deleted' => 'heroicon-m-trash',
'restored' => 'heroicon-m-arrow-uturn-left',
];
protected ?array $timelineIconColors = [
'created' => 'success',
'updated' => 'warning',
'deleted' => 'danger',
'restored' => 'info',
];
protected ?int $limit = 10;
protected Closure $modifyQueryUsing;
protected Closure|Builder $query;
protected ?Closure $activitiesUsing;
protected ?Closure $modifyTitleUsing;
protected ?Closure $shouldModifyTitleUsing;
public static function getDefaultName(): ?string
{
return 'activitylog_timeline';
}
protected function setUp(): void
{
parent::setUp();
$this->configureInfolist();
$this->configureModal();
$this->activitiesUsing = null;
$this->modifyTitleUsing = null;
$this->shouldModifyTitleUsing = fn () => true;
$this->modifyQueryUsing = fn ($builder) => $builder;
$this->modalHeading = __('activitylog::action.modal.heading');
$this->modalDescription = __('activitylog::action.modal.description');
$this->query = function (?Model $record) {
if (! $record) {
return Activity::query()->whereRaw('1 = 0');
}
return Activity::query()
->with([
'subject' => function ($query) {
if (method_exists($query, 'withTrashed')) {
$query->withTrashed();
}
},
'causer',
])
->where(function (Builder $query) use ($record) {
$query->where('subject_type', $record->getMorphClass())
->where('subject_id', $record->getKey());
if ($relations = $this->getWithRelations()) {
foreach ($relations as $relation) {
if (method_exists($record, $relation)) {
try {
$relationInstance = $record->{$relation}();
if ($relationInstance instanceof BelongsToMany) {
$subjectType = $relationInstance->getPivotClass();
$relatedIds = $relationInstance->pluck($relationInstance->getTable().'.id')->toArray();
if (! empty($relatedIds)) {
$query->orWhere(function (Builder $q) use ($subjectType, $relatedIds) {
$q->where('subject_type', $subjectType)
->whereIn('subject_id', $relatedIds);
});
}
continue;
}
$relatedModel = $relationInstance->getRelated();
$relatedIds = $relationInstance->pluck('id')->toArray();
if (! empty($relatedIds)) {
$query->orWhere(function (Builder $q) use ($relatedModel, $relatedIds) {
$q->where('subject_type', $relatedModel->getMorphClass())
->whereIn('subject_id', $relatedIds);
});
}
} catch (\Exception $e) {
// Ignore errors
}
}
}
}
});
};
}
protected function configureInfolist(): void
{
$this->infolist(function (?Model $record, Infolist $infolist) {
$activities = $this->getActivityLogRecord($record, $this->getWithRelations());
$formattedActivities = $activities->map(function ($activity) {
return [
'id' => $activity->id,
'log_name' => $activity->log_name,
'updated_at' => $activity->updated_at,
'activityData' => $activity->activityData,
];
})->toArray();
return $infolist
->state(['activities' => $formattedActivities])
->schema($this->getSchema());
});
}
protected function configureModal(): void
{
$this->slideOver()
->modalIcon('heroicon-o-eye')
->modalFooterActions(fn () => [])
->tooltip(__('activitylog::action.modal.tooltip'))
->icon('heroicon-o-bell-alert');
}
protected function getSchema(): array
{
return [
TimeLineRepeatableEntry::make('activities')
->schema([
TimeLineIconEntry::make('activityData.event')
->icon(function ($state) {
return $this->getTimelineIcons()[$state] ?? 'heroicon-m-check';
})
->color(function ($state) {
return $this->getTimelineIconColors()[$state] ?? 'primary';
}),
TimeLineTitleEntry::make('activityData')
->configureTitleUsing($this->modifyTitleUsing)
->shouldConfigureTitleUsing($this->shouldModifyTitleUsing),
TimeLinePropertiesEntry::make('activityData'),
TextEntry::make('log_name')
->hiddenLabel()
->badge(),
TextEntry::make('updated_at')
->hiddenLabel()
->since()
->badge(),
]),
];
}
public function withRelations(?array $relations = null): ?StaticAction
{
$this->withRelations = $relations;
return $this;
}
public function timelineIcons(?array $timelineIcons = null): ?StaticAction
{
$this->timelineIcons = $timelineIcons;
return $this;
}
public function timelineIconColors(?array $timelineIconColors = null): ?StaticAction
{
$this->timelineIconColors = $timelineIconColors;
return $this;
}
public function limit(?int $limit = 10): ?StaticAction
{
$this->limit = $limit;
return $this;
}
public function query(Closure|Builder|null $query): static
{
$this->query = $query;
return $this;
}
public function modifyQueryUsing(Closure $closure): static
{
$this->modifyQueryUsing = $closure;
return $this;
}
public function modifyTitleUsing(Closure $closure): static
{
$this->modifyTitleUsing = $closure;
return $this;
}
public function shouldModifyTitleUsing(Closure $closure): static
{
$this->shouldModifyTitleUsing = $closure;
return $this;
}
public function activitiesUsing(Closure $closure): static
{
$this->activitiesUsing = $closure;
return $this;
}
public function getWithRelations(): ?array
{
return $this->evaluate($this->withRelations);
}
public function getTimelineIcons(): ?array
{
return $this->evaluate($this->timelineIcons);
}
public function getTimelineIconColors(): ?array
{
return $this->evaluate($this->timelineIconColors);
}
public function getLimit(): ?int
{
return $this->evaluate($this->limit);
}
public function getQuery(): ?Builder
{
return $this->evaluate($this->query);
}
public function getModifyQueryUsing(Builder $builder): Builder
{
return $this->evaluate($this->modifyQueryUsing, ['builder' => $builder]);
}
public function getActivitiesUsing(): ?Collection
{
return $this->evaluate($this->activitiesUsing);
}
protected function getActivities(?Model $record, ?array $relations = null): Collection
{
if ($activities = $this->getActivitiesUsing()) {
return $activities;
}
if (! $record) {
return collect();
}
$builder = $this->getQuery()
->latest()
->limit($this->getLimit());
return $this->getModifyQueryUsing($builder)->get();
}
protected function getActivityLogRecord(?Model $record, ?array $relations = null): Collection
{
$activities = $this->getActivities($record, $relations);
return $activities->transform(function ($activity) {
$activity->activityData = $this->formatActivityData($activity);
return $activity;
});
}
protected function formatActivityData($activity): array
{
$properties = [];
if ($activity->properties) {
if (is_string($activity->properties)) {
$properties = json_decode($activity->properties, true) ?? [];
} elseif (is_array($activity->properties)) {
$properties = $activity->properties;
} elseif (is_object($activity->properties) && method_exists($activity->properties, 'toArray')) {
$properties = $activity->properties->toArray();
}
}
if ($activity->event === 'restored') {
if (empty($properties) && $activity->description !== 'restored') {
$properties['description'] = $activity->description;
}
}
return [
'log_name' => $activity->log_name,
'description' => $activity->description,
'subject' => $activity->subject,
'event' => $activity->event,
'causer' => $activity->causer,
'properties' => $this->formatDateValues($properties),
'batch_uuid' => $activity->batch_uuid,
'update' => $activity->updated_at,
];
}
protected static function formatDateValues(array|string|null $value): array|string|null
{
if (is_null($value)) {
return $value;
}
if (is_array($value)) {
foreach ($value as &$item) {
$item = self::formatDateValues($item);
}
return $value;
}
if (is_numeric($value) && ! preg_match('/^\d{10,}$/', $value)) {
return $value;
}
if (is_bool($value)) {
return $value ? 'true' : 'false';
}
try {
$parser = ActivitylogPlugin::get()->getDateParser();
return $parser($value)->format(ActivitylogPlugin::get()->getDatetimeFormat());
} catch (InvalidFormatException $e) {
return $value;
} catch (\Exception $e) {
return $value;
}
}
}
================================================
FILE: src/ActivitylogPlugin.php
================================================
<?php
namespace Rmsramos\Activitylog;
use Closure;
use Filament\Contracts\Plugin;
use Filament\Panel;
use Filament\Support\Concerns\EvaluatesClosures;
use Illuminate\Support\Carbon;
class ActivitylogPlugin implements Plugin
{
use EvaluatesClosures;
protected ?string $resource = null;
protected string|Closure|null $label = null;
protected string|Closure|null $resourceActionLabel = null;
protected bool|Closure|null $isResourceActionHidden = null;
protected bool|Closure|null $isRestoreActionHidden = null;
protected bool|Closure|null $isRestoreModelActionHidden = null;
protected Closure|bool $navigationItem = true;
protected string|Closure|null $navigationGroup = null;
protected string|Closure|null $dateParser = null;
protected string|Closure|null $dateFormat = null;
protected string|Closure|null $datetimeFormat = null;
protected ?Closure $datetimeColumnCallback = null;
protected ?Closure $datePickerCallback = null;
protected ?Closure $translateSubject = null;
protected ?Closure $translateLogKey = null;
protected ?string $navigationIcon = null;
protected ?int $navigationSort = null;
protected ?bool $navigationCountBadge = null;
protected string|Closure|null $pluralLabel = null;
protected bool|Closure $authorizeUsing = true;
public static function make(): static
{
return app(static::class);
}
public function getId(): string
{
return 'rmsramos/activitylog';
}
public function register(Panel $panel): void
{
$panel
->resources([
$this->getResource(),
]);
}
public function boot(Panel $panel): void
{
//
}
public static function get(): static
{
return filament(app(static::class)->getId());
}
public function getResource(): string
{
return $this->resource ?? config('filament-activitylog.resources.resource');
}
public function getLabel(): string
{
return $this->evaluate($this->label) ?? config('filament-activitylog.resources.label');
}
public function getResourceActionLabel(): string
{
return $this->evaluate($this->resourceActionLabel) ?? config('filament-activitylog.resources.resource_action_label');
}
public function getIsResourceActionHidden(): bool
{
return $this->evaluate($this->isResourceActionHidden) ?? config('filament-activitylog.resources.hide_resource_action');
}
public function getIsRestoreActionHidden(): bool
{
return $this->evaluate($this->isRestoreActionHidden) ?? config('filament-activitylog.resources.hide_restore_action');
}
public function getIsRestoreModelActionHidden(): bool
{
return $this->evaluate($this->isRestoreModelActionHidden) ?? config('filament-activitylog.resources.hide_restore_model_action');
}
public function getPluralLabel(): string
{
return $this->evaluate($this->pluralLabel) ?? config('filament-activitylog.resources.plural_label');
}
public function getNavigationItem(): bool
{
return $this->evaluate($this->navigationItem) ?? config('filament-activitylog.resources.navigation_item');
}
public function getNavigationGroup(): ?string
{
return $this->evaluate($this->navigationGroup) ?? config('filament-activitylog.resources.navigation_group');
}
public function getDateFormat(): ?string
{
return $this->evaluate($this->dateFormat) ?? config('filament-activitylog.date_format');
}
public function getDatetimeFormat(): ?string
{
return $this->evaluate($this->datetimeFormat) ?? config('filament-activitylog.datetime_format');
}
public function getDatetimeColumnCallback(): ?Closure
{
return $this->datetimeColumnCallback;
}
public function getDatePickerCallback(): ?Closure
{
return $this->datePickerCallback;
}
public function getTranslateSubject($label): ?string
{
if (is_null($this->translateSubject)) {
return $label;
}
$callable = $this->translateSubject;
return $callable($label);
}
public function getTranslateLogKey($label): ?string
{
if (is_null($this->translateLogKey)) {
return $label;
}
$callable = $this->translateLogKey;
return $callable($label);
}
public function getDateParser(): ?Closure
{
return $this->dateParser ?? fn ($date) => Carbon::parse($date);
}
public function getNavigationIcon(): ?string
{
return $this->navigationIcon ?? config('filament-activitylog.resources.navigation_icon');
}
public function getNavigationSort(): ?int
{
return $this->navigationSort ?? config('filament-activitylog.resources.navigation_sort');
}
public function getNavigationCountBadge(): ?bool
{
return $this->navigationCountBadge ?? config('filament-activitylog.resources.navigation_count_badge');
}
public function resource(string $resource): static
{
$this->resource = $resource;
return $this;
}
public function label(string|Closure $label): static
{
$this->label = $label;
return $this;
}
public function resourceActionLabel(string|Closure $label): static
{
$this->resourceActionLabel = $label;
return $this;
}
public function isResourceActionHidden(bool|Closure $isHidden): static
{
$this->isResourceActionHidden = $isHidden;
return $this;
}
public function isRestoreActionHidden(bool|Closure $isHidden): static
{
$this->isRestoreActionHidden = $isHidden;
return $this;
}
public function isRestoreModelActionHidden(bool|Closure $isHidden): static
{
$this->isRestoreModelActionHidden = $isHidden;
return $this;
}
public function pluralLabel(string|Closure $label): static
{
$this->pluralLabel = $label;
return $this;
}
public function navigationItem(Closure|bool $value = true): static
{
$this->navigationItem = $value;
return $this;
}
public function navigationGroup(string|Closure|null $group = null): static
{
$this->navigationGroup = $group;
return $this;
}
public function dateParser(?Closure $parser = null): static
{
$this->dateParser = $parser;
return $this;
}
public function dateFormat(string|Closure|null $format = null): static
{
$this->dateFormat = $format;
return $this;
}
public function datetimeFormat(string|Closure|null $format = null): static
{
$this->datetimeFormat = $format;
return $this;
}
public function customizeDatetimeColumn(Closure $callable): self
{
$this->datetimeColumnCallback = $callable;
return $this;
}
public function customizeDatePicker(Closure $callable): self
{
$this->datePickerCallback = $callable;
return $this;
}
public function translateSubject(string|Closure|null $callable = null): static
{
$this->translateSubject = $callable;
return $this;
}
public function translateLogKey(string|Closure|null $callable = null): static
{
$this->translateLogKey = $callable;
return $this;
}
public function navigationIcon(string $icon): static
{
$this->navigationIcon = $icon;
return $this;
}
public function navigationSort(int $order): static
{
$this->navigationSort = $order;
return $this;
}
public function navigationCountBadge(bool $show = true): static
{
$this->navigationCountBadge = $show;
return $this;
}
public function authorize(bool|Closure $callback = true): static
{
$this->authorizeUsing = $callback;
return $this;
}
public function isAuthorized(): bool
{
return $this->evaluate($this->authorizeUsing) === true;
}
}
================================================
FILE: src/ActivitylogServiceProvider.php
================================================
<?php
namespace Rmsramos\Activitylog;
use Filament\Support\Assets\Css;
use Filament\Support\Facades\FilamentAsset;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
class ActivitylogServiceProvider extends PackageServiceProvider
{
public static string $name = 'activitylog';
public function configurePackage(Package $package): void
{
$package
->name('activitylog')
->hasConfigFile('filament-activitylog')
->hasViews('activitylog')
->hasTranslations()
->hasInstallCommand(function (InstallCommand $installCommand) {
$installCommand
->publishConfigFile()
->askToStarRepoOnGitHub('rmsramos/activitylog')
->startWith(function (InstallCommand $installCommand) {
$installCommand->call('vendor:publish', [
'--provider' => "Spatie\Activitylog\ActivitylogServiceProvider",
'--tag' => 'activitylog-migrations',
]);
});
});
}
public function packageBooted(): void
{
$assets = [
Css::make('activitylog-styles', __DIR__ . '/../resources/dist/activitylog.css'),
];
FilamentAsset::register($assets, 'rmsramos/activitylog');
}
}
================================================
FILE: src/Helpers/ActivityLogHelper.php
================================================
<?php
namespace Rmsramos\Activitylog\Helpers;
use Illuminate\Support\Str;
class ActivityLogHelper
{
/**
* Checks if a class uses a specific trait.
*
* @param mixed $class The class or object instance to check.
* @param string $trait The fully qualified name of the trait to look for.
*/
public static function classUsesTrait($class, $trait): bool
{
$traits = class_uses_recursive($class);
return in_array($trait, $traits);
}
public static function getResourcePluralName($class): string
{
return Str::plural(Str::kebab(class_basename($class)));
}
}
================================================
FILE: src/Infolists/Components/TimeLineIconEntry.php
================================================
<?php
namespace Rmsramos\Activitylog\Infolists\Components;
use Filament\Infolists\Components\IconEntry;
class TimeLineIconEntry extends IconEntry
{
protected function setUp(): void
{
parent::setUp();
$this->configureIconEntry();
}
protected string $view = 'activitylog::filament.infolists.components.time-line-icon-entry';
protected function configureIconEntry()
{
$this
->hiddenLabel()
->size('w-4 h-4');
}
}
================================================
FILE: src/Infolists/Components/TimeLinePropertiesEntry.php
================================================
<?php
namespace Rmsramos\Activitylog\Infolists\Components;
use Filament\Infolists\Components\Entry;
use Illuminate\Support\HtmlString;
use Rmsramos\Activitylog\ActivitylogPlugin;
use Rmsramos\Activitylog\Infolists\Concerns\HasModifyState;
class TimeLinePropertiesEntry extends Entry
{
use HasModifyState;
protected string $view = 'activitylog::filament.infolists.components.time-line-propertie-entry';
protected function setup(): void
{
parent::setup();
$this->configurePropertieEntry();
}
protected function configurePropertieEntry(): void
{
$this
->hiddenLabel()
->modifyState(fn ($state) => $this->modifiedProperties($state));
}
protected function modifiedProperties($state): ?HtmlString
{
$properties = $state['properties'];
if (! empty($properties)) {
$changes = $this->getPropertyChanges($properties);
$causerName = $this->getCauserName($state['causer']);
return new HtmlString(trans('activitylog::infolists.components.updater_updated', [
'causer' => $causerName,
'event' => __('activitylog::action.event.' . $state['event']),
'changes' => implode('<br>', $changes),
]));
}
return null;
}
protected function getPropertyChanges(array $properties): array
{
$changes = [];
if (isset($properties['old'], $properties['attributes'])) {
$changes = $this->compareOldAndNewValues($properties['old'], $properties['attributes']);
} elseif (isset($properties['attributes'])) {
$changes = $this->getNewValues($properties['attributes']);
} elseif (isset($properties['old'])) {
$changes = $this->getNewValues($properties['old']);
}
return $changes;
}
protected function compareOldAndNewValues(array $oldValues, array $newValues): array
{
$changes = [];
foreach ($newValues as $key => $newValue) {
$oldValue = is_array($oldValues[$key]) ? json_encode($oldValues[$key]) : $oldValues[$key] ?? '-';
$newValue = $this->formatNewValue($newValue);
if (isset($oldValues[$key]) && $oldValues[$key] != $newValue) {
$changes[] = trans('activitylog::infolists.components.from_oldvalue_to_newvalue',
[
'key' => ActivitylogPlugin::get()->getTranslateLogKey($key),
'old_value' => htmlspecialchars($oldValue),
'new_value' => htmlspecialchars($newValue),
]);
} else {
$changes[] = trans('activitylog::infolists.components.to_newvalue',
[
'key' => ActivitylogPlugin::get()->getTranslateLogKey($key),
'new_value' => htmlspecialchars($newValue),
]);
}
}
return $changes;
}
protected function getNewValues(array $newValues): array
{
return array_map(
fn ($key, $value) => sprintf(
__('activitylog::timeline.properties.getNewValues'),
ActivitylogPlugin::get()->getTranslateLogKey($key),
htmlspecialchars($this->formatNewValue($value))
),
array_keys($newValues),
$newValues
);
}
protected function formatNewValue($value): string
{
return is_array($value) ? json_encode($value) : $value ?? '—';
}
}
================================================
FILE: src/Infolists/Components/TimeLineRepeatableEntry.php
================================================
<?php
namespace Rmsramos\Activitylog\Infolists\Components;
use Filament\Infolists\Components\RepeatableEntry;
class TimeLineRepeatableEntry extends RepeatableEntry
{
protected function setup(): void
{
parent::setup();
$this->configureRepeatableEntry();
}
protected function configureRepeatableEntry(): void
{
$this
->extraAttributes(['style' => 'margin-left:1.25rem;'])
->contained(false)
->hiddenLabel();
}
protected string $view = 'activitylog::filament.infolists.components.time-line-repeatable-entry';
}
================================================
FILE: src/Infolists/Components/TimeLineTitleEntry.php
================================================
<?php
namespace Rmsramos\Activitylog\Infolists\Components;
use Closure;
use Filament\Forms\Components\Concerns\CanAllowHtml;
use Filament\Infolists\Components\Entry;
use Filament\Support\Concerns\HasExtraAttributes;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Rmsramos\Activitylog\ActivitylogPlugin;
use Rmsramos\Activitylog\Infolists\Concerns\HasModifyState;
class TimeLineTitleEntry extends Entry
{
use CanAllowHtml;
use HasExtraAttributes;
use HasModifyState;
protected ?Closure $configureTitleUsing = null;
protected ?Closure $shouldConfigureTitleUsing = null;
protected function setUp(): void
{
parent::setUp();
$this->configureTitleEntry();
}
protected string $view = 'activitylog::filament.infolists.components.time-line-title-entry';
public function configureTitleUsing(?Closure $configureTitleUsing): TimeLineTitleEntry
{
$this->configureTitleUsing = $configureTitleUsing;
return $this;
}
public function shouldConfigureTitleUsing(?Closure $condition): TimeLineTitleEntry
{
$this->shouldConfigureTitleUsing = $condition;
return $this;
}
protected function configureTitleEntry()
{
$this
->hiddenLabel()
->modifyState(fn ($state) => $this->modifiedTitle($state));
}
protected function modifiedTitle($state): string|HtmlString|Closure
{
if ($this->configureTitleUsing !== null && $this->shouldConfigureTitleUsing !== null && $this->evaluate($this->shouldConfigureTitleUsing)) {
return $this->evaluate($this->configureTitleUsing, ['state' => $state]);
} else {
if ($state['description'] == $state['event'] || $state['event'] === 'restored') {
$className = property_exists($state['subject'], 'activityTitleName') && ! empty($state['subject']::$activityTitleName)
? $state['subject']::$activityTitleName
: Str::lower(Str::snake(class_basename($state['subject']), ' '));
$causerName = $this->getCauserName($state['causer']);
$parser = ActivitylogPlugin::get()->getDateParser();
$update_at = $parser($state['update'])->format(ActivitylogPlugin::get()->getDatetimeFormat());
return new HtmlString(
__('activitylog::infolists.components.created_by_at',
[
'subject' => ActivitylogPlugin::get()->getTranslateSubject($className),
'event' => __('activitylog::action.event.' . $state['event']),
'causer' => $causerName,
'update_at' => $update_at,
]),
);
}
}
return '';
}
}
================================================
FILE: src/Infolists/Concerns/HasModifyState.php
================================================
<?php
namespace Rmsramos\Activitylog\Infolists\Concerns;
use Closure;
use Illuminate\Support\HtmlString;
trait HasModifyState
{
protected $state;
public function modifyState(Closure $callback): static
{
$this->state = $callback;
return $this;
}
public function getModifiedState(): null|string|HtmlString
{
return $this->evaluate($this->state);
}
protected function getCauserName($causer): string
{
return $causer->name ?? $causer->first_name ?? $causer->last_name ?? $causer->username ?? trans('activitylog::infolists.components.unknown');
}
}
================================================
FILE: src/RelationManagers/ActivitylogRelationManager.php
================================================
<?php
namespace Rmsramos\Activitylog\RelationManagers;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Rmsramos\Activitylog\ActivitylogPlugin;
use Rmsramos\Activitylog\Resources\ActivitylogResource;
class ActivitylogRelationManager extends RelationManager
{
protected static string $relationship = 'activities';
protected static ?string $recordTitleAttribute = 'description';
public static function getTitle(Model $ownerRecord, string $pageClass): string
{
return static::$title ?? (string) str(ActivitylogPlugin::get()->getPluralLabel())
->kebab()
->replace('-', ' ')
->headline();
}
public function form(Form $form): Form
{
return ActivitylogResource::form($form);
}
public function table(Table $table): Table
{
return ActivitylogResource::table(
$table
->heading(ActivitylogPlugin::get()->getPluralLabel())
->actions([
ViewAction::make(),
])
);
}
}
================================================
FILE: src/Resources/ActivitylogResource/ActivitylogResource.php
================================================
<?php
namespace Rmsramos\Activitylog\Resources\ActivitylogResource;
use ActivitylogForm;
use Exception;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Placeholder;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\Column;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ViewColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Livewire\Component as Livewire;
use Rmsramos\Activitylog\Actions\Concerns\ActionContent;
use Rmsramos\Activitylog\ActivitylogPlugin;
use Rmsramos\Activitylog\Helpers\ActivityLogHelper;
use Rmsramos\Activitylog\RelationManagers\ActivitylogRelationManager;
use Rmsramos\Activitylog\Resources\ActivitylogResource\Pages\ListActivitylog;
use Rmsramos\Activitylog\Resources\ActivitylogResource\Pages\ViewActivitylog;
use Rmsramos\Activitylog\Traits\HasCustomActivityResource;
use Spatie\Activitylog\Models\Activity;
class ActivitylogResource extends Resource
{
use ActionContent;
protected static ?string $slug = 'activitylogs';
public static function getModel(): string
{
return config('activitylog.activity_model', Activity::class);
}
public static function getModelLabel(): string
{
return ActivitylogPlugin::get()->getLabel();
}
public static function getPluralModelLabel(): string
{
return ActivitylogPlugin::get()->getPluralLabel();
}
public static function getNavigationIcon(): string
{
return ActivitylogPlugin::get()->getNavigationIcon();
}
public static function getNavigationLabel(): string
{
return Str::title(static::getPluralModelLabel()) ?? Str::title(static::getModelLabel());
}
public static function getNavigationSort(): ?int
{
return ActivitylogPlugin::get()->getNavigationSort();
}
public static function getNavigationGroup(): ?string
{
return ActivitylogPlugin::get()->getNavigationGroup();
}
public static function getNavigationBadge(): ?string
{
return ActivitylogPlugin::get()->getNavigationCountBadge() ?
number_format(static::getModel()::count()) : null;
}
protected static function getResourceUrl(Activity $record): string
{
$panelID = Filament::getCurrentPanel()->getId();
if ($record->subject_type && $record->subject_id) {
try {
$model = app($record->subject_type);
if (ActivityLogHelper::classUsesTrait($model, HasCustomActivityResource::class)) {
$resourceModel = $model->getFilamentActualResourceModel($record);
$resourcePluralName = ActivityLogHelper::getResourcePluralName($resourceModel);
return route('filament.'.$panelID.'.resources.'.$resourcePluralName.'.edit', ['record' => $resourceModel->id]);
}
// Fallback to a standard resource mapping
$resourcePluralName = ActivityLogHelper::getResourcePluralName($record->subject_type);
return route('filament.'.$panelID.'.resources.'.$resourcePluralName.'.edit', ['record' => $record->subject_id]);
} catch (Exception $e) {
// If there's any error generating the URL, return placeholder
return '#';
}
}
return '#';
}
public static function form(Schema $schema): Schema
{
return ActivitylogForm::configure($schema);
}
protected static function flattenArrayForKeyValue(array $data): array
{
$flattened = [];
foreach ($data as $key => $value) {
if (is_array($value) || is_object($value)) {
$flattened[$key] = json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
} else {
$flattened[$key] = $value;
}
}
return $flattened;
}
public static function table(Table $table): Table
{
return $table
->columns([
static::getLogNameColumnComponent(),
static::getEventColumnComponent(),
static::getSubjectTypeColumnComponent(),
static::getCauserNameColumnComponent(),
static::getPropertiesColumnComponent(),
static::getCreatedAtColumnComponent(),
])
->defaultSort(
config('filament-activitylog.resources.default_sort_column', 'created_at'),
config('filament-activitylog.resources.default_sort_direction', 'desc')
)
->filters([
static::getDateFilterComponent(),
static::getEventFilterComponent(),
static::getLogNameFilterComponent(),
]);
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->with([
'subject' => function ($query) {
if (method_exists($query, 'withTrashed')) {
$query->withTrashed();
}
},
'causer',
]);
}
public static function getLogNameColumnComponent(): Column
{
return TextColumn::make('log_name')
->label(__('activitylog::tables.columns.log_name.label'))
->formatStateUsing(fn ($state) => $state ? ucwords($state) : '-')
->searchable()
->sortable()
->badge();
}
public static function getEventColumnComponent(): Column
{
return TextColumn::make('event')
->label(__('activitylog::tables.columns.event.label'))
->formatStateUsing(fn ($state) => $state ? ucwords(__('activitylog::action.event.'.$state)) : '-')
->badge()
->color(fn (?string $state): string => match ($state) {
'draft' => 'gray',
'updated' => 'warning',
'created' => 'success',
'deleted' => 'danger',
'restored' => 'info',
default => 'primary',
})
->searchable()
->sortable();
}
public static function getSubjectTypeColumnComponent(): Column
{
return TextColumn::make('subject_type')
->label(__('activitylog::tables.columns.subject_type.label'))
->formatStateUsing(function ($state, Model $record) {
/** @var Activity $record */
if (! $state) {
return '-';
}
$subjectInfo = Str::of($state)->afterLast('\\')->headline().' # '.$record->subject_id;
if ($record->subject) {
if (method_exists($record->subject, 'trashed') && $record->subject->trashed()) {
$subjectInfo .= __('activitylog::tables.columns.subject_type.soft_deleted');
}
} else {
$subjectInfo .= __('activitylog::tables.columns.subject_type.deleted');
}
return $subjectInfo;
})
->searchable()
->hidden(fn (Livewire $livewire) => $livewire instanceof ActivitylogRelationManager);
}
public static function getCauserNameColumnComponent(): Column
{
return TextColumn::make('causer.name')
->label(__('activitylog::tables.columns.causer.label'))
->getStateUsing(function (Model $record) {
/** @var Activity $record */
if ($record->causer_id === null || $record->causer === null) {
return new HtmlString('—');
}
return $record->causer->name ?? new HtmlString('—');
})
->searchable();
}
public static function getPropertiesColumnComponent(): Column
{
return ViewColumn::make('properties')
->searchable()
->label(__('activitylog::tables.columns.properties.label'))
->view('activitylog::filament.tables.columns.activity-logs-properties')
->toggleable(isToggledHiddenByDefault: true);
}
public static function getCreatedAtColumnComponent(): Column
{
$column = TextColumn::make('created_at')
->label(__('activitylog::tables.columns.created_at.label'))
->dateTime(ActivitylogPlugin::get()->getDatetimeFormat())
->searchable()
->sortable();
// Apply the custom callback if set
$callback = ActivitylogPlugin::get()->getDatetimeColumnCallback();
if ($callback) {
$column = $callback($column);
}
return $column;
}
public static function getDatePickerCompoment(string $label): DatePicker
{
$field = DatePicker::make($label)
->format(ActivitylogPlugin::get()->getDateFormat())
->label(__('activitylog::tables.filters.created_at.'.$label));
// Apply the custom callback if set
$callback = ActivitylogPlugin::get()->getDatePickerCallback();
if ($callback) {
$field = $callback($field);
}
return $field;
}
public static function getDateFilterComponent(): Filter
{
return Filter::make('created_at')
->label(__('activitylog::tables.filters.created_at.label'))
->indicateUsing(function (array $data): array {
$indicators = [];
$parser = ActivitylogPlugin::get()->getDateParser();
if ($data['created_from'] ?? null) {
$indicators['created_from'] = __('activitylog::tables.filters.created_at.created_from_indicator', [
'created_from' => $parser($data['created_from'])
->format(ActivitylogPlugin::get()->getDateFormat()),
]);
}
if ($data['created_until'] ?? null) {
$indicators['created_until'] = __('activitylog::tables.filters.created_at.created_until_indicator', [
'created_until' => $parser($data['created_until'])
->format(ActivitylogPlugin::get()->getDateFormat()),
]);
}
return $indicators;
})
->form([
self::getDatePickerCompoment('created_from'),
self::getDatePickerCompoment('created_until'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['created_from'] ?? null,
fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date),
)
->when(
$data['created_until'] ?? null,
fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date),
);
});
}
public static function getEventFilterComponent(): SelectFilter
{
return SelectFilter::make('event')
->label(__('activitylog::tables.filters.event.label'))
->options(static::getModel()::distinct()
->pluck('event', 'event')
->mapWithKeys(fn ($value, $key) => [$key => __('activitylog::action.event.'.$value)])
);
}
public static function getLogNameFilterComponent(): SelectFilter
{
return SelectFilter::make('log_name')
->label(__('activitylog::tables.filters.log_name.label'))
->options(static::getModel()::distinct()->pluck('log_name', 'log_name')->filter());
}
public static function getPages(): array
{
return [
'index' => ListActivitylog::route('/'),
'view' => ViewActivitylog::route('/{record}'),
];
}
public static function shouldRegisterNavigation(): bool
{
$plugin = Filament::getCurrentPanel()?->getPlugin('rmsramos/activitylog');
return $plugin?->getNavigationItem() ?? false;
}
public static function canAccess(): bool
{
$policy = Gate::getPolicyFor(static::getModel());
if ($policy && method_exists($policy, 'viewAny')) {
return static::canViewAny();
}
return ActivitylogPlugin::get()->isAuthorized();
}
protected static function canViewResource(Activity $record): bool
{
if ($record->subject_type && $record->subject_id) {
try {
$model = app($record->subject_type);
if (ActivityLogHelper::classUsesTrait($model, HasCustomActivityResource::class)) {
$resourceModel = $model->getFilamentActualResourceModel($record);
$user = auth()->user();
return $user && $user->can('update', $resourceModel);
}
// Fallback to check if the user can edit the model using a generic policy
$user = auth()->user();
return $user && $record->subject && $user->can('update', $record->subject);
} catch (Exception $e) {
return false;
}
}
return false;
}
public static function restoreActivity(int|string $key): void
{
$activity = Activity::find($key);
if (! $activity) {
Notification::make()
->title(__('activitylog::notifications.activity_not_found'))
->danger()
->send();
return;
}
$oldProperties = data_get($activity, 'properties.old');
$newProperties = data_get($activity, 'properties.attributes');
if ($oldProperties === null) {
Notification::make()
->title(__('activitylog::notifications.no_properties_to_restore'))
->danger()
->send();
return;
}
try {
$record = $activity->subject;
if (! $record) {
Notification::make()
->title(__('activitylog::notifications.subject_not_found'))
->danger()
->send();
return;
}
// Temporarily disable activity logging to prevent updated log
activity()->withoutLogs(function () use ($record, $oldProperties) {
$record->update($oldProperties);
});
if (auth()->user()) {
activity()
->performedOn($record)
->causedBy(auth()->user())
->withProperties([
'attributes' => $oldProperties,
'old' => $newProperties,
])
->tap(function ($log) {
$log->event = 'restored';
})
->log('restored');
}
Notification::make()
->title(__('activitylog::notifications.activity_restored_successfully'))
->success()
->send();
} catch (ModelNotFoundException $e) {
Notification::make()
->title(__('activitylog::notifications.record_not_found'))
->danger()
->send();
} catch (Exception $e) {
Notification::make()
->title(__('activitylog::notifications.failed_to_restore_activity', ['error' => $e->getMessage()]))
->danger()
->send();
}
}
public static function canRestoreSubjectFromSoftDelete(Activity $record): bool
{
if (ActivitylogPlugin::get()->getIsRestoreModelActionHidden()) {
return false;
}
if ($record->event !== 'deleted') {
return false;
}
if (! $record->subject) {
return false;
}
if (! method_exists($record->subject, 'trashed') ||
! method_exists($record->subject, 'restore')) {
return false;
}
if (! $record->subject->trashed()) {
return false;
}
$user = auth()->user();
if ($user && method_exists($record->subject, 'exists')) {
try {
return $user->can('restore', $record->subject);
} catch (\Exception $e) {
return true;
}
}
return true;
}
public static function restoreSubjectFromSoftDelete(Activity $record): void
{
if (! static::canRestoreSubjectFromSoftDelete($record)) {
Notification::make()
->title(__('activitylog::notifications.unable_to_restore_this_model'))
->danger()
->send();
return;
}
try {
DB::beginTransaction();
$subject = $record->subject;
$beforeRestore = $subject->toArray();
activity()->withoutLogs(function () use ($subject) {
$subject->restore();
});
$subject->refresh();
$afterRestore = $subject->toArray();
if (auth()->user()) {
activity()
->performedOn($subject)
->causedBy(auth()->user())
->withProperties([
'attributes' => $afterRestore,
'old' => $beforeRestore,
'restore_metadata' => [
'restored_from_soft_delete' => true,
'original_activity_id' => $record->id,
'restore_type' => 'soft_delete',
],
])
->tap(function ($log) {
$log->event = 'restored';
})
->log('restored');
}
DB::commit();
Notification::make()
->title(__('activitylog::notifications.model_successfully_restored'))
->success()
->send();
} catch (Exception $e) {
DB::rollBack();
Notification::make()
->title(__('activitylog::notifications.error_restoring_model'))
->body('Erro: '.$e->getMessage())
->danger()
->send();
}
}
}
================================================
FILE: src/Resources/ActivitylogResource/Pages/ListActivitylog.php
================================================
<?php
namespace Rmsramos\Activitylog\Resources\ActivitylogResource\Pages;
use Filament\Resources\Pages\ListRecords;
use Rmsramos\Activitylog\Resources\ActivitylogResource;
class ListActivitylog extends ListRecords
{
protected static string $resource = ActivitylogResource::class;
}
================================================
FILE: src/Resources/ActivitylogResource/Pages/ViewActivitylog.php
================================================
<?php
namespace Rmsramos\Activitylog\Resources\ActivitylogResource\Pages;
use Filament\Resources\Pages\ViewRecord;
use Rmsramos\Activitylog\Resources\ActivitylogResource;
class ViewActivitylog extends ViewRecord
{
public static function getResource(): string
{
return ActivitylogResource::class;
}
}
================================================
FILE: src/Resources/ActivitylogResource/Schemas/ActivitylogForm.php
================================================
<?php
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Model;
use Rmsramos\Activitylog\ActivitylogPlugin;
class ActivitylogForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
Section::make([
TextInput::make('causer_id')
->afterStateHydrated(function ($component, ?Model $record) {
return $component->state($record?->causer?->name ?? '-');
})
->label(__('activitylog::forms.fields.causer.label')),
TextInput::make('subject_type')
->afterStateHydrated(function ($component, ?Model $record, $state) {
/** @var Activity $record */
return $state ? $component->state(Str::of($state)->afterLast('\\')->headline().' # '.$record->subject_id) : $component->state('-');
})
->label(__('activitylog::forms.fields.subject_type.label')),
Textarea::make('description')
->label(__('activitylog::forms.fields.description.label'))
->rows(2)
->columnSpan('full'),
]),
Section::make([
TextEntry::make('log_name')
->content(function (?Model $record): string {
/** @var Activity $record */
return $record?->log_name ? ucwords($record->log_name) : '-';
})
->label(__('activitylog::forms.fields.log_name.label')),
TextEntry::make('event')
->content(function (?Model $record): string {
/** @var Activity $record */
return $record?->event ? ucwords(__('activitylog::action.event.'.$record->event)) : '-';
})
->label(__('activitylog::forms.fields.event.label')),
TextEntry::make('created_at')
->label(__('activitylog::forms.fields.created_at.label'))
->content(function (?Model $record): string {
/** @var Activity $record */
if (! $record?->created_at) {
return '-';
}
$parser = ActivitylogPlugin::get()->getDateParser();
return $parser($record->created_at)
->format(ActivitylogPlugin::get()->getDatetimeFormat());
}),
]),
]);
}
}
================================================
FILE: src/Traits/HasCustomActivityResource.php
================================================
<?php
namespace Rmsramos\Activitylog\Traits;
use Illuminate\Database\Eloquent\Model;
trait HasCustomActivityResource
{
/**
* Retrieve the associated Filament resource model.
*
* @param Model $record The activity log record providing context.
*/
public function getFilamentActualResourceModel($record): Model
{
return $record;
}
}
================================================
FILE: tailwind.config.js
================================================
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'class',
content: [
"./resources/**/*.blade.php",
],
theme: {
extend: {},
},
plugins: [],
}
gitextract_nvk_dftn/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.yml │ │ └── config.yml │ └── workflows/ │ └── fix-php-code-style-issues.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── config/ │ └── filament-activitylog.php ├── package.json ├── pint.json ├── postcss.config.js ├── resources/ │ ├── css/ │ │ └── plugin.css │ ├── dist/ │ │ └── activitylog.css │ ├── lang/ │ │ ├── ar/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── de/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── en/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── infolists.php │ │ │ ├── notifications.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── es/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── infolists.php │ │ │ ├── notifications.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── fa/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── infolists.php │ │ │ ├── notifications.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── fr/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── he/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── id/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── it/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── lv/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── nl/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── pl/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── pt_BR/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── infolists.php │ │ │ ├── notifications.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ ├── pt_PT/ │ │ │ ├── action.php │ │ │ ├── forms.php │ │ │ ├── tables.php │ │ │ └── timeline.php │ │ └── tr/ │ │ ├── action.php │ │ ├── forms.php │ │ ├── tables.php │ │ └── timeline.php │ └── views/ │ ├── .gitkeep │ └── filament/ │ ├── infolists/ │ │ └── components/ │ │ ├── time-line-icon-entry.blade.php │ │ ├── time-line-propertie-entry.blade.php │ │ ├── time-line-repeatable-entry.blade.php │ │ └── time-line-title-entry.blade.php │ └── tables/ │ └── columns/ │ └── activity-logs-properties.blade.php ├── src/ │ ├── Actions/ │ │ ├── ActivityLogTimelineSimpleAction.php │ │ ├── ActivityLogTimelineTableAction.php │ │ └── Concerns/ │ │ └── ActionContent.php │ ├── ActivitylogPlugin.php │ ├── ActivitylogServiceProvider.php │ ├── Helpers/ │ │ └── ActivityLogHelper.php │ ├── Infolists/ │ │ ├── Components/ │ │ │ ├── TimeLineIconEntry.php │ │ │ ├── TimeLinePropertiesEntry.php │ │ │ ├── TimeLineRepeatableEntry.php │ │ │ └── TimeLineTitleEntry.php │ │ └── Concerns/ │ │ └── HasModifyState.php │ ├── RelationManagers/ │ │ └── ActivitylogRelationManager.php │ ├── Resources/ │ │ └── ActivitylogResource/ │ │ ├── ActivitylogResource.php │ │ ├── Pages/ │ │ │ ├── ListActivitylog.php │ │ │ └── ViewActivitylog.php │ │ └── Schemas/ │ │ └── ActivitylogForm.php │ └── Traits/ │ └── HasCustomActivityResource.php └── tailwind.config.js
SYMBOL INDEX (146 symbols across 17 files)
FILE: src/Actions/ActivityLogTimelineSimpleAction.php
class ActivityLogTimelineSimpleAction (line 8) | class ActivityLogTimelineSimpleAction extends Action
FILE: src/Actions/ActivityLogTimelineTableAction.php
class ActivityLogTimelineTableAction (line 8) | class ActivityLogTimelineTableAction extends Action
FILE: src/Actions/Concerns/ActionContent.php
type ActionContent (line 21) | trait ActionContent
method getDefaultName (line 51) | public static function getDefaultName(): ?string
method setUp (line 56) | protected function setUp(): void
method configureInfolist (line 125) | protected function configureInfolist(): void
method configureModal (line 145) | protected function configureModal(): void
method getSchema (line 154) | protected function getSchema(): array
method withRelations (line 181) | public function withRelations(?array $relations = null): ?StaticAction
method timelineIcons (line 188) | public function timelineIcons(?array $timelineIcons = null): ?StaticAc...
method timelineIconColors (line 195) | public function timelineIconColors(?array $timelineIconColors = null):...
method limit (line 202) | public function limit(?int $limit = 10): ?StaticAction
method query (line 209) | public function query(Closure|Builder|null $query): static
method modifyQueryUsing (line 216) | public function modifyQueryUsing(Closure $closure): static
method modifyTitleUsing (line 223) | public function modifyTitleUsing(Closure $closure): static
method shouldModifyTitleUsing (line 230) | public function shouldModifyTitleUsing(Closure $closure): static
method activitiesUsing (line 237) | public function activitiesUsing(Closure $closure): static
method getWithRelations (line 244) | public function getWithRelations(): ?array
method getTimelineIcons (line 249) | public function getTimelineIcons(): ?array
method getTimelineIconColors (line 254) | public function getTimelineIconColors(): ?array
method getLimit (line 259) | public function getLimit(): ?int
method getQuery (line 264) | public function getQuery(): ?Builder
method getModifyQueryUsing (line 269) | public function getModifyQueryUsing(Builder $builder): Builder
method getActivitiesUsing (line 274) | public function getActivitiesUsing(): ?Collection
method getActivities (line 279) | protected function getActivities(?Model $record, ?array $relations = n...
method getActivityLogRecord (line 296) | protected function getActivityLogRecord(?Model $record, ?array $relati...
method formatActivityData (line 307) | protected function formatActivityData($activity): array
method formatDateValues (line 340) | protected static function formatDateValues(array|string|null $value): ...
FILE: src/ActivitylogPlugin.php
class ActivitylogPlugin (line 11) | class ActivitylogPlugin implements Plugin
method make (line 55) | public static function make(): static
method getId (line 60) | public function getId(): string
method register (line 65) | public function register(Panel $panel): void
method boot (line 73) | public function boot(Panel $panel): void
method get (line 78) | public static function get(): static
method getResource (line 83) | public function getResource(): string
method getLabel (line 88) | public function getLabel(): string
method getResourceActionLabel (line 93) | public function getResourceActionLabel(): string
method getIsResourceActionHidden (line 98) | public function getIsResourceActionHidden(): bool
method getIsRestoreActionHidden (line 103) | public function getIsRestoreActionHidden(): bool
method getIsRestoreModelActionHidden (line 108) | public function getIsRestoreModelActionHidden(): bool
method getPluralLabel (line 113) | public function getPluralLabel(): string
method getNavigationItem (line 118) | public function getNavigationItem(): bool
method getNavigationGroup (line 123) | public function getNavigationGroup(): ?string
method getDateFormat (line 128) | public function getDateFormat(): ?string
method getDatetimeFormat (line 133) | public function getDatetimeFormat(): ?string
method getDatetimeColumnCallback (line 138) | public function getDatetimeColumnCallback(): ?Closure
method getDatePickerCallback (line 143) | public function getDatePickerCallback(): ?Closure
method getTranslateSubject (line 148) | public function getTranslateSubject($label): ?string
method getTranslateLogKey (line 159) | public function getTranslateLogKey($label): ?string
method getDateParser (line 170) | public function getDateParser(): ?Closure
method getNavigationIcon (line 175) | public function getNavigationIcon(): ?string
method getNavigationSort (line 180) | public function getNavigationSort(): ?int
method getNavigationCountBadge (line 185) | public function getNavigationCountBadge(): ?bool
method resource (line 190) | public function resource(string $resource): static
method label (line 197) | public function label(string|Closure $label): static
method resourceActionLabel (line 204) | public function resourceActionLabel(string|Closure $label): static
method isResourceActionHidden (line 211) | public function isResourceActionHidden(bool|Closure $isHidden): static
method isRestoreActionHidden (line 218) | public function isRestoreActionHidden(bool|Closure $isHidden): static
method isRestoreModelActionHidden (line 225) | public function isRestoreModelActionHidden(bool|Closure $isHidden): st...
method pluralLabel (line 232) | public function pluralLabel(string|Closure $label): static
method navigationItem (line 239) | public function navigationItem(Closure|bool $value = true): static
method navigationGroup (line 246) | public function navigationGroup(string|Closure|null $group = null): st...
method dateParser (line 253) | public function dateParser(?Closure $parser = null): static
method dateFormat (line 260) | public function dateFormat(string|Closure|null $format = null): static
method datetimeFormat (line 267) | public function datetimeFormat(string|Closure|null $format = null): st...
method customizeDatetimeColumn (line 274) | public function customizeDatetimeColumn(Closure $callable): self
method customizeDatePicker (line 281) | public function customizeDatePicker(Closure $callable): self
method translateSubject (line 288) | public function translateSubject(string|Closure|null $callable = null)...
method translateLogKey (line 295) | public function translateLogKey(string|Closure|null $callable = null):...
method navigationIcon (line 302) | public function navigationIcon(string $icon): static
method navigationSort (line 309) | public function navigationSort(int $order): static
method navigationCountBadge (line 316) | public function navigationCountBadge(bool $show = true): static
method authorize (line 323) | public function authorize(bool|Closure $callback = true): static
method isAuthorized (line 330) | public function isAuthorized(): bool
FILE: src/ActivitylogServiceProvider.php
class ActivitylogServiceProvider (line 11) | class ActivitylogServiceProvider extends PackageServiceProvider
method configurePackage (line 15) | public function configurePackage(Package $package): void
method packageBooted (line 35) | public function packageBooted(): void
FILE: src/Helpers/ActivityLogHelper.php
class ActivityLogHelper (line 7) | class ActivityLogHelper
method classUsesTrait (line 15) | public static function classUsesTrait($class, $trait): bool
method getResourcePluralName (line 22) | public static function getResourcePluralName($class): string
FILE: src/Infolists/Components/TimeLineIconEntry.php
class TimeLineIconEntry (line 7) | class TimeLineIconEntry extends IconEntry
method setUp (line 9) | protected function setUp(): void
method configureIconEntry (line 18) | protected function configureIconEntry()
FILE: src/Infolists/Components/TimeLinePropertiesEntry.php
class TimeLinePropertiesEntry (line 10) | class TimeLinePropertiesEntry extends Entry
method setup (line 16) | protected function setup(): void
method configurePropertieEntry (line 23) | protected function configurePropertieEntry(): void
method modifiedProperties (line 30) | protected function modifiedProperties($state): ?HtmlString
method getPropertyChanges (line 48) | protected function getPropertyChanges(array $properties): array
method compareOldAndNewValues (line 63) | protected function compareOldAndNewValues(array $oldValues, array $new...
method getNewValues (line 90) | protected function getNewValues(array $newValues): array
method formatNewValue (line 103) | protected function formatNewValue($value): string
FILE: src/Infolists/Components/TimeLineRepeatableEntry.php
class TimeLineRepeatableEntry (line 7) | class TimeLineRepeatableEntry extends RepeatableEntry
method setup (line 9) | protected function setup(): void
method configureRepeatableEntry (line 16) | protected function configureRepeatableEntry(): void
FILE: src/Infolists/Components/TimeLineTitleEntry.php
class TimeLineTitleEntry (line 14) | class TimeLineTitleEntry extends Entry
method setUp (line 24) | protected function setUp(): void
method configureTitleUsing (line 33) | public function configureTitleUsing(?Closure $configureTitleUsing): Ti...
method shouldConfigureTitleUsing (line 40) | public function shouldConfigureTitleUsing(?Closure $condition): TimeLi...
method configureTitleEntry (line 47) | protected function configureTitleEntry()
method modifiedTitle (line 54) | protected function modifiedTitle($state): string|HtmlString|Closure
FILE: src/Infolists/Concerns/HasModifyState.php
type HasModifyState (line 8) | trait HasModifyState
method modifyState (line 12) | public function modifyState(Closure $callback): static
method getModifiedState (line 19) | public function getModifiedState(): null|string|HtmlString
method getCauserName (line 24) | protected function getCauserName($causer): string
FILE: src/RelationManagers/ActivitylogRelationManager.php
class ActivitylogRelationManager (line 13) | class ActivitylogRelationManager extends RelationManager
method getTitle (line 19) | public static function getTitle(Model $ownerRecord, string $pageClass)...
method form (line 27) | public function form(Form $form): Form
method table (line 32) | public function table(Table $table): Table
FILE: src/Resources/ActivitylogResource/ActivitylogResource.php
class ActivitylogResource (line 36) | class ActivitylogResource extends Resource
method getModel (line 42) | public static function getModel(): string
method getModelLabel (line 47) | public static function getModelLabel(): string
method getPluralModelLabel (line 52) | public static function getPluralModelLabel(): string
method getNavigationIcon (line 57) | public static function getNavigationIcon(): string
method getNavigationLabel (line 62) | public static function getNavigationLabel(): string
method getNavigationSort (line 67) | public static function getNavigationSort(): ?int
method getNavigationGroup (line 72) | public static function getNavigationGroup(): ?string
method getNavigationBadge (line 77) | public static function getNavigationBadge(): ?string
method getResourceUrl (line 83) | protected static function getResourceUrl(Activity $record): string
method form (line 111) | public static function form(Schema $schema): Schema
method flattenArrayForKeyValue (line 116) | protected static function flattenArrayForKeyValue(array $data): array
method table (line 131) | public static function table(Table $table): Table
method getEloquentQuery (line 153) | public static function getEloquentQuery(): Builder
method getLogNameColumnComponent (line 166) | public static function getLogNameColumnComponent(): Column
method getEventColumnComponent (line 176) | public static function getEventColumnComponent(): Column
method getSubjectTypeColumnComponent (line 194) | public static function getSubjectTypeColumnComponent(): Column
method getCauserNameColumnComponent (line 220) | public static function getCauserNameColumnComponent(): Column
method getPropertiesColumnComponent (line 235) | public static function getPropertiesColumnComponent(): Column
method getCreatedAtColumnComponent (line 244) | public static function getCreatedAtColumnComponent(): Column
method getDatePickerCompoment (line 262) | public static function getDatePickerCompoment(string $label): DatePicker
method getDateFilterComponent (line 278) | public static function getDateFilterComponent(): Filter
method getEventFilterComponent (line 319) | public static function getEventFilterComponent(): SelectFilter
method getLogNameFilterComponent (line 329) | public static function getLogNameFilterComponent(): SelectFilter
method getPages (line 336) | public static function getPages(): array
method shouldRegisterNavigation (line 344) | public static function shouldRegisterNavigation(): bool
method canAccess (line 351) | public static function canAccess(): bool
method canViewResource (line 362) | protected static function canViewResource(Activity $record): bool
method restoreActivity (line 387) | public static function restoreActivity(int|string $key): void
method canRestoreSubjectFromSoftDelete (line 460) | public static function canRestoreSubjectFromSoftDelete(Activity $recor...
method restoreSubjectFromSoftDelete (line 496) | public static function restoreSubjectFromSoftDelete(Activity $record):...
FILE: src/Resources/ActivitylogResource/Pages/ListActivitylog.php
class ListActivitylog (line 8) | class ListActivitylog extends ListRecords
FILE: src/Resources/ActivitylogResource/Pages/ViewActivitylog.php
class ViewActivitylog (line 8) | class ViewActivitylog extends ViewRecord
method getResource (line 10) | public static function getResource(): string
FILE: src/Resources/ActivitylogResource/Schemas/ActivitylogForm.php
class ActivitylogForm (line 11) | class ActivitylogForm
method configure (line 13) | public static function configure(Schema $schema): Schema
FILE: src/Traits/HasCustomActivityResource.php
type HasCustomActivityResource (line 7) | trait HasCustomActivityResource
method getFilamentActualResourceModel (line 14) | public function getFilamentActualResourceModel($record): Model
Condensed preview — 107 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (148K chars).
[
{
"path": ".editorconfig",
"chars": 220,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\ntrim_"
},
{
"path": ".gitattributes",
"chars": 705,
"preview": "# Path-based git attributes\n# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html\n\n# Ignore all test and"
},
{
"path": ".github/ISSUE_TEMPLATE/bug.yml",
"chars": 2816,
"preview": "name: Bug report\ndescription: Report a problem you're experiencing\nlabels: bug,unconfirmed\nbody:\n - type: markdown\n "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 484,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Ask a question\n url: https://github.com/Rmsramos/activitylog/dis"
},
{
"path": ".github/workflows/fix-php-code-style-issues.yml",
"chars": 512,
"preview": "name: Fix PHP code style issues\n\non:\n push:\n paths:\n - '**.php'\n\npermissions:\n contents: write\n\njobs:\n php-co"
},
{
"path": ".gitignore",
"chars": 115,
"preview": ".idea\n.phpunit.cache\nbuild\ncomposer.lock\ncoverage\ndocs\nphpunit.xml\nphpstan.neon\ntestbench.yaml\nvendor\nnode_modules\n"
},
{
"path": "LICENSE.md",
"chars": 1091,
"preview": "The MIT License (MIT)\n\nCopyright (c) Rmsramos <rmsramos@gmail.com>\n\nPermission is hereby granted, free of charge, to any"
},
{
"path": "README.md",
"chars": 19879,
"preview": "# ActivityLog\n\n### Spatie/Laravel-activitylog for Filament\n\n[~:not([hidden]){border-style:"
},
{
"path": "resources/lang/ar/action.php",
"chars": 185,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'سجل نشاط المستخدم',\n 'description' => 'تتبع جميع أنشطة"
},
{
"path": "resources/lang/ar/forms.php",
"chars": 667,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'النوع',\n ],\n 'event' => "
},
{
"path": "resources/lang/ar/tables.php",
"chars": 743,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'النوع',\n ],\n 'event' =>"
},
{
"path": "resources/lang/ar/timeline.php",
"chars": 535,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'تم تعديل <strong>%s</strong> بواسطة <strong>%s</strong>. <br"
},
{
"path": "resources/lang/de/action.php",
"chars": 246,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'User Aktivitäten Log',\n 'description' => 'Tracke alle "
},
{
"path": "resources/lang/de/forms.php",
"chars": 671,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Typ',\n ],\n 'event' => [\n"
},
{
"path": "resources/lang/de/tables.php",
"chars": 737,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Typ',\n ],\n 'event' => ["
},
{
"path": "resources/lang/de/timeline.php",
"chars": 532,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => '<strong>%s</strong> wurde <strong>%s</strong> von <strong>%s"
},
{
"path": "resources/lang/en/action.php",
"chars": 694,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'User Activity Log',\n 'description' => 'Track all user "
},
{
"path": "resources/lang/en/forms.php",
"chars": 690,
"preview": "<?php\n\nreturn [\n 'changes' => 'Changes',\n 'fields' => [\n 'log_name' => [\n 'label' => 'Type',\n "
},
{
"path": "resources/lang/en/infolists.php",
"chars": 562,
"preview": "<?php\n\nreturn [\n 'components' => [\n 'created_by_at' => 'The <strong>:subject</strong> was <strong>"
},
{
"path": "resources/lang/en/notifications.php",
"chars": 578,
"preview": "<?php\n\nreturn [\n 'no_properties_to_restore' => 'No properties to restore.',\n 'activity_restored' "
},
{
"path": "resources/lang/en/tables.php",
"chars": 1077,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Type',\n ],\n 'event' => "
},
{
"path": "resources/lang/en/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/es/action.php",
"chars": 775,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Registro de actividad de usuario',\n 'description' => '"
},
{
"path": "resources/lang/es/forms.php",
"chars": 705,
"preview": "<?php\n\nreturn [\n 'changes' => 'Cambios',\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tipo',\n "
},
{
"path": "resources/lang/es/infolists.php",
"chars": 566,
"preview": "<?php\n\nreturn [\n 'components' => [\n 'created_by_at' => 'El <strong>:subject</strong> fue <strong>:"
},
{
"path": "resources/lang/es/notifications.php",
"chars": 605,
"preview": "<?php\n\nreturn [\n 'no_properties_to_restore' => 'No hay propiedades para restaurar.',\n 'activity_restored' "
},
{
"path": "resources/lang/es/tables.php",
"chars": 1018,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => "
},
{
"path": "resources/lang/es/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'El <strong>%s</strong> fue <strong>%s</strong> por <strong>%"
},
{
"path": "resources/lang/fa/action.php",
"chars": 437,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'سیاههفعالیتکاربر',\n 'description' => 'ردیابی تمام فع"
},
{
"path": "resources/lang/fa/forms.php",
"chars": 703,
"preview": "<?php\n\nreturn [\n 'changes' => 'تغییرات',\n 'fields' => [\n 'log_name' => [\n 'label' => 'نوع',\n "
},
{
"path": "resources/lang/fa/infolists.php",
"chars": 596,
"preview": "<?php\n\nreturn [\n 'components' => [\n 'created_by_at' => '<strong>:subject</strong> توسط <strong>:ca"
},
{
"path": "resources/lang/fa/notifications.php",
"chars": 320,
"preview": "<?php\n\nreturn [\n 'no_properties_to_restore' => 'مقادیری برای بازگردانی وجود ندارد.',\n 'activity_restored' "
},
{
"path": "resources/lang/fa/tables.php",
"chars": 926,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'نوع',\n ],\n 'event' => ["
},
{
"path": "resources/lang/fa/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/fr/action.php",
"chars": 236,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Journal d\\'activité des utilisateurs',\n 'description' "
},
{
"path": "resources/lang/fr/forms.php",
"chars": 679,
"preview": "<?php\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Type',\n ],\n 'event' => [\n"
},
{
"path": "resources/lang/fr/tables.php",
"chars": 749,
"preview": "<?php\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Type',\n ],\n 'event' => ["
},
{
"path": "resources/lang/fr/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/he/action.php",
"chars": 184,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'יומן פעילות משתמש',\n 'description' => 'הצגת כל פעילויו"
},
{
"path": "resources/lang/he/forms.php",
"chars": 645,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'סוג',\n ],\n 'event' => [\n"
},
{
"path": "resources/lang/he/tables.php",
"chars": 698,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'סוג',\n ],\n 'event' => ["
},
{
"path": "resources/lang/he/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/id/action.php",
"chars": 200,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Log Aktivitas Pengguna',\n 'description' => 'Lacak semu"
},
{
"path": "resources/lang/id/forms.php",
"chars": 666,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Jenis',\n ],\n 'event' => "
},
{
"path": "resources/lang/id/tables.php",
"chars": 732,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Jenis',\n ],\n 'event' =>"
},
{
"path": "resources/lang/id/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/it/action.php",
"chars": 208,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Log Attività Utente',\n 'description' => 'Traccia tutte"
},
{
"path": "resources/lang/it/forms.php",
"chars": 671,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => ["
},
{
"path": "resources/lang/it/tables.php",
"chars": 731,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => "
},
{
"path": "resources/lang/it/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/lv/action.php",
"chars": 212,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Lietotāju darbību žurnāls',\n 'description' => 'Sekojie"
},
{
"path": "resources/lang/lv/forms.php",
"chars": 668,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tips',\n ],\n 'event' => ["
},
{
"path": "resources/lang/lv/tables.php",
"chars": 739,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tips',\n ],\n 'event' => "
},
{
"path": "resources/lang/lv/timeline.php",
"chars": 532,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => '<strong>%s</strong> tika <strong>%s</strong> ar lietotāju <s"
},
{
"path": "resources/lang/nl/action.php",
"chars": 208,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Gebruikersctiviteiten Log',\n 'description' => 'Volg al"
},
{
"path": "resources/lang/nl/forms.php",
"chars": 667,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Type',\n ],\n 'event' => ["
},
{
"path": "resources/lang/nl/tables.php",
"chars": 733,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Type',\n ],\n 'event' => "
},
{
"path": "resources/lang/nl/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'De <strong>%s</strong> is <strong>%s</strong> door <strong>%"
},
{
"path": "resources/lang/pl/action.php",
"chars": 193,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Dziennik zdarzeń',\n 'description' => 'Sprawdź historię"
},
{
"path": "resources/lang/pl/forms.php",
"chars": 685,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Typ',\n ],\n 'event' => [\n"
},
{
"path": "resources/lang/pl/tables.php",
"chars": 750,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Typ',\n ],\n 'event' => ["
},
{
"path": "resources/lang/pl/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/pt_BR/action.php",
"chars": 747,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Registro de Logs do usuário',\n 'description' => 'Acomp"
},
{
"path": "resources/lang/pt_BR/forms.php",
"chars": 700,
"preview": "<?php\n\nreturn [\n 'changes' => 'Mudanças',\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tipo',\n "
},
{
"path": "resources/lang/pt_BR/infolists.php",
"chars": 566,
"preview": "<?php\n\nreturn [\n 'components' => [\n 'created_by_at' => 'O <strong>:subject</strong> foi <strong>:e"
},
{
"path": "resources/lang/pt_BR/notifications.php",
"chars": 612,
"preview": "<?php\n\nreturn [\n 'no_properties_to_restore' => 'Nenhuma propriedade para restaurar.',\n 'activity_restored' "
},
{
"path": "resources/lang/pt_BR/tables.php",
"chars": 1022,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => "
},
{
"path": "resources/lang/pt_BR/timeline.php",
"chars": 533,
"preview": "<?php\n\nreturn [\n 'title' => [\n 'modifiedTitle' => 'O <strong>%s</strong> foi <strong>%s</strong> por <strong>%"
},
{
"path": "resources/lang/pt_PT/action.php",
"chars": 228,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Registro de Logs do utilizador',\n 'description' => 'Ac"
},
{
"path": "resources/lang/pt_PT/forms.php",
"chars": 673,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => ["
},
{
"path": "resources/lang/pt_PT/tables.php",
"chars": 741,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tipo',\n ],\n 'event' => "
},
{
"path": "resources/lang/pt_PT/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/lang/tr/action.php",
"chars": 217,
"preview": "<?php\n\nreturn [\n 'modal' => [\n 'heading' => 'Kullanıcı Aktivite Günlüğü',\n 'description' => 'Tüm ku"
},
{
"path": "resources/lang/tr/forms.php",
"chars": 663,
"preview": "<?php\n\nreturn [\n 'fields' => [\n 'log_name' => [\n 'label' => 'Tip',\n ],\n 'event' => [\n"
},
{
"path": "resources/lang/tr/tables.php",
"chars": 737,
"preview": "<?php\n\nreturn [\n 'columns' => [\n 'log_name' => [\n 'label' => 'Tip',\n ],\n 'event' => ["
},
{
"path": "resources/lang/tr/timeline.php",
"chars": 533,
"preview": "<?php\nreturn [\n 'title' => [\n 'modifiedTitle' => 'The <strong>%s</strong> was <strong>%s</strong> by <strong>%"
},
{
"path": "resources/views/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "resources/views/filament/infolists/components/time-line-icon-entry.blade.php",
"chars": 2734,
"preview": "@php\n use Filament\\Infolists\\Components\\IconEntry\\IconEntrySize;\n@endphp\n\n<x-dynamic-component :component=\"$getEntryW"
},
{
"path": "resources/views/filament/infolists/components/time-line-propertie-entry.blade.php",
"chars": 224,
"preview": "<x-dynamic-component :component=\"$getEntryWrapperView()\" :entry=\"$entry\">\n <div>\n\n {{ $getModifiedState() ?? ("
},
{
"path": "resources/views/filament/infolists/components/time-line-repeatable-entry.blade.php",
"chars": 1893,
"preview": "@php\n $isContained = $isContained();\n@endphp\n\n<x-dynamic-component :component=\"$getEntryWrapperView()\" :entry=\"$entry"
},
{
"path": "resources/views/filament/infolists/components/time-line-title-entry.blade.php",
"chars": 320,
"preview": "<x-dynamic-component :component=\"$getEntryWrapperView()\" :entry=\"$entry\">\n <div\n {{\n $attributes\n "
},
{
"path": "resources/views/filament/tables/columns/activity-logs-properties.blade.php",
"chars": 823,
"preview": "<div class=\"my-2 text-sm tracking-tight\">\n @foreach($getState() ?? [] as $key => $value)\n <span class=\"inline-"
},
{
"path": "src/Actions/ActivityLogTimelineSimpleAction.php",
"chars": 215,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Actions;\n\nuse Filament\\Actions\\Action;\nuse Rmsramos\\Activitylog\\Actions\\Concerns\\A"
},
{
"path": "src/Actions/ActivityLogTimelineTableAction.php",
"chars": 221,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Actions;\n\nuse Filament\\Tables\\Actions\\Action;\nuse Rmsramos\\Activitylog\\Actions\\Con"
},
{
"path": "src/Actions/Concerns/ActionContent.php",
"chars": 12138,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Actions\\Concerns;\n\nuse Carbon\\Exceptions\\InvalidFormatException;\nuse Closure;\nuse "
},
{
"path": "src/ActivitylogPlugin.php",
"chars": 8183,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog;\n\nuse Closure;\nuse Filament\\Contracts\\Plugin;\nuse Filament\\Panel;\nuse Filament\\Sup"
},
{
"path": "src/ActivitylogServiceProvider.php",
"chars": 1469,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog;\n\nuse Filament\\Support\\Assets\\Css;\nuse Filament\\Support\\Facades\\FilamentAsset;\nuse"
},
{
"path": "src/Helpers/ActivityLogHelper.php",
"chars": 636,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Helpers;\n\nuse Illuminate\\Support\\Str;\n\nclass ActivityLogHelper\n{\n /**\n * Ch"
},
{
"path": "src/Infolists/Components/TimeLineIconEntry.php",
"chars": 492,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Infolists\\Components;\n\nuse Filament\\Infolists\\Components\\IconEntry;\n\nclass TimeLin"
},
{
"path": "src/Infolists/Components/TimeLinePropertiesEntry.php",
"chars": 3600,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Infolists\\Components;\n\nuse Filament\\Infolists\\Components\\Entry;\nuse Illuminate\\Sup"
},
{
"path": "src/Infolists/Components/TimeLineRepeatableEntry.php",
"chars": 602,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Infolists\\Components;\n\nuse Filament\\Infolists\\Components\\RepeatableEntry;\n\nclass T"
},
{
"path": "src/Infolists/Components/TimeLineTitleEntry.php",
"chars": 2867,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Infolists\\Components;\n\nuse Closure;\nuse Filament\\Forms\\Components\\Concerns\\CanAllo"
},
{
"path": "src/Infolists/Concerns/HasModifyState.php",
"chars": 623,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Infolists\\Concerns;\n\nuse Closure;\nuse Illuminate\\Support\\HtmlString;\n\ntrait HasMod"
},
{
"path": "src/RelationManagers/ActivitylogRelationManager.php",
"chars": 1196,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\RelationManagers;\n\nuse Filament\\Forms\\Form;\nuse Filament\\Resources\\RelationManager"
},
{
"path": "src/Resources/ActivitylogResource/ActivitylogResource.php",
"chars": 18976,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Resources\\ActivitylogResource;\n\nuse ActivitylogForm;\nuse Exception;\nuse Filament\\F"
},
{
"path": "src/Resources/ActivitylogResource/Pages/ListActivitylog.php",
"chars": 289,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Resources\\ActivitylogResource\\Pages;\n\nuse Filament\\Resources\\Pages\\ListRecords;\nus"
},
{
"path": "src/Resources/ActivitylogResource/Pages/ViewActivitylog.php",
"chars": 323,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Resources\\ActivitylogResource\\Pages;\n\nuse Filament\\Resources\\Pages\\ViewRecord;\nuse"
},
{
"path": "src/Resources/ActivitylogResource/Schemas/ActivitylogForm.php",
"chars": 2997,
"preview": "<?php\n\nuse Filament\\Forms\\Components\\Textarea;\nuse Filament\\Forms\\Components\\TextInput;\nuse Filament\\Infolists\\Component"
},
{
"path": "src/Traits/HasCustomActivityResource.php",
"chars": 380,
"preview": "<?php\n\nnamespace Rmsramos\\Activitylog\\Traits;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ntrait HasCustomActivityResource\n"
},
{
"path": "tailwind.config.js",
"chars": 186,
"preview": "/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n darkMode: 'class',\n content: [\n \"./resources/**/*.b"
}
]
About this extraction
This page contains the full source code of the rmsramos/activitylog GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 107 files (131.3 KB), approximately 34.3k tokens, and a symbol index with 146 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.