'operations', 'surfaceType' => 'simple_monitoring', 'stateFields' => [ [ 'stateKey' => 'tenant_id', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true, 'tenantSensitive' => true, 'invalidFallback' => 'discard_and_continue', ], [ 'stateKey' => 'tenant_scope', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true, 'tenantSensitive' => true, 'invalidFallback' => 'reset_to_default_scope', ], [ 'stateKey' => 'problemClass', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'scoped_deeplink', 'shareable' => true, 'restorableOnRefresh' => true, 'tenantSensitive' => false, 'invalidFallback' => 'discard_and_continue', ], [ 'stateKey' => 'activeTab', 'stateClass' => 'active', 'carrier' => 'livewire_property', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true, 'tenantSensitive' => false, 'invalidFallback' => 'discard_and_continue', ], [ 'stateKey' => 'tableFilters', 'stateClass' => 'shareable_restorable', 'carrier' => 'session', 'queryRole' => 'unsupported', 'shareable' => false, 'restorableOnRefresh' => true, 'tenantSensitive' => true, 'invalidFallback' => 'discard_and_continue', ], ], 'hydrationRule' => [ 'precedenceOrder' => ['query', 'session', 'default'], 'appliesOnInitialMountOnly' => true, 'activeStateBecomesAuthoritativeAfterMount' => true, 'clearsOnTenantSwitch' => ['tenant_id', 'type', 'initiator_name'], 'invalidRequestedStateFallback' => 'discard_and_continue', ], 'inspectContract' => [ 'primaryModel' => 'none', 'selectedStateKey' => null, 'openedBy' => [], 'presentation' => 'none', 'shareable' => false, 'invalidSelectionFallback' => 'discard_and_continue', ], 'shareableStateKeys' => ['tenant_id', 'tenant_scope', 'problemClass', 'activeTab'], 'localOnlyStateKeys' => [], ]; public string $activeTab = 'all'; /** * @var array|null */ public ?array $navigationContextPayload = null; 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 static function actionSurfaceDeclaration(): ActionSurfaceDeclaration { return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::RunLog, ActionSurfaceType::ReadOnlyRegistryReport) ->withDefaults(new ActionSurfaceDefaults( moreGroupLabel: 'More', exportIsDefaultBulkActionForReadOnly: false, )) ->satisfy(ActionSurfaceSlot::ListHeader, 'Header actions preserve scope context and return navigation for the monitoring operations list.') ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value) ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Operation runs remain immutable on the monitoring list and intentionally omit bulk actions.') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'The empty state explains when no operation runs exist for the active workspace scope.') ->exempt(ActionSurfaceSlot::DetailHeader, 'Row navigation opens the canonical tenantless operation detail page, which owns header actions.'); } /** * @return array */ public static function monitoringPageStateContract(): array { return self::MONITORING_PAGE_STATE_CONTRACT; } public function mount(): void { $this->navigationContextPayload = is_array(request()->query('nav')) ? request()->query('nav') : null; $this->applyRequestedTenantScope(); app(CanonicalAdminTenantFilterState::class)->sync( $this->getTableFiltersSessionKey(), ['type', 'initiator_name'], request(), ); $this->mountInteractsWithTable(); $this->applyRequestedDashboardPrefilter(); } protected function getHeaderWidgets(): array { return [ OperationsKpiHeader::class, ]; } /** * @return array */ protected function getHeaderActions(): array { $operateHubShell = app(OperateHubShell::class); $navigationContext = $this->navigationContext(); $actions = [ Action::make('operate_hub_scope_operations') ->label($operateHubShell->scopeLabel(request())) ->color('gray') ->disabled(), ]; $activeTenant = $operateHubShell->activeEntitledTenant(request()); if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) { $actions[] = Action::make('operate_hub_back_to_origin_operations') ->label($navigationContext->backLinkLabel) ->icon('heroicon-o-arrow-left') ->color('gray') ->url($navigationContext->backLinkUrl); } elseif ($activeTenant instanceof Tenant) { $actions[] = Action::make('operate_hub_back_to_tenant_operations') ->label('Back to '.$activeTenant->name) ->icon('heroicon-o-arrow-left') ->color('gray') ->url(\App\Filament\Pages\TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant)); } if ($activeTenant instanceof Tenant) { $actions[] = Action::make('operate_hub_show_all_tenants') ->label('Show all tenants') ->color('gray') ->action(function (): void { Filament::setTenant(null, true); app(WorkspaceContext::class)->clearLastTenantId(request()); $this->removeTableFilter('tenant_id'); $this->redirect('/admin/operations'); }); } return $actions; } /** * @return array{ * scope_label: string, * scope_body: string, * return_label: ?string, * return_body: ?string, * scope_reset_label: ?string, * scope_reset_body: ?string, * inspect_body: string * } */ public function landingHierarchySummary(): array { $operateHubShell = app(OperateHubShell::class); $navigationContext = $this->navigationContext(); $activeTenant = $operateHubShell->activeEntitledTenant(request()); $returnLabel = null; $returnBody = null; if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) { $returnLabel = $navigationContext->backLinkLabel; $returnBody = 'Return to the originating monitoring surface without competing with the current tab, filters, or row inspection flow.'; } elseif ($activeTenant instanceof Tenant) { $returnLabel = 'Back to '.$activeTenant->name; $returnBody = 'Return to the tenant dashboard when you need tenant-specific context outside this workspace monitoring landing.'; } return [ 'scope_label' => $operateHubShell->scopeLabel(request()), 'scope_body' => $activeTenant instanceof Tenant ? 'The landing is currently narrowed to one tenant inside the active workspace.' : 'The landing is currently showing workspace-wide monitoring across all entitled tenants.', 'return_label' => $returnLabel, 'return_body' => $returnBody, 'scope_reset_label' => $activeTenant instanceof Tenant ? 'Show all tenants' : null, 'scope_reset_body' => $activeTenant instanceof Tenant ? 'Reset the landing back to workspace-wide monitoring when tenant-specific context is no longer needed.' : null, 'inspect_body' => 'Open a run from the table to enter the canonical monitoring detail viewer.', ]; } public function tabUrl(string $tab): string { $normalizedTab = in_array($tab, self::supportedTabs(), true) ? $tab : 'all'; return $this->operationsUrl([ 'activeTab' => $normalizedTab !== 'all' ? $normalizedTab : null, 'problemClass' => in_array($normalizedTab, self::problemClassTabs(), true) ? $normalizedTab : null, ]); } private function navigationContext(): ?CanonicalNavigationContext { if (! is_array($this->navigationContextPayload)) { return CanonicalNavigationContext::fromRequest(request()); } return CanonicalNavigationContext::fromPayload($this->navigationContextPayload); } public function updatedActiveTab(): void { $this->resetPage(); } public function table(Table $table): Table { return OperationRunResource::table($table) ->query(function (): Builder { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); $tenantFilter = $this->currentTenantFilterId(); $query = OperationRun::query() ->with('user') ->latest('id') ->when( $workspaceId, fn (Builder $query): Builder => $query->where('workspace_id', (int) $workspaceId), ) ->when( ! $workspaceId, fn (Builder $query): Builder => $query->whereRaw('1 = 0'), ) ->when( $tenantFilter !== null, fn (Builder $query): Builder => $query->where('tenant_id', $tenantFilter), ); return $this->applyActiveTab($query); }); } private function applyRequestedTenantScope(): void { if (! $this->shouldForceWorkspaceWideTenantScope()) { return; } Filament::setTenant(null, true); app(WorkspaceContext::class)->clearLastTenantId(request()); } /** * @return array{likely_stale:int,reconciled:int} */ public function lifecycleVisibilitySummary(): array { $baseQuery = $this->scopedSummaryQuery(); if (! $baseQuery instanceof Builder) { return [ 'likely_stale' => 0, 'reconciled' => 0, ]; } $reconciled = (clone $baseQuery) ->whereNotNull('context->reconciliation->reconciled_at') ->count(); $policy = app(OperationLifecyclePolicy::class); $likelyStale = (clone $baseQuery) ->likelyStale($policy) ->count(); return [ 'likely_stale' => $likelyStale, 'reconciled' => $reconciled, ]; } private function applyActiveTab(Builder $query): Builder { return match ($this->activeTab) { 'active' => $query->healthyActive(), OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION => $query->activeStaleAttention(), OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP => $query->terminalFollowUp(), 'blocked' => $query->dashboardNeedsFollowUp(), 'succeeded' => $query ->where('status', OperationRunStatus::Completed->value) ->where('outcome', OperationRunOutcome::Succeeded->value), 'partial' => $query ->where('status', OperationRunStatus::Completed->value) ->where('outcome', OperationRunOutcome::PartiallySucceeded->value), 'failed' => $query ->where('status', OperationRunStatus::Completed->value) ->where('outcome', OperationRunOutcome::Failed->value), default => $query, }; } private function scopedSummaryQuery(): ?Builder { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); if (! $workspaceId) { return null; } $tenantFilter = $this->currentTenantFilterId(); return OperationRun::query() ->where('workspace_id', (int) $workspaceId) ->when( $tenantFilter !== null, fn (Builder $query): Builder => $query->where('tenant_id', $tenantFilter), ); } private function applyRequestedDashboardPrefilter(): void { if (! $this->shouldForceWorkspaceWideTenantScope()) { $requestedTenantId = $this->normalizeEntitledTenantFilter(request()->query('tenant_id')); if ($requestedTenantId !== null) { $tenantId = (string) $requestedTenantId; $this->tableFilters['tenant_id']['value'] = $tenantId; $this->tableDeferredFilters['tenant_id']['value'] = $tenantId; } } $requestedProblemClass = request()->query('problemClass'); if (in_array($requestedProblemClass, self::problemClassTabs(), true)) { $this->activeTab = (string) $requestedProblemClass; return; } $requestedTab = request()->query('activeTab'); if (in_array($requestedTab, self::supportedTabs(), true)) { $this->activeTab = (string) $requestedTab; } } private function shouldForceWorkspaceWideTenantScope(): bool { return request()->query('tenant_scope') === 'all'; } private function operationsUrl(array $overrides = []): string { $parameters = array_merge( $this->navigationContext()?->toQuery() ?? [], [ 'tenant_scope' => $this->shouldForceWorkspaceWideTenantScope() ? 'all' : null, 'tenant_id' => $this->shouldForceWorkspaceWideTenantScope() ? null : $this->currentTenantFilterId(), 'activeTab' => $this->activeTab !== 'all' ? $this->activeTab : null, 'problemClass' => in_array($this->activeTab, self::problemClassTabs(), true) ? $this->activeTab : null, ], $overrides, ); return route( 'admin.operations.index', array_filter($parameters, static fn (mixed $value): bool => $value !== null && $value !== '' && $value !== []), ); } private function currentTenantFilterId(): ?int { $tenantFilter = app(CanonicalAdminTenantFilterState::class)->currentFilterValue( $this->getTableFiltersSessionKey(), $this->tableFilters ?? [], request(), ); return $this->normalizeEntitledTenantFilter($tenantFilter); } private function normalizeEntitledTenantFilter(mixed $value): ?int { if (! is_numeric($value)) { return null; } $tenantId = (int) $value; return in_array($tenantId, $this->authorizedTenantIds(), true) ? $tenantId : null; } /** * @return list */ private function authorizedTenantIds(): array { $user = auth()->user(); $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); if (! $user instanceof User || ! is_int($workspaceId)) { return []; } return collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) ->filter(static fn (Tenant $tenant): bool => (int) $tenant->workspace_id === $workspaceId) ->filter(static fn (Tenant $tenant): bool => $tenant->isActive()) ->map(static fn (Tenant $tenant): int => (int) $tenant->getKey()) ->values() ->all(); } /** * @return list */ private static function supportedTabs(): array { return [ 'all', 'active', 'blocked', 'succeeded', 'partial', 'failed', ...self::problemClassTabs(), ]; } /** * @return list */ private static function problemClassTabs(): array { return [ OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ]; } }