revisions()->count(); return $count > 0 ? (string) $count : null; } public function table(Table $table): Table { return $table ->defaultSort('id', 'desc') ->modifyQueryUsing(fn ($query) => $query->with('user')) ->columns([ TextColumn::make('event') ->label(__('panel.revisions.fields.event')) ->badge() ->formatStateUsing(fn (string $state) => __("panel.revisions.events.{$state}")) // Publishing is a separate permission because it is a // bigger act than editing; it reads differently here too. ->color(fn (string $state) => match ($state) { 'published' => 'success', 'unpublished' => 'warning', 'scheduled' => 'info', 'created' => 'info', 'deleted', 'erased' => 'danger', default => 'gray', }), TextColumn::make('user_name') ->label(__('panel.revisions.fields.author')) ->state(fn (Revision $record) => $record->author()), TextColumn::make('changeset') ->label(__('panel.revisions.fields.fields')) ->state(fn (Revision $record) => $record->fields()) ->badge() ->color('gray') ->limitList(4) ->placeholder('—'), TextColumn::make('created_at') ->label(__('panel.revisions.fields.when')) ->since() ->dateTimeTooltip() ->sortable(), ]) ->filters([ SelectFilter::make('event') ->label(__('panel.revisions.fields.event')) ->options(fn () => collect(['created', 'updated', 'published', 'scheduled', 'unpublished', 'deleted', 'restored', 'erased']) ->mapWithKeys(fn (string $e) => [$e => __("panel.revisions.events.{$e}")]) ->all()), ]) ->recordActions([ Action::make('diff') ->label(__('panel.revisions.actions.diff')) ->icon('heroicon-o-eye') ->modalHeading(fn (Revision $record) => __('panel.revisions.diff_heading', [ 'author' => $record->author(), 'when' => $record->created_at?->isoFormat('LLL'), ])) ->modalSubmitAction(false) ->modalContent(fn (Revision $record) => view('filament.revisions.diff', [ 'revision' => $record, ])), Action::make('restore') ->label(__('panel.revisions.actions.restore')) ->icon('heroicon-o-arrow-uturn-left') ->color('warning') ->requiresConfirmation() ->modalDescription(__('panel.revisions.restore_confirm')) ->authorize(fn () => (bool) Auth::user()?->can('update', $this->getOwnerRecord())) // Nothing to put back for a creation or a deletion, and // the newest revision already is the current state. ->visible(fn (Revision $record) => filled($record->changeset) && $record->isNot($this->getOwnerRecord()->revisions()->first())) ->action(function (Revision $record): void { $owner = $this->getOwnerRecord(); // Restoring is itself a change, so it lands in the // history like any other — the way back is never lost. $owner->forceFill($record->previousValues())->save(); Notification::make() ->title(__('panel.revisions.restored')) ->success() ->send(); }), ]); } public function isReadOnly(): bool { return true; } }