| null */ #[Url] public ?array $tableFilters = null; #[Url] public ?string $tableGrouping = null; #[Url] public ?string $tableGroupingDirection = null; /** * @var ?string */ #[Url] public $tableSearch = ''; #[Url] public ?string $tableSortColumn = null; #[Url] public ?string $tableSortDirection = null; #[Url] public ?string $activeTab = null; /** * @var array */ protected array $cachedTabs; public function mount(): void { static::authorizeResourceAccess(); if (blank($this->activeTab)) { $this->activeTab = $this->getDefaultActiveTab(); } } public function getBreadcrumb(): ?string { return static::$breadcrumb ?? __('filament-panels::resources/pages/list-records.breadcrumb'); } public function table(Table $table): Table { return static::getResource()::table($table); } public function getTitle(): string | Htmlable { return static::$title ?? Str::headline(static::getResource()::getPluralModelLabel()); } protected function configureAction(Action $action): void { match (true) { $action instanceof CreateAction => $this->configureCreateAction($action), default => null, }; } public function form(Form $form): Form { return static::getResource()::form($form); } public function infolist(Infolist $infolist): Infolist { return static::getResource()::infolist($infolist); } protected function configureCreateAction(CreateAction | Tables\Actions\CreateAction $action): void { $resource = static::getResource(); $action ->authorize($resource::canCreate()) ->model($this->getModel()) ->modelLabel($this->getModelLabel() ?? static::getResource()::getModelLabel()) ->form(fn (Form $form): Form => $this->form($form->columns(2))); if ($action instanceof CreateAction) { $action->relationship(($tenant = Filament::getTenant()) ? fn (): Relation => static::getResource()::getTenantRelationship($tenant) : null); } if ($resource::hasPage('create')) { $action->url(fn (): string => $resource::getUrl('create')); } } protected function configureTableAction(Tables\Actions\Action $action): void { match (true) { $action instanceof Tables\Actions\CreateAction => $this->configureCreateAction($action), $action instanceof Tables\Actions\DeleteAction => $this->configureDeleteAction($action), $action instanceof Tables\Actions\EditAction => $this->configureEditAction($action), $action instanceof Tables\Actions\ForceDeleteAction => $this->configureForceDeleteAction($action), $action instanceof Tables\Actions\ReplicateAction => $this->configureReplicateAction($action), $action instanceof Tables\Actions\RestoreAction => $this->configureRestoreAction($action), $action instanceof Tables\Actions\ViewAction => $this->configureViewAction($action), default => null, }; } protected function configureDeleteAction(Tables\Actions\DeleteAction $action): void { $action ->authorize(fn (Model $record): bool => static::getResource()::canDelete($record)); } protected function configureEditAction(Tables\Actions\EditAction $action): void { $resource = static::getResource(); $action ->authorize(fn (Model $record): bool => $resource::canEdit($record)) ->form(fn (Form $form): Form => $this->form($form->columns(2))); if ($resource::hasPage('edit')) { $action->url(fn (Model $record): string => $resource::getUrl('edit', ['record' => $record])); } } protected function configureForceDeleteAction(Tables\Actions\ForceDeleteAction $action): void { $action ->authorize(fn (Model $record): bool => static::getResource()::canForceDelete($record)); } protected function configureReplicateAction(Tables\Actions\ReplicateAction $action): void { $action ->authorize(fn (Model $record): bool => static::getResource()::canReplicate($record)); } protected function configureRestoreAction(Tables\Actions\RestoreAction $action): void { $action ->authorize(fn (Model $record): bool => static::getResource()::canRestore($record)); } protected function configureViewAction(Tables\Actions\ViewAction $action): void { $resource = static::getResource(); $action ->authorize(fn (Model $record): bool => $resource::canView($record)) ->infolist(fn (Infolist $infolist): Infolist => $this->infolist($infolist->columns(2))) ->form(fn (Form $form): Form => $this->form($form->columns(2))); if ($resource::hasPage('view')) { $action->url(fn (Model $record): string => $resource::getUrl('view', ['record' => $record])); } } protected function configureTableBulkAction(BulkAction $action): void { match (true) { $action instanceof Tables\Actions\DeleteBulkAction => $this->configureDeleteBulkAction($action), $action instanceof Tables\Actions\ForceDeleteBulkAction => $this->configureForceDeleteBulkAction($action), $action instanceof Tables\Actions\RestoreBulkAction => $this->configureRestoreBulkAction($action), default => null, }; } protected function configureDeleteBulkAction(Tables\Actions\DeleteBulkAction $action): void { $action ->authorize(static::getResource()::canDeleteAny()); } protected function configureForceDeleteBulkAction(Tables\Actions\ForceDeleteBulkAction $action): void { $action ->authorize(static::getResource()::canForceDeleteAny()); } protected function configureRestoreBulkAction(Tables\Actions\RestoreBulkAction $action): void { $action ->authorize(static::getResource()::canRestoreAny()); } protected function getMountedActionFormModel(): string { return $this->getModel(); } /** * @deprecated Override the `table()` method to configure the table. */ public function getModelLabel(): ?string { return null; } /** * @deprecated Override the `table()` method to configure the table. */ public function getPluralModelLabel(): ?string { return null; } protected function makeTable(): Table { return $this->makeBaseTable() ->query(fn (): Builder => $this->getTableQuery()) ->modelLabel($this->getModelLabel() ?? static::getResource()::getModelLabel()) ->pluralModelLabel($this->getPluralModelLabel() ?? static::getResource()::getPluralModelLabel()) ->recordAction(function (Model $record, Table $table): ?string { foreach (['view', 'edit'] as $action) { $action = $table->getAction($action); if (! $action) { continue; } $action->record($record); if ($action->isHidden()) { continue; } if ($action->getUrl()) { continue; } return $action->getName(); } return null; }) ->recordTitle(fn (Model $record): string => static::getResource()::getRecordTitle($record)) ->recordUrl($this->getTableRecordUrlUsing() ?? function (Model $record, Table $table): ?string { foreach (['view', 'edit'] as $action) { $action = $table->getAction($action); if (! $action) { continue; } $action->record($record); if ($action->isHidden()) { continue; } $url = $action->getUrl(); if (! $url) { continue; } return $url; } $resource = static::getResource(); foreach (['view', 'edit'] as $action) { if (! $resource::hasPage($action)) { continue; } if (! $resource::{'can' . ucfirst($action)}($record)) { continue; } return $resource::getUrl($action, ['record' => $record]); } return null; }) ->reorderable(condition: static::getResource()::canReorder()); } protected function getTableQuery(): Builder { $query = static::getResource()::getEloquentQuery(); $tabs = $this->getCachedTabs(); if ( filled($this->activeTab) && array_key_exists($this->activeTab, $tabs) ) { $tabs[$this->activeTab]->modifyQuery($query); } return $query; } /** * @return array */ protected function getForms(): array { return []; } /** * @return array */ public function getTabs(): array { return []; } /** * @return array */ public function getCachedTabs(): array { return $this->cachedTabs ??= $this->getTabs(); } public function getDefaultActiveTab(): string | int | null { return array_key_first($this->getCachedTabs()); } public function updatedActiveTab(): void { $this->resetPage(); } public function generateTabLabel(string $key): string { return (string) str($key) ->replace(['_', '-'], ' ') ->ucfirst(); } }