Implement superadmin audit log for mutations
This commit is contained in:
@@ -6,6 +6,7 @@ use App\Filament\Blog\Resources\CategoryResource\Pages;
|
||||
use App\Filament\Blog\Traits\HasContentEditor;
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Models\BlogCategory;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
@@ -24,6 +25,7 @@ use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -116,38 +118,25 @@ class CategoryResource extends Resource
|
||||
$data['description_de'] = $descArray['de'] ?? '';
|
||||
$data['description_en'] = $descArray['en'] ?? '';
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('BeforeFill Description Extraction:', [
|
||||
'descJson' => $descJson,
|
||||
'descArray' => $descArray,
|
||||
'description_de' => $data['description_de'],
|
||||
'description_en' => $data['description_en'],
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
\Illuminate\Support\Facades\Log::info('mutateFormDataBeforeCreate Input Data:', ['data' => $data]);
|
||||
|
||||
$nameData = [
|
||||
'de' => $data['name_de'] ?? '',
|
||||
'en' => $data['name_en'] ?? '',
|
||||
];
|
||||
$data['name'] = json_encode($nameData);
|
||||
\Illuminate\Support\Facades\Log::info('mutateFormDataBeforeCreate Name JSON:', ['name' => $nameData]);
|
||||
|
||||
$descData = [
|
||||
'de' => $data['description_de'] ?? '',
|
||||
'en' => $data['description_en'] ?? '',
|
||||
];
|
||||
$data['description'] = json_encode($descData);
|
||||
\Illuminate\Support\Facades\Log::info('mutateFormDataBeforeCreate Description JSON:', ['description' => $descData]);
|
||||
|
||||
unset($data['name_de'], $data['name_en'], $data['description_de'], $data['description_en']);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('mutateFormDataBeforeCreate Final Data:', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -185,11 +174,28 @@ class CategoryResource extends Resource
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, BlogCategory $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Blog\Resources\CategoryResource\Pages;
|
||||
|
||||
use App\Filament\Blog\Resources\CategoryResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreateCategory extends CreateRecord
|
||||
class CreateCategory extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = CategoryResource::class;
|
||||
|
||||
@@ -30,4 +30,4 @@ class CreateCategory extends CreateRecord
|
||||
|
||||
$this->record = static::getResource()::getModel()::create($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,23 @@
|
||||
namespace App\Filament\Blog\Resources\CategoryResource\Pages;
|
||||
|
||||
use App\Filament\Blog\Resources\CategoryResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditCategory extends EditRecord
|
||||
class EditCategory extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = CategoryResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -24,7 +30,7 @@ class EditCategory extends EditRecord
|
||||
'description_de' => 'nullable|string',
|
||||
'name_en' => 'nullable|string|max:255',
|
||||
'description_en' => 'nullable|string',
|
||||
'slug' => 'required|string|max:255|unique:blog_categories,slug,' . $this->record->id,
|
||||
'slug' => 'required|string|max:255|unique:blog_categories,slug,'.$this->record->id,
|
||||
'is_visible' => 'boolean',
|
||||
];
|
||||
}
|
||||
@@ -40,12 +46,13 @@ class EditCategory extends EditRecord
|
||||
public function save(bool $shouldRedirect = true, bool $shouldSendSavedNotification = true): void
|
||||
{
|
||||
$state = $this->form->getState();
|
||||
\Illuminate\Support\Facades\Log::info('EditCategory Save - Full State:', $state);
|
||||
|
||||
$data = $state['data'] ?? $state;
|
||||
|
||||
$data = \App\Filament\Blog\Resources\CategoryResource::mutateFormDataBeforeSave($data);
|
||||
|
||||
$this->record->update($data);
|
||||
|
||||
parent::afterSave();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Filament\Blog\Traits\HasContentEditor;
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Models\BlogCategory;
|
||||
use App\Models\BlogPost;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
@@ -29,6 +30,7 @@ use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -243,11 +245,27 @@ class PostResource extends Resource
|
||||
->actions([
|
||||
DeleteAction::make()
|
||||
->icon('heroicon-o-trash')
|
||||
->label(''),
|
||||
->label('')
|
||||
->after(fn (BlogPost $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Blog\Resources\PostResource\Pages;
|
||||
|
||||
use App\Filament\Blog\Resources\PostResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreatePost extends CreateRecord
|
||||
class CreatePost extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = PostResource::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
namespace App\Filament\Blog\Resources\PostResource\Pages;
|
||||
|
||||
use App\Filament\Blog\Resources\PostResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPost extends EditRecord
|
||||
class EditPost extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PostResource::class;
|
||||
|
||||
@@ -14,7 +15,12 @@ class EditPost extends EditRecord
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
namespace App\Filament\Clusters\DailyOps\Resources\Photos\Pages;
|
||||
|
||||
use App\Filament\Clusters\DailyOps\Resources\Photos\PhotoResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPhoto extends EditRecord
|
||||
class EditPhoto extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PhotoResource::class;
|
||||
|
||||
@@ -15,7 +16,12 @@ class EditPhoto extends EditRecord
|
||||
{
|
||||
return [
|
||||
ViewAction::make(),
|
||||
DeleteAction::make(),
|
||||
DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Clusters\DailyOps\Resources\Photos\Tables;
|
||||
use App\Models\Event;
|
||||
use App\Models\Photo;
|
||||
use App\Models\Tenant;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -208,6 +209,18 @@ class PhotosTable
|
||||
'moderated_at' => now(),
|
||||
'moderated_by' => Filament::auth()->id(),
|
||||
]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'photo.'.$status,
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'status',
|
||||
'moderation_notes',
|
||||
'moderated_at',
|
||||
'moderated_by',
|
||||
]),
|
||||
source: self::class
|
||||
);
|
||||
}
|
||||
|
||||
private static function applyModerationToRecords(Collection $records, string $status, ?string $notes): int
|
||||
@@ -215,7 +228,7 @@ class PhotosTable
|
||||
$moderatedAt = now();
|
||||
$moderatedBy = Filament::auth()->id();
|
||||
|
||||
return Photo::query()
|
||||
$updated = Photo::query()
|
||||
->whereIn('id', $records->pluck('id'))
|
||||
->where('status', 'pending')
|
||||
->update([
|
||||
@@ -224,6 +237,24 @@ class PhotosTable
|
||||
'moderated_at' => $moderatedAt,
|
||||
'moderated_by' => $moderatedBy,
|
||||
]);
|
||||
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->record(
|
||||
'photo.'.$status,
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'status',
|
||||
'moderation_notes',
|
||||
'moderated_at',
|
||||
'moderated_by',
|
||||
]),
|
||||
source: self::class
|
||||
);
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
private static function statusLabels(): array
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\RareAdmin\Resources\SuperAdminActionLogs\Pages;
|
||||
|
||||
use App\Filament\Clusters\RareAdmin\Resources\SuperAdminActionLogs\SuperAdminActionLogResource;
|
||||
use Filament\Resources\Pages\ManageRecords;
|
||||
|
||||
class ManageSuperAdminActionLogs extends ManageRecords
|
||||
{
|
||||
protected static string $resource = SuperAdminActionLogResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\RareAdmin\Resources\SuperAdminActionLogs;
|
||||
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Filament\Clusters\RareAdmin\Resources\SuperAdminActionLogs\Pages\ManageSuperAdminActionLogs;
|
||||
use App\Models\SuperAdminActionLog;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use UnitEnum;
|
||||
|
||||
class SuperAdminActionLogResource extends Resource
|
||||
{
|
||||
protected static ?string $model = SuperAdminActionLog::class;
|
||||
|
||||
protected static ?string $cluster = RareAdminCluster::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedClipboardDocumentList;
|
||||
|
||||
protected static ?int $navigationSort = 95;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'action';
|
||||
|
||||
public static function getNavigationGroup(): UnitEnum|string|null
|
||||
{
|
||||
return __('admin.nav.infrastructure');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Audit log';
|
||||
}
|
||||
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canEdit($record): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canDelete($record): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canDeleteAny(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
//
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('action')
|
||||
->columns([
|
||||
TextColumn::make('action')
|
||||
->badge()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('actor.fullName')
|
||||
->label('Actor')
|
||||
->sortable()
|
||||
->searchable(),
|
||||
TextColumn::make('subject_type')
|
||||
->label('Subject')
|
||||
->formatStateUsing(fn (?string $state) => $state ? class_basename($state) : '—')
|
||||
->searchable()
|
||||
->toggleable(),
|
||||
TextColumn::make('subject_id')
|
||||
->label('Subject ID')
|
||||
->sortable()
|
||||
->toggleable(),
|
||||
TextColumn::make('metadata')
|
||||
->label('Fields')
|
||||
->formatStateUsing(function ($state): string {
|
||||
if (! is_array($state)) {
|
||||
return '—';
|
||||
}
|
||||
|
||||
$fields = $state['fields'] ?? [];
|
||||
|
||||
return $fields ? implode(', ', $fields) : '—';
|
||||
})
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
->wrap(),
|
||||
TextColumn::make('source')
|
||||
->label('Source')
|
||||
->limit(40)
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
TextColumn::make('occurred_at')
|
||||
->label('Timestamp')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([])
|
||||
->toolbarActions([]);
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ManageSuperAdminActionLogs::route('/'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,17 @@
|
||||
namespace App\Filament\Resources\Coupons\Pages;
|
||||
|
||||
use App\Filament\Resources\Coupons\CouponResource;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateCoupon extends CreateRecord
|
||||
class CreateCoupon extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = CouponResource::class;
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
parent::afterCreate();
|
||||
|
||||
SyncCouponToPaddle::dispatch($this->record);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
namespace App\Filament\Resources\Coupons\Pages;
|
||||
|
||||
use App\Filament\Resources\Coupons\CouponResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditCoupon extends EditRecord
|
||||
class EditCoupon extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = CouponResource::class;
|
||||
|
||||
@@ -19,14 +20,34 @@ class EditCoupon extends EditRecord
|
||||
return [
|
||||
ViewAction::make(),
|
||||
DeleteAction::make()
|
||||
->after(fn ($record) => SyncCouponToPaddle::dispatch($record, true)),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
->after(function ($record): void {
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
|
||||
SyncCouponToPaddle::dispatch($record, true);
|
||||
}),
|
||||
ForceDeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'force_deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
RestoreAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'restored',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
parent::afterSave();
|
||||
|
||||
SyncCouponToPaddle::dispatch($this->record);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\Coupons\Pages;
|
||||
|
||||
use App\Filament\Resources\Coupons\CouponResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,7 +14,13 @@ class ViewCoupon extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources\Coupons\Tables;
|
||||
use App\Enums\CouponStatus;
|
||||
use App\Enums\CouponType;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
@@ -18,6 +19,7 @@ use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CouponsTable
|
||||
@@ -95,7 +97,13 @@ class CouponsTable
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Action::make('sync')
|
||||
->label(__('Sync to Paddle'))
|
||||
->icon('heroicon-m-arrow-path')
|
||||
@@ -104,9 +112,42 @@ class CouponsTable
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
ForceDeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'force_deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
RestoreBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'restored',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\EmotionResource\Pages;
|
||||
use App\Models\Emotion;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\MarkdownEditor;
|
||||
@@ -17,6 +18,7 @@ use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class EmotionResource extends Resource
|
||||
@@ -116,10 +118,27 @@ class EmotionResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, Emotion $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\EmotionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EmotionResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ManageRecords;
|
||||
|
||||
@@ -13,7 +14,13 @@ class ManageEmotions extends ManageRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\CreateAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\Action::make('import')
|
||||
->label(__('admin.common.import_csv'))
|
||||
->icon('heroicon-o-arrow-up-tray')
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Exports\EventPurchaseExporter;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\EventPurchaseResource\Pages;
|
||||
use App\Models\EventPurchase;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
@@ -23,6 +24,7 @@ use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class EventPurchaseResource extends Resource
|
||||
@@ -174,11 +176,29 @@ class EventPurchaseResource extends Resource
|
||||
->action(function (EventPurchase $record) {
|
||||
$record->update(['refunded_at' => now()]);
|
||||
Log::info('Refund processed for purchase ID: '.$record->id);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'event_purchase.refunded',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['refunded_at']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
ExportBulkAction::make()
|
||||
->label('Export CSV')
|
||||
->exporter(EventPurchaseExporter::class),
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\EventPurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventPurchaseResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreateEventPurchase extends CreateRecord
|
||||
class CreateEventPurchase extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = EventPurchaseResource::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
namespace App\Filament\Resources\EventPurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventPurchaseResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditEventPurchase extends EditRecord
|
||||
class EditEventPurchase extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = EventPurchaseResource::class;
|
||||
|
||||
@@ -14,7 +15,12 @@ class EditEventPurchase extends EditRecord
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\EventPurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventPurchaseResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,7 +14,13 @@ class ViewEventPurchase extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Models\Event;
|
||||
use App\Models\EventJoinTokenEvent;
|
||||
use App\Models\EventType;
|
||||
use App\Models\Tenant;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Support\JoinTokenLayoutRegistry;
|
||||
use BackedEnum;
|
||||
use Carbon\Carbon;
|
||||
@@ -22,6 +23,7 @@ use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class EventResource extends Resource
|
||||
@@ -133,11 +135,26 @@ class EventResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, Event $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\Action::make('toggle')
|
||||
->label(__('admin.events.actions.toggle_active'))
|
||||
->icon('heroicon-o-power')
|
||||
->action(fn ($record) => $record->update(['is_active' => ! $record->is_active])),
|
||||
->action(function (Event $record): void {
|
||||
$record->update(['is_active' => ! $record->is_active]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'event.toggled',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_active']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Actions\Action::make('download_photos')
|
||||
->label(__('admin.events.actions.download_photos'))
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
@@ -243,7 +260,18 @@ class EventResource extends Resource
|
||||
}),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\EventResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreateEvent extends CreateRecord
|
||||
class CreateEvent extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = EventResource::class;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\EventResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
|
||||
class EditEvent extends EditRecord
|
||||
class EditEvent extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = EventResource::class;
|
||||
}
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
namespace App\Filament\Resources\EventResource\RelationManagers;
|
||||
|
||||
use App\Models\EventPackage;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
|
||||
@@ -93,15 +93,43 @@ class EventPackagesRelationManager extends RelationManager
|
||||
])
|
||||
->filters([])
|
||||
->headerActions([
|
||||
CreateAction::make(),
|
||||
CreateAction::make()
|
||||
->after(fn (array $data, EventPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->actions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, EventPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
DeleteAction::make()
|
||||
->after(fn (EventPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\EventTypeResource\Pages;
|
||||
use App\Models\EventType;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\KeyValue;
|
||||
@@ -16,6 +17,7 @@ use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class EventTypeResource extends Resource
|
||||
@@ -104,10 +106,27 @@ class EventTypeResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, EventType $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\EventTypeResource\Pages;
|
||||
|
||||
use App\Filament\Resources\EventTypeResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ManageRecords;
|
||||
|
||||
@@ -13,7 +14,13 @@ class ManageEventTypes extends ManageRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\CreateAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\GiftVoucherResource\Pages;
|
||||
use App\Models\GiftVoucher;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Services\GiftVouchers\GiftVoucherService;
|
||||
use BackedEnum;
|
||||
use Carbon\Carbon;
|
||||
@@ -97,6 +98,13 @@ class GiftVoucherResource extends Resource
|
||||
->visible(fn (GiftVoucher $record): bool => $record->canBeRefunded())
|
||||
->action(function (GiftVoucher $record, GiftVoucherService $service): void {
|
||||
$service->refund($record, 'customer_request');
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'gift_voucher.refunded',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['status', 'refunded_at']),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->successNotificationTitle('Gutschein erstattet'),
|
||||
Action::make('resend')
|
||||
@@ -118,6 +126,13 @@ class GiftVoucherResource extends Resource
|
||||
$record,
|
||||
Carbon::parse($data['recipient_delivery_scheduled_at'])
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'gift_voucher.delivery_scheduled',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->visible(fn (GiftVoucher $record): bool => ! empty($record->recipient_email)),
|
||||
Action::make('mark_redeemed')
|
||||
@@ -136,6 +151,13 @@ class GiftVoucherResource extends Resource
|
||||
'manual_marked' => true,
|
||||
]),
|
||||
])->save();
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'gift_voucher.marked_redeemed',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['status', 'redeemed_at', 'metadata']),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->successNotificationTitle('Als eingelöst markiert'),
|
||||
]);
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
namespace App\Filament\Resources\GiftVoucherResource\Pages;
|
||||
|
||||
use App\Filament\Resources\GiftVoucherResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Services\GiftVouchers\GiftVoucherService;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ListGiftVouchers extends ListRecords
|
||||
@@ -62,7 +63,20 @@ class ListGiftVouchers extends ListRecords
|
||||
],
|
||||
];
|
||||
|
||||
$service->issueFromPaddle($payload);
|
||||
$voucher = $service->issueFromPaddle($payload);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'issued',
|
||||
$voucher,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'amount',
|
||||
'currency',
|
||||
'status',
|
||||
'expires_at',
|
||||
'coupon_id',
|
||||
]),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->modalHeading('Geschenkgutschein ausstellen'),
|
||||
];
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Filament\Resources\LegalPageResource\Pages;
|
||||
use App\Models\LegalPage;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
@@ -18,6 +19,7 @@ use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class LegalPageResource extends Resource
|
||||
@@ -99,10 +101,27 @@ class LegalPageResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, LegalPage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\LegalPageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\LegalPageResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
|
||||
class EditLegalPage extends EditRecord
|
||||
class EditLegalPage extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = LegalPageResource::class;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Filament\Resources\MediaStorageTargetResource\Pages;
|
||||
use App\Models\MediaStorageTarget;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\KeyValue;
|
||||
@@ -15,6 +16,7 @@ use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class MediaStorageTargetResource extends Resource
|
||||
@@ -115,10 +117,27 @@ class MediaStorageTargetResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, MediaStorageTarget $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
namespace App\Filament\Resources\MediaStorageTargetResource\Pages;
|
||||
|
||||
use App\Filament\Resources\MediaStorageTargetResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreateMediaStorageTarget extends CreateRecord
|
||||
class CreateMediaStorageTarget extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = MediaStorageTargetResource::class;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,23 @@
|
||||
namespace App\Filament\Resources\MediaStorageTargetResource\Pages;
|
||||
|
||||
use App\Filament\Resources\MediaStorageTargetResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditMediaStorageTarget extends EditRecord
|
||||
class EditMediaStorageTarget extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = MediaStorageTargetResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\PackageAddonResource\Pages;
|
||||
use App\Jobs\SyncPackageAddonToPaddle;
|
||||
use App\Models\PackageAddon;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
@@ -17,6 +18,7 @@ use Filament\Tables;
|
||||
use Filament\Tables\Columns\BadgeColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class PackageAddonResource extends Resource
|
||||
{
|
||||
@@ -130,11 +132,28 @@ class PackageAddonResource extends Resource
|
||||
->body('Das Add-on wird im Hintergrund mit Paddle abgeglichen.')
|
||||
->send();
|
||||
}),
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, PackageAddon $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\BulkActionGroup::make([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\PackageAddonResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PackageAddonResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreatePackageAddon extends CreateRecord
|
||||
class CreatePackageAddon extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = PackageAddonResource::class;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\PackageAddonResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PackageAddonResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
|
||||
class EditPackageAddon extends EditRecord
|
||||
class EditPackageAddon extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PackageAddonResource::class;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Filament\Resources\PackageResource\Pages;
|
||||
use App\Jobs\PullPackageFromPaddle;
|
||||
use App\Jobs\SyncPackageToPaddle;
|
||||
use App\Models\Package;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -37,6 +38,7 @@ use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules\Unique;
|
||||
@@ -319,20 +321,75 @@ class PackageResource extends Resource
|
||||
->send();
|
||||
}),
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, Package $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
DeleteAction::make()
|
||||
->visible(fn (Package $record) => ! $record->trashed()),
|
||||
->visible(fn (Package $record) => ! $record->trashed())
|
||||
->after(fn (Package $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
RestoreAction::make()
|
||||
->visible(fn (Package $record) => $record->trashed()),
|
||||
->visible(fn (Package $record) => $record->trashed())
|
||||
->after(fn (Package $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'restored',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
ForceDeleteAction::make()
|
||||
->visible(fn (Package $record) => $record->trashed())
|
||||
->requiresConfirmation(),
|
||||
->requiresConfirmation()
|
||||
->after(fn (Package $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'force_deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
ForceDeleteBulkAction::make()->requiresConfirmation(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
RestoreBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'restored',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
ForceDeleteBulkAction::make()
|
||||
->requiresConfirmation()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'force_deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Filament\Resources\PackageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PackageResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
|
||||
class CreatePackage extends CreateRecord
|
||||
class CreatePackage extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = PackageResource::class;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
namespace App\Filament\Resources\PackageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PackageResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPackage extends EditRecord
|
||||
class EditPackage extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PackageResource::class;
|
||||
|
||||
@@ -14,7 +15,12 @@ class EditPackage extends EditRecord
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
19
app/Filament/Resources/Pages/AuditedCreateRecord.php
Normal file
19
app/Filament/Resources/Pages/AuditedCreateRecord.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Pages;
|
||||
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class AuditedCreateRecord extends CreateRecord
|
||||
{
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$this->record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($this->form->getState()),
|
||||
static::class
|
||||
);
|
||||
}
|
||||
}
|
||||
25
app/Filament/Resources/Pages/AuditedEditRecord.php
Normal file
25
app/Filament/Resources/Pages/AuditedEditRecord.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Pages;
|
||||
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class AuditedEditRecord extends EditRecord
|
||||
{
|
||||
protected function afterSave(): void
|
||||
{
|
||||
$changed = array_keys($this->record->getChanges());
|
||||
|
||||
if ($changed === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$this->record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($changed ?: $this->form->getState()),
|
||||
static::class
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use App\Filament\Clusters\DailyOps\DailyOpsCluster;
|
||||
use App\Filament\Resources\PhotoResource\Pages;
|
||||
use App\Models\Event;
|
||||
use App\Models\Photo;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
@@ -16,6 +17,7 @@ use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class PhotoResource extends Resource
|
||||
@@ -78,29 +80,95 @@ class PhotoResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, Photo $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\Action::make('feature')
|
||||
->label(__('admin.photos.actions.feature'))
|
||||
->visible(fn (Photo $record) => ! $record->is_featured)
|
||||
->action(fn (Photo $record) => $record->update(['is_featured' => true]))
|
||||
->action(function (Photo $record): void {
|
||||
$record->update(['is_featured' => true]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'photo.featured',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_featured']),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->icon('heroicon-o-star'),
|
||||
Actions\Action::make('unfeature')
|
||||
->label(__('admin.photos.actions.unfeature'))
|
||||
->visible(fn (Photo $record) => $record->is_featured)
|
||||
->action(fn (Photo $record) => $record->update(['is_featured' => false]))
|
||||
->action(function (Photo $record): void {
|
||||
$record->update(['is_featured' => false]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'photo.unfeatured',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_featured']),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->icon('heroicon-o-star'),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn (Photo $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\BulkAction::make('feature')
|
||||
->label(__('admin.photos.actions.feature_selected'))
|
||||
->icon('heroicon-o-star')
|
||||
->action(fn ($records) => $records->each->update(['is_featured' => true])),
|
||||
->action(function ($records): void {
|
||||
$records->each->update(['is_featured' => true]);
|
||||
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->record(
|
||||
'photo.featured',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_featured']),
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
Actions\BulkAction::make('unfeature')
|
||||
->label(__('admin.photos.actions.unfeature_selected'))
|
||||
->icon('heroicon-o-star')
|
||||
->action(fn ($records) => $records->each->update(['is_featured' => false])),
|
||||
Actions\DeleteBulkAction::make(),
|
||||
->action(function ($records): void {
|
||||
$records->each->update(['is_featured' => false]);
|
||||
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->record(
|
||||
'photo.unfeatured',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_featured']),
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\PhotoResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\PhotoResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPhoto extends EditRecord
|
||||
class EditPhoto extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PhotoResource::class;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\PhotoboothSettings\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\PhotoboothSettings\PhotoboothSettingResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPhotoboothSetting extends EditRecord
|
||||
class EditPhotoboothSetting extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PhotoboothSettingResource::class;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Resources\PhotoboothSettings\Tables;
|
||||
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -29,7 +30,13 @@ class PhotoboothSettingsTable
|
||||
->label(__('Aktualisiert')),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
])
|
||||
->headerActions([])
|
||||
->bulkActions([]);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Filament\Resources\PurchaseResource\Pages;
|
||||
use App\Models\PackagePurchase;
|
||||
use App\Notifications\Customer\RefundReceipt;
|
||||
use App\Notifications\Ops\RefundProcessed;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Services\Paddle\PaddleTransactionService;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
@@ -27,6 +28,7 @@ use Filament\Tables\Filters\Filter;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
@@ -178,7 +180,13 @@ class PurchaseResource extends Resource
|
||||
])
|
||||
->actions([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, PackagePurchase $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Action::make('refund')
|
||||
->label('Refund')
|
||||
->color('danger')
|
||||
@@ -234,11 +242,29 @@ class PurchaseResource extends Resource
|
||||
if ($opsEmail) {
|
||||
Notification::route('mail', $opsEmail)->notify(new RefundProcessed($record, $refundSuccess, $reason, $errorMessage));
|
||||
}
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'purchase.refunded',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['refunded', 'metadata']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
])
|
||||
->emptyStateHeading('No Purchases Found')
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\PurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
use App\Filament\Resources\PurchaseResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreatePurchase extends CreateRecord
|
||||
class CreatePurchase extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = PurchaseResource::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Filament\Resources\PurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\PurchaseResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPurchase extends EditRecord
|
||||
class EditPurchase extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = PurchaseResource::class;
|
||||
|
||||
@@ -14,7 +15,12 @@ class EditPurchase extends EditRecord
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\PurchaseResource\Pages;
|
||||
|
||||
use App\Filament\Resources\PurchaseResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,8 +14,19 @@ class ViewPurchase extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
Actions\Action::make('refund')
|
||||
->label('Refund')
|
||||
->color('danger')
|
||||
@@ -24,6 +36,13 @@ class ViewPurchase extends ViewRecord
|
||||
->action(function ($record) {
|
||||
$record->update(['refunded' => true]);
|
||||
// TODO: Call Paddle API for actual refund
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'purchase.refunded',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['refunded']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\TaskResource\Pages;
|
||||
use App\Models\Task;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
use Filament\Forms\Components\MarkdownEditor;
|
||||
@@ -17,6 +18,7 @@ use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use UnitEnum;
|
||||
|
||||
class TaskResource extends Resource
|
||||
@@ -163,11 +165,33 @@ class TaskResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, Task $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn (Task $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Filament\Resources\TaskResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TaskResource;
|
||||
use App\Models\Task;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
@@ -14,7 +15,9 @@ use Illuminate\Support\Facades\Storage;
|
||||
class ImportTasks extends Page
|
||||
{
|
||||
protected static string $resource = TaskResource::class;
|
||||
|
||||
protected string $view = 'filament.resources.task-resource.pages.import-tasks';
|
||||
|
||||
protected ?string $heading = null;
|
||||
|
||||
public ?string $file = null;
|
||||
@@ -35,8 +38,9 @@ class ImportTasks extends Page
|
||||
$this->validate();
|
||||
|
||||
$path = $this->form->getState()['file'] ?? null;
|
||||
if (!$path || !Storage::disk('public')->exists($path)) {
|
||||
if (! $path || ! Storage::disk('public')->exists($path)) {
|
||||
Notification::make()->danger()->title(__('admin.notifications.file_not_found'))->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,14 +62,14 @@ class ImportTasks extends Page
|
||||
private function importTasksCsv(string $file): array
|
||||
{
|
||||
$handle = fopen($file, 'r');
|
||||
if (!$handle) {
|
||||
if (! $handle) {
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
$ok = 0;
|
||||
$fail = 0;
|
||||
$headers = fgetcsv($handle, 0, ',');
|
||||
if (!$headers) {
|
||||
if (! $headers) {
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
@@ -87,7 +91,7 @@ class ImportTasks extends Page
|
||||
$emotionId = DB::table('emotions')->where('name->en', $emotionNameEn)->value('id');
|
||||
}
|
||||
|
||||
if (!$emotionId) {
|
||||
if (! $emotionId) {
|
||||
throw new \Exception('Emotion not found.');
|
||||
}
|
||||
|
||||
@@ -97,7 +101,7 @@ class ImportTasks extends Page
|
||||
$eventTypeId = DB::table('event_types')->where('slug', $eventTypeSlug)->value('id');
|
||||
}
|
||||
|
||||
Task::create([
|
||||
$task = Task::create([
|
||||
'emotion_id' => $emotionId,
|
||||
'event_type_id' => $eventTypeId,
|
||||
'title' => [
|
||||
@@ -113,10 +117,17 @@ class ImportTasks extends Page
|
||||
'de' => $row[$map['example_text_de']] ?? null,
|
||||
'en' => $row[$map['example_text_en']] ?? null,
|
||||
],
|
||||
'sort_order' => (int)($row[$map['sort_order']] ?? 0),
|
||||
'is_active' => (int)($row[$map['is_active']] ?? 1) ? 1 : 0,
|
||||
'sort_order' => (int) ($row[$map['sort_order']] ?? 0),
|
||||
'is_active' => (int) ($row[$map['is_active']] ?? 1) ? 1 : 0,
|
||||
]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$task,
|
||||
SuperAdminAuditLogger::fieldsMetadata($task->getChanges()),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
$ok++;
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
@@ -125,6 +136,7 @@ class ImportTasks extends Page
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return [$ok, $fail];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\TaskResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TaskResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ManageRecords;
|
||||
|
||||
@@ -13,7 +14,13 @@ class ManageTasks extends ManageRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\CreateAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'created',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\Action::make('import')
|
||||
->label(__('admin.common.import_csv'))
|
||||
->icon('heroicon-o-arrow-up-tray')
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\TenantFeedbackResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TenantFeedbackResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,7 +14,12 @@ class ViewTenantFeedback extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\TenantFeedbackResource\Tables;
|
||||
|
||||
use App\Models\TenantFeedback;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -182,11 +183,23 @@ class TenantFeedbackTable
|
||||
'moderated_at' => now(),
|
||||
'moderated_by' => Filament::auth()->id(),
|
||||
]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant_feedback.'.$status,
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'status',
|
||||
'moderation_notes',
|
||||
'moderated_at',
|
||||
'moderated_by',
|
||||
]),
|
||||
source: self::class
|
||||
);
|
||||
}
|
||||
|
||||
private static function applyModerationToRecords(Collection $records, string $status, ?string $notes): int
|
||||
{
|
||||
return TenantFeedback::query()
|
||||
$updated = TenantFeedback::query()
|
||||
->whereIn('id', $records->pluck('id'))
|
||||
->update([
|
||||
'status' => $status,
|
||||
@@ -194,6 +207,24 @@ class TenantFeedbackTable
|
||||
'moderated_at' => now(),
|
||||
'moderated_by' => Filament::auth()->id(),
|
||||
]);
|
||||
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->record(
|
||||
'tenant_feedback.'.$status,
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'status',
|
||||
'moderation_notes',
|
||||
'moderated_at',
|
||||
'moderated_by',
|
||||
]),
|
||||
source: self::class
|
||||
);
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
private static function statusLabels(): array
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\TenantPackageResource\Pages;
|
||||
use App\Models\TenantPackage;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -20,6 +21,7 @@ use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class TenantPackageResource extends Resource
|
||||
{
|
||||
@@ -68,13 +70,35 @@ class TenantPackageResource extends Resource
|
||||
->actions([
|
||||
ActionGroup::make([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, TenantPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
DeleteAction::make()
|
||||
->after(fn (TenantPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
]),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantPackageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
use App\Filament\Resources\TenantPackageResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateTenantPackage extends CreateRecord
|
||||
class CreateTenantPackage extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = TenantPackageResource::class;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantPackageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\TenantPackageResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditTenantPackage extends EditRecord
|
||||
class EditTenantPackage extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = TenantPackageResource::class;
|
||||
|
||||
@@ -14,7 +15,12 @@ class EditTenantPackage extends EditRecord
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\TenantPackageResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TenantPackageResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,8 +14,19 @@ class ViewTenantPackage extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Filament\Resources\TenantResource\Schemas\TenantInfolist;
|
||||
use App\Jobs\AnonymizeAccount;
|
||||
use App\Models\Tenant;
|
||||
use App\Notifications\InactiveTenantDeletionWarning;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Services\Tenant\TenantLifecycleLogger;
|
||||
use BackedEnum;
|
||||
use Carbon\Carbon;
|
||||
@@ -27,6 +28,7 @@ use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use UnitEnum;
|
||||
@@ -180,7 +182,13 @@ class TenantResource extends Resource
|
||||
])
|
||||
->filters([])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, Tenant $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\Action::make('add_package')
|
||||
->label('Package hinzufügen')
|
||||
->icon('heroicon-o-plus')
|
||||
@@ -213,6 +221,13 @@ class TenantResource extends Resource
|
||||
'price' => 0,
|
||||
'metadata' => ['reason' => $data['reason'] ?? 'manual assignment'],
|
||||
]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.package_added',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Actions\Action::make('export')
|
||||
->label('Daten exportieren')
|
||||
@@ -225,7 +240,18 @@ class TenantResource extends Resource
|
||||
->icon('heroicon-o-shield-exclamation'),
|
||||
])
|
||||
->bulkActions([
|
||||
Actions\DeleteBulkAction::make(),
|
||||
Actions\DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -269,6 +295,13 @@ class TenantResource extends Resource
|
||||
actor: Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.activated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_active']),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
return $updated;
|
||||
}),
|
||||
Actions\Action::make('deactivate')
|
||||
@@ -287,6 +320,13 @@ class TenantResource extends Resource
|
||||
actor: Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.deactivated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_active']),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
return $updated;
|
||||
}),
|
||||
Actions\Action::make('suspend')
|
||||
@@ -305,6 +345,13 @@ class TenantResource extends Resource
|
||||
actor: Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.suspended',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_suspended']),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
return $updated;
|
||||
}),
|
||||
Actions\Action::make('unsuspend')
|
||||
@@ -322,6 +369,13 @@ class TenantResource extends Resource
|
||||
actor: Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.unsuspended',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['is_suspended']),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
return $updated;
|
||||
}),
|
||||
Actions\Action::make('schedule_deletion')
|
||||
@@ -374,6 +428,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.deletion_scheduled',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->successNotificationTitle(__('admin.tenants.actions.schedule_deletion_success')),
|
||||
Actions\Action::make('cancel_deletion')
|
||||
@@ -398,6 +459,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.deletion_cancelled',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['pending_deletion_at', 'deletion_warning_sent_at']),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->successNotificationTitle(__('admin.tenants.actions.cancel_deletion_success')),
|
||||
Actions\Action::make('anonymize_now')
|
||||
@@ -415,6 +483,13 @@ class TenantResource extends Resource
|
||||
'anonymize_requested',
|
||||
actor: Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.anonymize_requested',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata([]),
|
||||
source: static::class
|
||||
);
|
||||
})
|
||||
->successNotificationTitle(__('admin.tenants.actions.anonymize_success')),
|
||||
];
|
||||
@@ -472,6 +547,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.limits_updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Actions\Action::make('update_subscription_expires_at')
|
||||
->label(__('admin.tenants.actions.update_subscription_expires_at'))
|
||||
@@ -508,6 +590,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.subscription_expires_at_updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Actions\Action::make('set_grace_period')
|
||||
->label(__('admin.tenants.actions.set_grace_period'))
|
||||
@@ -537,6 +626,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.grace_period_set',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Actions\Action::make('clear_grace_period')
|
||||
->label(__('admin.tenants.actions.clear_grace_period'))
|
||||
@@ -560,6 +656,13 @@ class TenantResource extends Resource
|
||||
],
|
||||
Filament::auth()->user()
|
||||
);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant.grace_period_cleared',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['grace_period_ends_at']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\TenantResource;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditTenant extends EditRecord
|
||||
class EditTenant extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = TenantResource::class;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Resources\TenantResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TenantResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -23,7 +24,13 @@ class ViewTenant extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
...TenantResource::lifecycleActions(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Filament\Resources\TenantResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TenantResource;
|
||||
use App\Filament\Resources\TenantResource\Schemas\TenantLifecycleInfolist;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
use Filament\Schemas\Schema;
|
||||
@@ -25,7 +26,13 @@ class ViewTenantLifecycle extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
Actions\EditAction::make()
|
||||
->after(fn (array $data, $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Actions\ActionGroup::make(TenantResource::lifecycleActions())
|
||||
->label(__('admin.tenants.actions.lifecycle'))
|
||||
->icon('heroicon-o-shield-exclamation'),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantResource\RelationManagers;
|
||||
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
@@ -15,6 +16,7 @@ use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class PackagePurchasesRelationManager extends RelationManager
|
||||
{
|
||||
@@ -130,7 +132,18 @@ class PackagePurchasesRelationManager extends RelationManager
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,22 +2,19 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantResource\RelationManagers;
|
||||
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class PurchasesRelationManager extends RelationManager
|
||||
{
|
||||
@@ -77,7 +74,7 @@ class PurchasesRelationManager extends RelationManager
|
||||
->columns([
|
||||
TextColumn::make('package_id')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match($state) {
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'starter_pack' => 'info',
|
||||
'pro_pack' => 'success',
|
||||
'lifetime_unlimited' => 'danger',
|
||||
@@ -92,7 +89,7 @@ class PurchasesRelationManager extends RelationManager
|
||||
->money('EUR'),
|
||||
TextColumn::make('platform')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match($state) {
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'ios' => 'info',
|
||||
'android' => 'success',
|
||||
'web' => 'warning',
|
||||
@@ -123,10 +120,19 @@ class PurchasesRelationManager extends RelationManager
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Filament\Resources\TenantResource\RelationManagers;
|
||||
|
||||
use App\Models\TenantPackage;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
@@ -17,6 +19,7 @@ use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class TenantPackagesRelationManager extends RelationManager
|
||||
{
|
||||
@@ -92,22 +95,57 @@ class TenantPackagesRelationManager extends RelationManager
|
||||
])
|
||||
->headerActions([])
|
||||
->actions([
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, TenantPackage $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
Action::make('activate')
|
||||
->label('Aktivieren')
|
||||
->icon('heroicon-o-check-circle')
|
||||
->color('success')
|
||||
->action(fn ($record) => $record->update(['active' => true])),
|
||||
->action(function (TenantPackage $record): void {
|
||||
$record->update(['active' => true]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant_package.activated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['active']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
Action::make('deactivate')
|
||||
->label('Deaktivieren')
|
||||
->icon('heroicon-o-x-circle')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->action(fn ($record) => $record->update(['active' => false])),
|
||||
->action(function (TenantPackage $record): void {
|
||||
$record->update(['active' => false]);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'tenant_package.deactivated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata(['active']),
|
||||
source: static::class
|
||||
);
|
||||
}),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\UserResource\Pages;
|
||||
use App\Models\User;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -19,6 +20,7 @@ use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class UserResource extends Resource
|
||||
{
|
||||
@@ -98,12 +100,29 @@ class UserResource extends Resource
|
||||
->actions([
|
||||
ActionGroup::make([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
EditAction::make()
|
||||
->after(fn (array $data, User $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'updated',
|
||||
$record,
|
||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||
static::class
|
||||
)),
|
||||
]),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
DeleteBulkAction::make()
|
||||
->after(function (Collection $records): void {
|
||||
$logger = app(SuperAdminAuditLogger::class);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$logger->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace App\Filament\Resources\UserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
use App\Filament\Resources\UserResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreateUser extends CreateRecord
|
||||
class CreateUser extends AuditedCreateRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
|
||||
@@ -2,19 +2,25 @@
|
||||
|
||||
namespace App\Filament\Resources\UserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Filament\Resources\UserResource;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class EditUser extends EditRecord
|
||||
class EditUser extends AuditedEditRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'deleted',
|
||||
$record,
|
||||
source: static::class
|
||||
)),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Filament\SuperAdmin\Pages;
|
||||
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Models\GuestPolicySetting;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Forms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
@@ -163,6 +164,26 @@ class GuestPolicySettingsPage extends Page
|
||||
$settings->guest_notification_ttl_hours = $this->guest_notification_ttl_hours;
|
||||
$settings->save();
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'guest_policy.updated',
|
||||
$settings,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'guest_downloads_enabled',
|
||||
'guest_sharing_enabled',
|
||||
'guest_upload_visibility',
|
||||
'per_device_upload_limit',
|
||||
'join_token_failure_limit',
|
||||
'join_token_failure_decay_minutes',
|
||||
'join_token_access_limit',
|
||||
'join_token_access_decay_minutes',
|
||||
'join_token_download_limit',
|
||||
'join_token_download_decay_minutes',
|
||||
'share_link_ttl_hours',
|
||||
'guest_notification_ttl_hours',
|
||||
]),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
Notification::make()
|
||||
->title(__('admin.guest_policy.notifications.saved'))
|
||||
->success()
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Filament\SuperAdmin\Pages;
|
||||
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Models\WatermarkSetting;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Forms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
@@ -128,6 +129,21 @@ class WatermarkSettingsPage extends Page
|
||||
$settings->offset_y = $this->offset_y;
|
||||
$settings->save();
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'watermark_settings.updated',
|
||||
$settings,
|
||||
SuperAdminAuditLogger::fieldsMetadata([
|
||||
'asset',
|
||||
'position',
|
||||
'opacity',
|
||||
'scale',
|
||||
'padding',
|
||||
'offset_x',
|
||||
'offset_y',
|
||||
]),
|
||||
source: static::class
|
||||
);
|
||||
|
||||
Notification::make()
|
||||
->title('Wasserzeichen aktualisiert')
|
||||
->success()
|
||||
|
||||
Reference in New Issue
Block a user