TenantAtlas/app/Filament/Pages/Monitoring/Operations.php
ahmido 0b6600b926 059-unified-badges (#71)
## Summary
- centralize all status-like badge semantics via `BadgeCatalog`/`BadgeRenderer` and new per-domain mappings plus coverage for every affected entity
- replace ad-hoc badge colors in Filament tables/views with the shared catalog and add a guard test that blocks new inline semantics
- stabilize restore views by avoiding `@php(...)` shorthand so Blade compiles cleanly, and document BADGE-001 in the constitution/templates

## Testing
- `vendor/bin/sail php vendor/bin/pint --dirty`
- `vendor/bin/sail artisan test tests/Unit/Badges tests/Feature/Guards/NoAdHocStatusBadgesTest.php`
- `vendor/bin/sail artisan test tests/Feature/Monitoring/OperationsDbOnlyTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php`
- `vendor/bin/sail artisan test tests/Feature/RestoreRunWizardMetadataTest.php tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php`

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #71
2026-01-22 23:44:51 +00:00

126 lines
4.7 KiB
PHP

<?php
namespace App\Filament\Pages\Monitoring;
use App\Models\OperationRun;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
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()
->formatStateUsing(BadgeRenderer::label(BadgeDomain::OperationRunStatus))
->color(BadgeRenderer::color(BadgeDomain::OperationRunStatus))
->icon(BadgeRenderer::icon(BadgeDomain::OperationRunStatus))
->iconColor(BadgeRenderer::iconColor(BadgeDomain::OperationRunStatus)),
TextColumn::make('outcome')
->badge()
->formatStateUsing(BadgeRenderer::label(BadgeDomain::OperationRunOutcome))
->color(BadgeRenderer::color(BadgeDomain::OperationRunOutcome))
->icon(BadgeRenderer::icon(BadgeDomain::OperationRunOutcome))
->iconColor(BadgeRenderer::iconColor(BadgeDomain::OperationRunOutcome)),
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
]);
}
}