schema([ Infolists\Components\TextEntry::make('display_name')->label('Policy'), Infolists\Components\TextEntry::make('policy_type')->label('Type'), Infolists\Components\TextEntry::make('platform'), Infolists\Components\TextEntry::make('external_id')->label('External ID'), Infolists\Components\TextEntry::make('last_synced_at')->dateTime()->label('Last synced'), Infolists\Components\TextEntry::make('created_at')->since(), Infolists\Components\ViewEntry::make('settings') ->label('Settings') ->view('filament.infolists.entries.normalized-settings') ->state(function (Policy $record) { $snapshot = $record->versions() ->orderByDesc('captured_at') ->value('snapshot'); return app(PolicyNormalizer::class)->normalize( is_array($snapshot) ? $snapshot : [], $record->policy_type ?? '', $record->platform ); }), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('display_name') ->label('Policy') ->searchable(), Tables\Columns\TextColumn::make('policy_type') ->label('Type') ->badge() ->formatStateUsing(fn (?string $state, Policy $record) => static::typeMeta($record->policy_type)['label'] ?? $state), Tables\Columns\TextColumn::make('category') ->label('Category') ->badge() ->state(fn (Policy $record) => static::typeMeta($record->policy_type)['category'] ?? 'Unknown'), Tables\Columns\TextColumn::make('restore_mode') ->label('Restore') ->badge() ->state(fn (Policy $record) => static::typeMeta($record->policy_type)['restore'] ?? 'enabled'), Tables\Columns\TextColumn::make('platform') ->badge() ->sortable(), Tables\Columns\TextColumn::make('versions_count') ->label('Settings') ->badge() ->state(fn (Policy $record) => $record->versions_count > 0 ? 'Available' : 'Missing') ->color(fn (Policy $record) => $record->versions_count > 0 ? 'success' : 'gray'), Tables\Columns\TextColumn::make('external_id') ->label('External ID') ->copyable() ->limit(32), Tables\Columns\TextColumn::make('last_synced_at') ->label('Last synced') ->dateTime() ->sortable(), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->since() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ Tables\Filters\SelectFilter::make('policy_type') ->options(fn () => Policy::query()->distinct()->pluck('policy_type', 'policy_type')->all()), Tables\Filters\SelectFilter::make('category') ->options(function () { return collect(config('tenantpilot.supported_policy_types', [])) ->pluck('category', 'category') ->filter() ->unique() ->sort() ->all(); }) ->query(function (Builder $query, array $data) { $category = $data['value'] ?? null; if (! $category) { return; } $types = collect(config('tenantpilot.supported_policy_types', [])) ->where('category', $category) ->pluck('type') ->all(); $query->whereIn('policy_type', $types); }), Tables\Filters\SelectFilter::make('platform') ->options(fn () => Policy::query()->distinct()->pluck('platform', 'platform')->filter()->all()), ]) ->actions([ Actions\ViewAction::make(), ]) ->bulkActions([]); } public static function getEloquentQuery(): Builder { $tenantId = Tenant::current()->getKey(); return parent::getEloquentQuery() ->when($tenantId, fn (Builder $query) => $query->where('tenant_id', $tenantId)) ->withCount('versions'); } public static function getRelations(): array { return [ VersionsRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListPolicies::route('/'), 'view' => Pages\ViewPolicy::route('/{record}'), ]; } /** * @return array{label:?string,category:?string,restore:?string,risk:?string}|array|array */ private static function typeMeta(?string $type): array { if ($type === null) { return []; } return collect(config('tenantpilot.supported_policy_types', [])) ->firstWhere('type', $type) ?? []; } }