Filament moderne (groupes nav, 4 charts, filtres/badges) + Filament Shield (rôles/permissions) + noms exos localisés dans routines
Build & Deploy / build (push) Successful in 19s
Build & Deploy / build (push) Successful in 19s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,12 +13,21 @@ use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Technical\Integrations\Models\Integration;
|
||||
use UnitEnum;
|
||||
|
||||
class IntegrationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Integration::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedArrowsRightLeft;
|
||||
|
||||
protected static string|UnitEnum|null $navigationGroup = 'Système';
|
||||
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
protected static ?string $modelLabel = 'intégration';
|
||||
|
||||
protected static ?string $pluralModelLabel = 'intégrations';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
@@ -37,6 +46,14 @@ class IntegrationResource extends Resource
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getGloballySearchableAttributes(): array
|
||||
{
|
||||
return ['provider', 'external_user_id', 'user.name'];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
|
||||
namespace App\Filament\Resources\Integrations\Tables;
|
||||
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Technical\Integrations\Enums\IntegrationStatus;
|
||||
use Technical\Integrations\Models\Integration;
|
||||
|
||||
/**
|
||||
* Table des intégrations externes : utilisateur, fournisseur, état, dernière synchro.
|
||||
@@ -27,7 +31,17 @@ class IntegrationsTable
|
||||
TextColumn::make('provider')
|
||||
->label('Fournisseur')
|
||||
->badge()
|
||||
->searchable(),
|
||||
->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()
|
||||
@@ -36,6 +50,11 @@ class IntegrationsTable
|
||||
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()
|
||||
@@ -43,6 +62,9 @@ class IntegrationsTable
|
||||
->placeholder('Jamais'),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('provider')
|
||||
->label('Fournisseur')
|
||||
->options(fn (): array => self::distinctProviders()),
|
||||
SelectFilter::make('status')
|
||||
->label('État')
|
||||
->options(IntegrationStatus::class),
|
||||
@@ -53,8 +75,34 @@ class IntegrationsTable
|
||||
->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<string, string>
|
||||
*/
|
||||
private static function distinctProviders(): array
|
||||
{
|
||||
return Integration::query()
|
||||
->distinct()
|
||||
->orderBy('provider')
|
||||
->pluck('provider', 'provider')
|
||||
->all();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user