Skip to content

Commit 4e41f1f

Browse files
committed
add audit logging 🥸
1 parent ed4fd3c commit 4e41f1f

24 files changed

+901
-1
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\AuditLogs;
6+
7+
use App\Filament\Resources\AuditLogs\Pages\ListAuditLogs;
8+
use App\Filament\Resources\AuditLogs\Pages\ViewAuditLog;
9+
use App\Filament\Resources\AuditLogs\Schemas\AuditLogInfolist;
10+
use App\Filament\Resources\AuditLogs\Tables\AuditLogsTable;
11+
use App\Models\AuditLog;
12+
use BackedEnum;
13+
use Filament\Resources\Resource;
14+
use Filament\Schemas\Schema;
15+
use Filament\Support\Icons\Heroicon;
16+
use Filament\Tables\Table;
17+
18+
class AuditLogResource extends Resource
19+
{
20+
protected static ?string $model = AuditLog::class;
21+
22+
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedTableCells;
23+
24+
protected static ?string $recordTitleAttribute = 'action';
25+
26+
protected static ?string $navigationLabel = 'Audit Logs';
27+
28+
protected static ?string $modelLabel = 'Audit Log';
29+
30+
protected static ?string $pluralModelLabel = 'Audit Logs';
31+
32+
protected static ?int $navigationSort = 100;
33+
34+
public static function infolist(Schema $schema): Schema
35+
{
36+
return AuditLogInfolist::configure($schema);
37+
}
38+
39+
public static function table(Table $table): Table
40+
{
41+
return AuditLogsTable::configure($table);
42+
}
43+
44+
public static function getRelations(): array
45+
{
46+
return [
47+
//
48+
];
49+
}
50+
51+
public static function getPages(): array
52+
{
53+
return [
54+
'index' => ListAuditLogs::route('/'),
55+
'view' => ViewAuditLog::route('/{record}'),
56+
];
57+
}
58+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\AuditLogs\Pages;
6+
7+
use App\Filament\Resources\AuditLogs\AuditLogResource;
8+
use Filament\Resources\Pages\ListRecords;
9+
10+
class ListAuditLogs extends ListRecords
11+
{
12+
protected static string $resource = AuditLogResource::class;
13+
14+
protected function getHeaderActions(): array
15+
{
16+
return [
17+
//
18+
];
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\AuditLogs\Pages;
6+
7+
use App\Filament\Resources\AuditLogs\AuditLogResource;
8+
use Filament\Resources\Pages\ViewRecord;
9+
10+
class ViewAuditLog extends ViewRecord
11+
{
12+
protected static string $resource = AuditLogResource::class;
13+
14+
protected function getHeaderActions(): array
15+
{
16+
return [
17+
//
18+
];
19+
}
20+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\AuditLogs\Schemas;
6+
7+
use Filament\Infolists\Components\TextEntry;
8+
use Filament\Schemas\Components\Section;
9+
use Filament\Schemas\Schema;
10+
11+
class AuditLogInfolist
12+
{
13+
public static function configure(Schema $schema): Schema
14+
{
15+
return $schema
16+
->components([
17+
Section::make('Audit Log Details')
18+
->schema([
19+
TextEntry::make('created_at')
20+
->label('Timestamp')
21+
->dateTime(),
22+
TextEntry::make('user.name')
23+
->label('User')
24+
->placeholder('System'),
25+
TextEntry::make('action')
26+
->badge()
27+
->color(fn (string $state): string => match ($state) {
28+
'create' => 'success',
29+
'update' => 'warning',
30+
'delete' => 'danger',
31+
'deploy' => 'info',
32+
'prepare' => 'primary',
33+
'create_zip' => 'secondary',
34+
default => 'secondary',
35+
}),
36+
TextEntry::make('model_type')
37+
->label('Entity Type')
38+
->formatStateUsing(fn (string $state): string => class_basename($state)),
39+
TextEntry::make('model_id')
40+
->label('Entity ID'),
41+
TextEntry::make('ip_address')
42+
->label('IP Address')
43+
->placeholder('-'),
44+
TextEntry::make('user_agent')
45+
->label('User Agent')
46+
->placeholder('-')
47+
->columnSpanFull(),
48+
]),
49+
Section::make('Changes')
50+
->schema([
51+
TextEntry::make('old_values')
52+
->label('Previous Values')
53+
->placeholder('No previous values')
54+
->formatStateUsing(fn ($state) => $state ? json_encode($state, JSON_PRETTY_PRINT) : null)
55+
->columnSpanFull()
56+
->copyable(),
57+
TextEntry::make('new_values')
58+
->label('New Values')
59+
->placeholder('No new values')
60+
->formatStateUsing(fn ($state) => $state ? json_encode($state, JSON_PRETTY_PRINT) : null)
61+
->columnSpanFull()
62+
->copyable(),
63+
])
64+
->collapsible()
65+
->collapsed(),
66+
]);
67+
}
68+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\AuditLogs\Tables;
6+
7+
use Filament\Actions\ViewAction;
8+
use Filament\Tables\Columns\TextColumn;
9+
use Filament\Tables\Table;
10+
11+
class AuditLogsTable
12+
{
13+
public static function configure(Table $table): Table
14+
{
15+
return $table
16+
->columns([
17+
TextColumn::make('created_at')
18+
->label('Timestamp')
19+
->dateTime()
20+
->sortable()
21+
->toggleable(),
22+
TextColumn::make('user.name')
23+
->label('User')
24+
->searchable()
25+
->placeholder('System'),
26+
TextColumn::make('action')
27+
->badge()
28+
->color(fn (string $state): string => match ($state) {
29+
'create' => 'success',
30+
'update' => 'warning',
31+
'delete' => 'danger',
32+
'deploy' => 'info',
33+
'prepare' => 'primary',
34+
'create_zip' => 'secondary',
35+
default => 'secondary',
36+
})
37+
->searchable(),
38+
TextColumn::make('model_type')
39+
->label('Entity')
40+
->formatStateUsing(fn (string $state): string => class_basename($state))
41+
->searchable(),
42+
TextColumn::make('model_id')
43+
->label('Entity ID')
44+
->numeric()
45+
->sortable(),
46+
TextColumn::make('ip_address')
47+
->label('IP Address')
48+
->searchable()
49+
->toggleable(isToggledHiddenByDefault: true),
50+
])
51+
->filters([
52+
//
53+
])
54+
->recordActions([
55+
ViewAction::make(),
56+
])
57+
->defaultSort('created_at', 'desc');
58+
}
59+
}

app/Filament/Resources/FileChanges/FileChangeResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class FileChangeResource extends Resource
2222

2323
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedQueueList;
2424

25+
protected static ?int $navigationSort = 20;
26+
2527
public static function form(Schema $schema): Schema
2628
{
2729
return FileChangeForm::configure($schema);

app/Filament/Resources/OverrideRules/OverrideRuleResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class OverrideRuleResource extends Resource
2222

2323
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedSwatch;
2424

25+
protected static ?int $navigationSort = 30;
26+
2527
public static function form(Schema $schema): Schema
2628
{
2729
return OverrideRuleForm::configure($schema);

app/Filament/Resources/Releases/ReleaseResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class ReleaseResource extends Resource
3434

3535
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRocketLaunch;
3636

37+
protected static ?int $navigationSort = 10;
38+
3739
public static function log(Release $release, string $message, string $level = 'info'): void
3840
{
3941
$release->logs()->create([

app/Filament/Resources/Servers/ServerResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class ServerResource extends Resource
2222

2323
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedServerStack;
2424

25+
protected static ?int $navigationSort = 50;
26+
2527
public static function form(Schema $schema): Schema
2628
{
2729
return ServerForm::configure($schema);

app/Filament/Resources/Users/UserResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class UserResource extends Resource
2222

2323
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedUsers;
2424

25+
protected static ?int $navigationSort = 90;
26+
2527
public static function form(Schema $schema): Schema
2628
{
2729
return UserForm::configure($schema);

0 commit comments

Comments
 (0)