Feat: Bringin Privacy to Filament v4, the managers and resources were built with filament v3

This commit is contained in:
2026-09-16 00:24:18 +03:00
parent 58d165acc3
commit c084eb47cb
12 changed files with 50 additions and 41 deletions
+4 -2
View File
@@ -2,6 +2,8 @@
namespace Modules\Core\Export;
use Closure;
/**
* One column in a CsvWriter schema: a header label plus a closure that pulls this
* column's value out of one record. The closure doesn't care what shape a record
@@ -12,10 +14,10 @@ namespace Modules\Core\Export;
final class CsvColumn
{
/**
* @param \Closure(mixed): (string|int|float|null) $value
* @param Closure(mixed):((string|int|float|null)) $value
*/
public function __construct(
public readonly string $header,
public readonly \Closure $value,
public readonly Closure $value,
) {}
}
@@ -2,6 +2,7 @@
namespace Modules\Core\Payment\Filament\Resources\PaymentMethodResource\Pages;
use Filament\Actions\CreateAction;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Modules\Core\Payment\Filament\Resources\PaymentMethodResource;
@@ -15,7 +16,7 @@ class ListPaymentMethods extends ListRecords
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
CreateAction::make()
->schema(PaymentMethodResource::getFormComponents())
->fillForm(fn () => [
'position' => (PaymentMethod::max('position') ?? 0) + 1,
@@ -33,7 +33,7 @@ class CustomerErasureActionsExtension extends BaseExtension
->color('danger')
->requiresConfirmation()
->modalDescription('Opens a cancellable grace-period erasure request for this Customer account. No linked User\'s login is affected.')
->form([
->schema([
Checkbox::make('immediate')
->label('Erase immediately (skip the 30-day grace period)')
->helperText('Staff-only, for a formal legal request or regulator inquiry that genuinely requires urgency — not a routine deletion. Runs synchronously, cannot be cancelled once submitted.')
@@ -2,13 +2,15 @@
namespace Modules\Core\Privacy\Filament\Resources;
use Filament\Schemas\Schema;
use Filament\Actions\ViewAction;
use Filament\Actions\Action;
use Modules\Core\Privacy\Filament\Resources\DataErasureRequestResource\Pages\ListDataErasureRequests;
use Modules\Core\Privacy\Filament\Resources\DataErasureRequestResource\Pages\ViewDataErasureRequest;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
@@ -30,17 +32,17 @@ class DataErasureRequestResource extends Resource
{
protected static ?string $model = DataErasureRequest::class;
protected static ?string $navigationIcon = 'heroicon-o-shield-exclamation';
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-shield-exclamation';
protected static ?string $navigationGroup = 'Privacy';
protected static string | \UnitEnum | null $navigationGroup = 'Privacy';
protected static ?string $modelLabel = 'Erasure Request';
protected static ?string $pluralModelLabel = 'Erasure Requests';
public static function form(Form $form): Form
public static function form(Schema $schema): Schema
{
return $form->schema([
return $schema->components([
Placeholder::make('subject')
->label('Subject')
->content(fn (DataErasureRequest $record) => sprintf(
@@ -139,7 +141,7 @@ class DataErasureRequestResource extends Resource
];
}),
])
->actions([
->recordActions([
ViewAction::make(),
Action::make('cancel')
->label('Cancel')
@@ -154,8 +156,8 @@ class DataErasureRequestResource extends Resource
public static function getPages(): array
{
return [
'index' => Pages\ListDataErasureRequests::route('/'),
'view' => Pages\ViewDataErasureRequest::route('/{record}'),
'index' => ListDataErasureRequests::route('/'),
'view' => ViewDataErasureRequest::route('/{record}'),
];
}
@@ -2,12 +2,14 @@
namespace Modules\Core\Privacy\Filament\Resources;
use Filament\Schemas\Schema;
use Filament\Actions\ViewAction;
use Filament\Actions\Action;
use Modules\Core\Privacy\Filament\Resources\DataExportRequestResource\Pages\ListDataExportRequests;
use Modules\Core\Privacy\Filament\Resources\DataExportRequestResource\Pages\ViewDataExportRequest;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
@@ -25,17 +27,17 @@ class DataExportRequestResource extends Resource
{
protected static ?string $model = DataExportRequest::class;
protected static ?string $navigationIcon = 'heroicon-o-arrow-down-tray';
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-arrow-down-tray';
protected static ?string $navigationGroup = 'Privacy';
protected static string | \UnitEnum | null $navigationGroup = 'Privacy';
protected static ?string $modelLabel = 'Export Request';
protected static ?string $pluralModelLabel = 'Export Requests';
public static function form(Form $form): Form
public static function form(Schema $schema): Schema
{
return $form->schema([
return $schema->components([
Placeholder::make('subject')
->label('Subject')
->content(fn (DataExportRequest $record) => sprintf(
@@ -100,7 +102,7 @@ class DataExportRequestResource extends Resource
ExportRequestStatus::Failed->value => 'Failed',
]),
])
->actions([
->recordActions([
ViewAction::make(),
Action::make('download')
->label('Download')
@@ -113,8 +115,8 @@ class DataExportRequestResource extends Resource
public static function getPages(): array
{
return [
'index' => Pages\ListDataExportRequests::route('/'),
'view' => Pages\ViewDataExportRequest::route('/{record}'),
'index' => ListDataExportRequests::route('/'),
'view' => ViewDataExportRequest::route('/{record}'),
];
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace Modules\Core\Privacy\Jobs;
use Throwable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -60,7 +61,7 @@ class ExportDataSubjectJob implements ShouldQueue
));
}
public function failed(\Throwable $exception): void
public function failed(Throwable $exception): void
{
$this->request->update(['status' => ExportRequestStatus::Failed]);
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace Modules\Core\Privacy;
use LogicException;
use Illuminate\Contracts\Container\Container;
use Modules\Core\Privacy\Contracts\PersonalDataProvider;
@@ -41,7 +42,7 @@ class PrivacyManager
$duplicates = array_diff_assoc($names, array_unique($names));
if ($duplicates !== []) {
throw new \LogicException(
throw new LogicException(
'Duplicate Modules\Core\Privacy provider name(s): '.implode(', ', array_unique($duplicates))
.'. Each provider registered in config(\'core.privacy.providers\') must return a unique name().'
);
@@ -2,9 +2,9 @@
namespace Modules\Core\Privacy\RelationManagers;
use Filament\Actions\ViewAction;
use Filament\Actions\Action;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
@@ -65,7 +65,7 @@ class ErasureRequestsRelationManager extends RelationManager
]),
])
->headerActions([])
->actions([
->recordActions([
ViewAction::make()
->url(fn (DataErasureRequest $record) => DataErasureRequestResource::getUrl('view', ['record' => $record])),
Action::make('cancel')
@@ -2,9 +2,9 @@
namespace Modules\Core\Privacy\RelationManagers;
use Filament\Actions\ViewAction;
use Filament\Actions\Action;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
@@ -56,7 +56,7 @@ class ExportRequestsRelationManager extends RelationManager
]),
])
->headerActions([])
->actions([
->recordActions([
ViewAction::make()
->url(fn (DataExportRequest $record) => DataExportRequestResource::getUrl('view', ['record' => $record])),
Action::make('download')
@@ -2,11 +2,11 @@
namespace Modules\Core\Privacy\RelationManagers;
use Filament\Actions\Action;
use Filament\Forms\Components\Checkbox;
use Filament\Infolists\Components\RepeatableEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Tables\Actions\Action;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Modules\Core\Customer\RelationManagers\UserRelationManager as CoreUserRelationManager;
@@ -31,7 +31,7 @@ class UserRelationManager extends CoreUserRelationManager
{
$table = parent::getDefaultTable($table);
return $table->actions([
return $table->recordActions([
...$table->getActions(),
Action::make('privacyRequests')
->label('Privacy Requests')
@@ -39,14 +39,14 @@ class UserRelationManager extends CoreUserRelationManager
->modalHeading(fn (Model $record) => "Privacy requests for {$record->name}")
->modalSubmitAction(false)
->modalCancelActionLabel('Close')
->infolist(fn (Model $record) => $this->requestsInfolist($record)),
->schema(fn (Model $record) => $this->requestsInfolist($record)),
Action::make('requestErasure')
->label('Request Erasure')
->icon('heroicon-o-shield-exclamation')
->color('danger')
->requiresConfirmation()
->modalDescription('Opens a cancellable grace-period erasure request for this individual — deactivates their login and detaches them from every linked Customer account once it completes. No Customer account\'s own data is affected.')
->form([
->schema([
Checkbox::make('immediate')
->label('Erase immediately (skip the 30-day grace period)')
->helperText('Staff-only, for a formal legal request or regulator inquiry that genuinely requires urgency — not a routine deletion. Runs synchronously, cannot be cancelled once submitted.')
@@ -47,7 +47,7 @@ class ShippingMethodResourceExtension extends ResourceExtension
}
if (in_array(HasChildComponents::class, class_uses_recursive($component), true)) {
$component->schema($this->replaceNameField($component->getChildComponents()));
$component->schema($this->replaceNameField($component->getDefaultChildComponents()));
}
return $component;
@@ -158,7 +158,7 @@ class ShippingMethodResourceExtension extends ResourceExtension
if (in_array(HasChildComponents::class, class_uses_recursive($component), true)) {
$component->schema(
$this->replaceChargeByField($component->getChildComponents())
$this->replaceChargeByField($component->getDefaultChildComponents())
);
}
@@ -269,7 +269,7 @@ class ShippingMethodResourceExtension extends ResourceExtension
if (in_array(HasChildComponents::class, class_uses_recursive($component), true)) {
$component->schema(
$this->replaceDriverField($component->getChildComponents())
$this->replaceDriverField($component->getDefaultChildComponents())
);
}