TenantAtlas/app/Filament/Pages/Monitoring/Operations.php
2026-01-18 15:46:49 +01:00

128 lines
4.5 KiB
PHP

<?php
namespace App\Filament\Pages\Monitoring;
use App\Models\OperationRun;
use App\Support\OperationCatalog;
use BackedEnum;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use UnitEnum;
class Operations extends Page implements HasForms, HasTable
{
use InteractsWithForms;
use InteractsWithTable;
protected static bool $isDiscovered = false;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-queue-list';
protected static string|UnitEnum|null $navigationGroup = 'Monitoring';
protected static ?string $title = 'Operations';
// Must be non-static
protected string $view = 'filament.pages.monitoring.operations';
public function table(Table $table): Table
{
return $table
->query(
OperationRun::query()
->where('tenant_id', Filament::getTenant()->id)
->latest('created_at')
)
->columns([
TextColumn::make('type')
->formatStateUsing(fn (?string $state): string => OperationCatalog::label((string) $state))
->searchable()
->sortable(),
TextColumn::make('status')
->badge()
->colors([
'secondary' => 'queued',
'warning' => 'running',
'success' => 'completed',
]),
TextColumn::make('outcome')
->badge()
->colors([
'gray' => 'pending',
'success' => 'succeeded',
'warning' => 'partially_succeeded',
'danger' => 'failed',
'secondary' => 'cancelled',
]),
TextColumn::make('initiator_name')
->label('Initiator')
->searchable(),
TextColumn::make('created_at')
->dateTime()
->sortable()
->label('Started'),
TextColumn::make('duration')
->getStateUsing(function (OperationRun $record) {
if ($record->started_at && $record->completed_at) {
return $record->completed_at->diffForHumans($record->started_at, true);
}
return '-';
}),
])
->filters([
SelectFilter::make('outcome')
->options([
'succeeded' => 'Succeeded',
'partially_succeeded' => 'Partially Succeeded',
'failed' => 'Failed',
'cancelled' => 'Cancelled',
'pending' => 'Pending',
]),
SelectFilter::make('type')
->options(
fn () => OperationRun::where('tenant_id', Filament::getTenant()->id)
->distinct()
->pluck('type', 'type')
->toArray()
),
Filter::make('created_at')
->form([
DatePicker::make('created_from'),
DatePicker::make('created_until'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['created_from'],
fn (Builder $query, $date) => $query->whereDate('created_at', '>=', $date),
)
->when(
$data['created_until'],
fn (Builder $query, $date) => $query->whereDate('created_at', '<=', $date),
);
}),
])
->actions([
// View action handled by opening a modal or side-peek
]);
}
}