columns([ TextColumn::make('user.name') ->label('Utilisateur') ->searchable() ->sortable(), TextColumn::make('provider') ->label('Fournisseur') ->badge() ->color(fn (string $state): string => match (strtolower($state)) { 'strava' => 'danger', 'garmin' => 'info', default => 'gray', }) ->searchable() ->sortable(), TextColumn::make('external_user_id') ->label('ID externe') ->toggleable(isToggledHiddenByDefault: true) ->placeholder('—'), TextColumn::make('status') ->label('État') ->badge() ->color(fn (IntegrationStatus $state): string => match ($state) { IntegrationStatus::Connected => 'success', IntegrationStatus::Revoked => 'gray', IntegrationStatus::Error => 'danger', }), TextColumn::make('connected_at') ->label('Connecté le') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('last_synced_at') ->label('Dernière synchro') ->dateTime() ->sortable() ->placeholder('Jamais'), ]) ->filters([ SelectFilter::make('provider') ->label('Fournisseur') ->options(fn (): array => self::distinctProviders()), SelectFilter::make('status') ->label('État') ->options(IntegrationStatus::class), ]) ->recordActions([ EditAction::make(), ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), // Révocation groupée : coupe l'accès sans supprimer l'historique de connexion. BulkAction::make('revoke') ->label('Révoquer') ->icon(Heroicon::OutlinedBoltSlash) ->color('danger') ->requiresConfirmation() ->action(function (Collection $records): void { $records->each(fn (Integration $integration) => $integration->update([ 'status' => IntegrationStatus::Revoked, ])); }) ->deselectRecordsAfterCompletion(), ]), ]) ->defaultSort('last_synced_at', 'desc'); } /** * Valeurs distinctes de la colonne "provider" pour alimenter le filtre. * * @return array */ private static function distinctProviders(): array { return Integration::query() ->distinct() ->orderBy('provider') ->pluck('provider', 'provider') ->all(); } }