'operations', 'surfaceType' => 'simple_monitoring', 'stateFields' => [ [ 'stateKey' => 'environment_id', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true, 'tenantSensitive' => true, 'invalidFallback' => 'discard_and_continue', ], [ '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' => ['environment_id', 'managed_environment_id', 'type', 'initiator_name'], 'invalidRequestedStateFallback' => 'discard_and_continue', ], 'inspectContract' => [ 'primaryModel' => 'none', 'selectedStateKey' => null, 'openedBy' => [], 'presentation' => 'none', 'shareable' => false, 'invalidSelectionFallback' => 'discard_and_continue', ], 'shareableStateKeys' => ['environment_id', '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 static function canAccess(): bool { if (Filament::getCurrentPanel()?->getId() !== 'admin') { return false; } $user = auth()->user(); if (! $user instanceof User) { return false; } $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); if (! is_int($workspaceId)) { return false; } $workspace = Workspace::query()->whereKey($workspaceId)->first(); if (! $workspace instanceof Workspace) { return false; } return true; } public function mount(): void { $user = auth()->user(); $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); if (! $user instanceof User || ! is_int($workspaceId)) { abort(404); } $workspace = Workspace::query()->whereKey($workspaceId)->first(); if (! $workspace instanceof Workspace) { abort(404); } /** @var WorkspaceCapabilityResolver $resolver */ $resolver = app(WorkspaceCapabilityResolver::class); if (! $resolver->isMember($user, $workspace)) { abort(404); } $this->navigationContextPayload = is_array(request()->query('nav')) ? request()->query('nav') : null; $this->resetWorkspaceHubEnvironmentFilterStateForCleanEntry(request()); $this->mountInteractsWithTable(); $this->resetWorkspaceHubEnvironmentFilterStateForCleanEntry(request()); $this->applyRequestedDashboardPrefilter(); } protected function getHeaderWidgets(): array { return []; } /** * @return array */ protected function getHeaderActions(): array { $operateHubShell = app(OperateHubShell::class); $navigationContext = $this->navigationContext(); $activeEnvironment = $this->currentTenantFilterId() === null ? $operateHubShell->activeEntitledTenant(request()) : null; $actions = []; if ($activeEnvironment instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_scope_operations') ->label($operateHubShell->scopeLabel(request())) ->color('gray') ->disabled(); } 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 ($activeEnvironment instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_back_to_tenant_operations') ->label('Back to '.$activeEnvironment->name) ->icon('heroicon-o-arrow-left') ->color('gray') ->url(ManagedEnvironmentLinks::viewUrl($activeEnvironment)); } if ($activeEnvironment instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_show_all_tenants') ->label(__('localization.shell.show_all_environments')) ->color('gray') ->action(function (): void { Filament::setTenant(null, true); app(WorkspaceContext::class)->clearLastEnvironmentId(request()); $this->removeTableFilter('managed_environment_id'); $this->redirect(OperationRunLinks::index(allTenants: true)); }); } 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(); $filteredTenant = $this->filteredTenant(); $activeEnvironment = $filteredTenant instanceof ManagedEnvironment ? null : $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 ($activeEnvironment instanceof ManagedEnvironment) { $returnLabel = 'Back to '.$activeEnvironment->name; $returnBody = 'Return to the environment dashboard when you need environment-specific context outside this workspace operations view.'; } return [ 'scope_label' => $operateHubShell->scopeLabel(request()), 'scope_body' => $filteredTenant instanceof ManagedEnvironment ? 'Filtered to one environment in this workspace.' : ($activeEnvironment instanceof ManagedEnvironment ? 'Showing the active environment inside this workspace.' : 'Showing workspace-wide execution records across entitled environments.'), 'return_label' => $returnLabel, 'return_body' => $returnBody, 'scope_reset_label' => $activeEnvironment instanceof ManagedEnvironment ? __('localization.shell.show_all_environments') : null, 'scope_reset_body' => $activeEnvironment instanceof ManagedEnvironment ? 'Reset Operations Hub back to workspace-wide execution records when environment-specific context is no longer needed.' : null, 'inspect_body' => 'Open a run from the table to enter the canonical monitoring detail viewer.', ]; } /** * @return array{ * question:string, * has_attention:bool, * selected_operation:array|null, * diagnostics:array{label:string,state:string,body:string} * } */ public function decisionWorkbench(): array { $selectedOperation = $this->selectedWorkbenchOperation(); $needsAttention = $this->summaryCount( fn (Builder $query): Builder => $query->dashboardNeedsFollowUp(), ); return [ 'question' => 'Which operation needs attention now?', 'has_attention' => $needsAttention > 0, 'selected_operation' => $selectedOperation instanceof OperationRun ? $this->workbenchOperationPayload($selectedOperation, $needsAttention > 0) : null, 'diagnostics' => [ 'label' => 'Diagnostics', 'state' => 'Collapsed', 'body' => 'Raw context, provider payloads, stack traces, debug metadata, and support diagnostics stay on authorized operation detail surfaces.', ], ]; } private function selectedWorkbenchOperation(): ?OperationRun { $attentionRun = $this->topOperationFromQuery( fn (Builder $query): Builder => $query->dashboardNeedsFollowUp(), sortByAttention: true, ); if ($attentionRun instanceof OperationRun) { return $attentionRun; } $activeRun = $this->topOperationFromQuery( fn (Builder $query): Builder => $query->active(), ); if ($activeRun instanceof OperationRun) { return $activeRun; } return $this->topOperationFromQuery(); } private function topOperationFromQuery(?callable $scope = null, bool $sortByAttention = false): ?OperationRun { $query = $this->scopedSummaryQuery(); if (! $query instanceof Builder) { return null; } $query ->with('tenant') ->latest('id') ->limit(50); if ($scope !== null) { $query = $scope($query); } /** @var Collection $runs */ $runs = $query->get(); if ($runs->isEmpty()) { return null; } if (! $sortByAttention) { return $runs->first(); } return $runs ->sort(function (OperationRun $left, OperationRun $right): int { return [ $this->attentionPriority($right), $right->created_at?->getTimestamp() ?? 0, (int) $right->getKey(), ] <=> [ $this->attentionPriority($left), $left->created_at?->getTimestamp() ?? 0, (int) $left->getKey(), ]; }) ->first(); } private function attentionPriority(OperationRun $run): int { if ((string) $run->outcome === OperationRunOutcome::Blocked->value) { return 50; } if ((string) $run->outcome === OperationRunOutcome::Failed->value) { return 40; } if ((string) $run->outcome === OperationRunOutcome::PartiallySucceeded->value) { return 30; } if ($run->problemClass() === OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION) { return 20; } if ($run->problemClass() === OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP) { return 10; } return 0; } /** * @return array */ private function workbenchOperationPayload(OperationRun $run, bool $hasAttention): array { $progress = OperationRunProgressContract::forRun($run); $decisionTruth = OperationUxPresenter::decisionZoneTruth($run); $actionDecision = OperationRunResource::actionDecision($run); $primaryAction = is_array($actionDecision['primary_action'] ?? null) ? $actionDecision['primary_action'] : null; $tenant = $run->tenant; return [ 'id' => (int) $run->getKey(), 'title' => OperationCatalog::label((string) $run->type), 'identifier' => OperationRunLinks::identifier($run), 'status_label' => $this->humanizeState((string) $run->status), 'outcome_label' => $this->humanizeState((string) $run->outcome), 'attention_label' => $hasAttention && $run->requiresOperatorReview() ? 'Needs attention' : ($run->isCurrentlyActive() ? 'Active operation' : 'No attention needed'), 'reason' => $this->operationReason($run, $decisionTruth), 'impact' => $this->operationImpact($run), 'environment' => $tenant instanceof ManagedEnvironment ? (string) $tenant->name : 'Workspace-level operation', 'timing' => $this->operationTiming($run), 'proof_label' => 'Operation detail available', 'proof_body' => (string) ($actionDecision['attention_reason'] ?? 'Open operation for stored proof, related links, and authorized diagnostics.'), 'primary_action_label' => is_string($primaryAction['label'] ?? null) ? (string) $primaryAction['label'] : OperationRunLinks::openLabel(), 'primary_action_url' => OperationRunLinks::withNavigationContext( OperationRunResource::primaryActionUrl($run), OperationRunLinks::operationsIndexNavigationContext($run, $this->operationsUrl()), ), 'progress' => $progress, 'progress_label' => is_string($progress['label'] ?? null) ? $progress['label'] : null, 'show_progress_bar' => ($progress['display'] ?? null) === OperationRunProgressContract::COUNTED, 'progress_percent' => is_int($progress['percent'] ?? null) ? $progress['percent'] : null, 'outcome_guidance' => OperationUxPresenter::surfaceGuidance($run) ?? 'Review the operation detail for the next safe step.', 'diagnostics_available' => ! empty($run->failure_summary) || ! empty($run->context), ]; } /** * @param array $decisionTruth */ private function operationReason(OperationRun $run, array $decisionTruth): string { $attentionNote = $decisionTruth['attentionNote'] ?? null; if (is_string($attentionNote) && trim($attentionNote) !== '') { return $attentionNote; } $lifecycleLabel = $decisionTruth['freshnessLabel'] ?? null; if (is_string($lifecycleLabel) && trim($lifecycleLabel) !== '') { return $lifecycleLabel; } return match ((string) $run->outcome) { OperationRunOutcome::Blocked->value => 'The operation is blocked by an execution prerequisite recorded on the run.', OperationRunOutcome::Failed->value => 'The operation finished with a failed outcome and needs review before retrying or relying on the result.', OperationRunOutcome::PartiallySucceeded->value => 'The operation finished partially and needs follow-up on affected items.', OperationRunOutcome::Succeeded->value => 'The operation completed successfully. This is execution truth only, not an environment health claim.', default => $run->isCurrentlyActive() ? 'The operation is still active. Progress is shown only from trusted run counts.' : 'Reason unavailable from stored operation truth.', }; } private function operationImpact(OperationRun $run): string { if ($run->problemClass() === OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION) { return 'Follow-up is needed before starting overlapping work for this operation scope.'; } return match ((string) $run->outcome) { OperationRunOutcome::Blocked->value => 'Execution did not proceed; inspect the blocked prerequisite before retrying from the source surface.', OperationRunOutcome::Failed->value => 'The expected result may be incomplete or unavailable until the failure is reviewed.', OperationRunOutcome::PartiallySucceeded->value => 'Some work completed, but affected items may still require review or a targeted rerun.', OperationRunOutcome::Succeeded->value => 'Execution completed; use operation detail for proof rather than treating this as governance health.', default => $run->isCurrentlyActive() ? 'Work is in progress; avoid duplicate starts until this run settles or becomes stale.' : 'Impact unavailable from stored operation truth.', }; } private function operationTiming(OperationRun $run): string { if ($run->completed_at !== null) { return 'Completed '.$run->completed_at->diffForHumans(); } if ($run->started_at !== null) { return 'Started '.$run->started_at->diffForHumans(); } if ($run->created_at !== null) { return 'Created '.$run->created_at->diffForHumans(); } return 'Timing unavailable'; } private function summaryCount(callable $scope): int { $query = $this->scopedSummaryQuery(); if (! $query instanceof Builder) { return 0; } return (int) $scope($query)->count(); } private function humanizeState(string $state): string { $label = OperationRunOutcome::uiLabels(includeReserved: true)[$state] ?? null; if (is_string($label)) { return $label; } return Str::of($state)->replace('_', ' ')->headline()->toString(); } 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, ]); } /** * @return array{label: string, clear_url: string}|null */ public function environmentFilterChip(): ?array { $tenant = $this->filteredTenant(); if (! $tenant instanceof ManagedEnvironment) { return null; } return [ 'label' => (string) $tenant->name, 'clear_url' => $this->cleanWorkspaceHubUrl(route('admin.operations.index', [ 'workspace' => app(WorkspaceContext::class)->currentWorkspace(request()), ])), ]; } 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) ->recordUrl(fn (OperationRun $record): string => OperationRunLinks::viewFromOperationsIndex( $record, $this->operationsUrl(), )) ->query(function (): Builder { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); $tenantFilter = $this->currentTenantFilterId(); $allowedTenantIds = $this->allowedTenantIdsForWorkspaceScope($workspaceId); $query = OperationRun::query() ->with(['tenant', '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( $workspaceId && $allowedTenantIds !== null, function (Builder $query) use ($allowedTenantIds): Builder { return $query->where(function (Builder $query) use ($allowedTenantIds): void { $query->whereNull('managed_environment_id'); if ($allowedTenantIds !== []) { $query->orWhereIn('managed_environment_id', $allowedTenantIds); } }); }, ) ->when( $tenantFilter !== null, fn (Builder $query): Builder => $query->where('managed_environment_id', $tenantFilter), ); return $this->applyActiveTab($query); }); } /** * @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->currentTerminalFollowUp(), '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(); $allowedTenantIds = $this->allowedTenantIdsForWorkspaceScope($workspaceId); return OperationRun::query() ->where('workspace_id', (int) $workspaceId) ->when( $allowedTenantIds !== null, function (Builder $query) use ($allowedTenantIds): Builder { return $query->where(function (Builder $query) use ($allowedTenantIds): void { $query->whereNull('managed_environment_id'); if ($allowedTenantIds !== []) { $query->orWhereIn('managed_environment_id', $allowedTenantIds); } }); }, ) ->when( $tenantFilter !== null, fn (Builder $query): Builder => $query->where('managed_environment_id', $tenantFilter), ); } private function applyRequestedDashboardPrefilter(): void { $workspace = app(WorkspaceContext::class)->currentWorkspace(request()); if ($workspace instanceof Workspace) { $filter = WorkspaceHubEnvironmentFilter::fromRequest(request(), $workspace); if ($filter instanceof WorkspaceHubEnvironmentFilter) { $requestedTenantId = $this->normalizeEntitledTenantFilter($filter->environmentId()); if ($requestedTenantId === null) { abort(404); } $tenantId = (string) $requestedTenantId; $this->tableFilters['managed_environment_id']['value'] = $tenantId; $this->tableDeferredFilters['managed_environment_id']['value'] = $tenantId; } } $requestedOperationType = request()->query('operation_type'); if (is_string($requestedOperationType) && trim($requestedOperationType) !== '') { $canonicalOperationType = OperationCatalog::canonicalCode($requestedOperationType); if (OperationCatalog::rawValuesForCanonical($canonicalOperationType) !== []) { $this->tableFilters['type']['value'] = $canonicalOperationType; $this->tableDeferredFilters['type']['value'] = $canonicalOperationType; } } $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 operationsUrl(array $overrides = []): string { $parameters = array_merge( ['workspace' => app(WorkspaceContext::class)->currentWorkspace(request())], $this->navigationContext()?->toQuery() ?? [], [ 'environment_id' => $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(CanonicalAdminEnvironmentFilterState::class)->currentFilterValue( $this->getTableFiltersSessionKey(), $this->tableFilters ?? [], request(), ); return $this->normalizeEntitledTenantFilter($tenantFilter); } private function filteredTenant(): ?ManagedEnvironment { $tenantId = $this->currentTenantFilterId(); if (! is_int($tenantId)) { return null; } foreach ($this->authorizedTenants() as $tenant) { if ((int) $tenant->getKey() === $tenantId) { return $tenant; } } return null; } /** * Null means inherited access to all environments in the workspace. * * @return list|null */ private function allowedTenantIdsForWorkspaceScope(mixed $workspaceId): ?array { $user = auth()->user(); if (! $user instanceof User || ! is_int($workspaceId)) { return []; } $allowedIds = app(ManagedEnvironmentAccessScopeResolver::class) ->allowedManagedEnvironmentIdsForWorkspace($user, $workspaceId); if ($allowedIds === null) { return null; } return array_values(array_unique(array_map('intval', $allowedIds))); } 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 (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === $workspaceId) ->filter(static fn (ManagedEnvironment $tenant): bool => $tenant->isActive()) ->map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->values() ->all(); } /** * @return array */ private function authorizedTenants(): 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 (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === $workspaceId) ->filter(static fn (ManagedEnvironment $tenant): bool => $tenant->isActive()) ->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, ]; } }