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(), Actions\Action::make('verify') ->label('Verify configuration') ->icon('heroicon-o-check-badge') ->color('primary') ->requiresConfirmation() ->action(function ( Tenant $record, TenantConfigService $configService, TenantPermissionService $permissionService, RbacHealthService $rbacHealthService, AuditLogger $auditLogger, ProviderConnectionResolver $connectionResolver, ProviderNextStepsRegistry $nextStepsRegistry, ) { $resolution = $connectionResolver->resolveDefault($record, 'microsoft'); if (! $resolution->resolved) { $reasonCode = $resolution->effectiveReasonCode(); $nextSteps = $nextStepsRegistry->forReason($record, $reasonCode, $resolution->connection); $notification = Notification::make() ->title('Verification blocked') ->body("Blocked by provider configuration ({$reasonCode}).") ->warning(); foreach ($nextSteps as $index => $step) { if (! is_array($step)) { continue; } $label = is_string($step['label'] ?? null) ? $step['label'] : null; $url = is_string($step['url'] ?? null) ? $step['url'] : null; if ($label === null || $url === null) { continue; } $notification->actions([ Actions\Action::make('next_step_'.$index) ->label($label) ->url($url), ]); break; } $notification->send(); return; } TenantResource::verifyTenant($record, $configService, $permissionService, $rbacHealthService, $auditLogger); }), 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'), ]; } }