label('Provider connections') ->icon('heroicon-o-link') ->url(fn (Tenant $record): string => ProviderConnectionResource::getUrl('index', ['tenant' => $record->external_id], panel: 'admin')) ) ->requireCapability(Capabilities::PROVIDER_VIEW) ->apply(), UiEnforcement::forAction( Actions\Action::make('edit') ->label('Edit') ->icon('heroicon-o-pencil-square') ->url(fn (Tenant $record): string => TenantResource::getUrl('edit', ['record' => $record])) ) ->requireCapability(Capabilities::TENANT_MANAGE) ->apply(), Actions\Action::make('admin_consent') ->label('Admin consent') ->icon('heroicon-o-clipboard-document') ->url(fn (Tenant $record) => TenantResource::adminConsentUrl($record)) ->visible(fn (Tenant $record) => TenantResource::adminConsentUrl($record) !== null) ->openUrlInNewTab(), Actions\Action::make('open_in_entra') ->label('Open in Entra') ->icon('heroicon-o-arrow-top-right-on-square') ->url(fn (Tenant $record) => TenantResource::entraUrl($record)) ->visible(fn (Tenant $record) => TenantResource::entraUrl($record) !== null) ->openUrlInNewTab(), UiEnforcement::forAction( Actions\Action::make('verify') ->label('Verify configuration') ->icon('heroicon-o-check-badge') ->color('primary') ->requiresConfirmation() ->visible(fn (Tenant $record): bool => $record->isActive()) ->action(function ( Tenant $record, StartVerification $verification, ): void { $user = auth()->user(); if (! $user instanceof User) { abort(403); } if (! $user->canAccessTenant($record)) { abort(404); } $result = $verification->providerConnectionCheckForTenant( tenant: $record, initiator: $user, extraContext: [ 'surface' => [ 'kind' => 'tenant_view_header', ], ], ); $runUrl = OperationRunLinks::tenantlessView($result->run); if ($result->status === 'scope_busy') { Notification::make() ->title('Another operation is already running') ->body('Please wait for the active run to finish.') ->warning() ->actions([ Actions\Action::make('view_run') ->label('View run') ->url($runUrl), ]) ->send(); return; } if ($result->status === 'deduped') { Notification::make() ->title('Verification already running') ->body('A verification run is already queued or running.') ->warning() ->actions([ Actions\Action::make('view_run') ->label('View run') ->url($runUrl), ]) ->send(); return; } if ($result->status === 'blocked') { $reasonCode = is_string($result->run->context['reason_code'] ?? null) ? (string) $result->run->context['reason_code'] : 'unknown_error'; $actions = [ Actions\Action::make('view_run') ->label('View run') ->url($runUrl), ]; $nextSteps = $result->run->context['next_steps'] ?? []; $nextSteps = is_array($nextSteps) ? $nextSteps : []; foreach ($nextSteps as $index => $step) { if (! is_array($step)) { continue; } $label = is_string($step['label'] ?? null) ? trim((string) $step['label']) : ''; $url = is_string($step['url'] ?? null) ? trim((string) $step['url']) : ''; if ($label === '' || $url === '') { continue; } $actions[] = Actions\Action::make('next_step_'.$index) ->label($label) ->url($url); break; } Notification::make() ->title('Verification blocked') ->body("Blocked by provider configuration ({$reasonCode}).") ->warning() ->actions($actions) ->send(); return; } Notification::make() ->title('Verification started') ->success() ->actions([ Actions\Action::make('view_run') ->label('View run') ->url($runUrl), ]) ->send(); }), ) ->preserveVisibility() ->requireCapability(Capabilities::PROVIDER_RUN) ->apply(), TenantResource::rbacAction(), UiEnforcement::forAction( Actions\Action::make('archive') ->label('Deactivate') ->color('danger') ->icon('heroicon-o-archive-box-x-mark') ->visible(fn (Tenant $record): bool => ! $record->trashed()) ->action(function (Tenant $record, AuditLogger $auditLogger): void { $record->delete(); $auditLogger->log( tenant: $record, action: 'tenant.archived', resourceType: 'tenant', resourceId: (string) $record->getKey(), status: 'success', context: [ 'metadata' => [ 'internal_tenant_id' => (int) $record->getKey(), 'tenant_guid' => (string) $record->tenant_id, ], ] ); Notification::make() ->title('Tenant deactivated') ->body('The tenant has been archived and hidden from lists.') ->success() ->send(); }) ) ->preserveVisibility() ->requireCapability(Capabilities::TENANT_DELETE) ->destructive() ->apply(), ]) ->label('Actions') ->icon('heroicon-o-ellipsis-vertical') ->color('gray'), ]; } }