label('Restore to Intune') ->icon('heroicon-o-arrow-path-rounded-square') ->color('danger') ->requiresConfirmation() ->modalHeading(fn (PolicyVersion $record): string => "Restore version {$record->version_number} to Intune?") ->modalSubheading('Creates a restore run using this policy version snapshot.') ->form([ Forms\Components\Toggle::make('is_dry_run') ->label('Preview only (dry-run)') ->default(true), ]) ->action(function (PolicyVersion $record, array $data, RestoreService $restoreService) { $tenant = Tenant::current(); $user = auth()->user(); if (! $tenant instanceof Tenant || ! $user instanceof User) { Notification::make() ->title('Missing tenant or user context.') ->danger() ->send(); return; } if ($record->tenant_id !== $tenant->id) { Notification::make() ->title('Policy version belongs to a different tenant') ->danger() ->send(); return; } try { $run = $restoreService->executeFromPolicyVersion( tenant: $tenant, version: $record, dryRun: (bool) ($data['is_dry_run'] ?? true), actorEmail: $user->email, actorName: $user->name, ); } catch (\Throwable $throwable) { Notification::make() ->title('Restore run failed to start') ->body($throwable->getMessage()) ->danger() ->send(); return; } Notification::make() ->title('Restore run started') ->success() ->send(); return redirect(RestoreRunResource::getUrl('view', ['record' => $run])); }); UiEnforcement::forAction($restoreToIntune) ->requireCapability(Capabilities::TENANT_MANAGE) ->apply(); $restoreToIntune ->disabled(function (PolicyVersion $record): bool { if (($record->metadata['source'] ?? null) === 'metadata_only') { return true; } $tenant = Tenant::current(); $user = auth()->user(); if (! $tenant instanceof Tenant || ! $user instanceof User) { return true; } $resolver = app(CapabilityResolver::class); if (! $resolver->isMember($user, $tenant)) { return true; } return ! $resolver->can($user, $tenant, Capabilities::TENANT_MANAGE); }) ->tooltip(function (PolicyVersion $record): ?string { if (($record->metadata['source'] ?? null) === 'metadata_only') { return 'Disabled for metadata-only snapshots (Graph did not provide policy settings).'; } $tenant = Tenant::current(); $user = auth()->user(); if (! $tenant instanceof Tenant || ! $user instanceof User) { return null; } $resolver = app(CapabilityResolver::class); if (! $resolver->isMember($user, $tenant)) { return null; } if (! $resolver->can($user, $tenant, Capabilities::TENANT_MANAGE)) { return UiTooltips::INSUFFICIENT_PERMISSION; } return null; }); return $table ->columns([ Tables\Columns\TextColumn::make('version_number')->sortable(), Tables\Columns\TextColumn::make('captured_at')->dateTime()->sortable(), Tables\Columns\TextColumn::make('created_by')->label('Actor'), Tables\Columns\TextColumn::make('policy_type') ->badge() ->formatStateUsing(TagBadgeRenderer::label(TagBadgeDomain::PolicyType)) ->color(TagBadgeRenderer::color(TagBadgeDomain::PolicyType)) ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('version_number', 'desc') ->filters([]) ->headerActions([]) ->actions([ $restoreToIntune, Actions\ViewAction::make() ->url(fn ($record) => \App\Filament\Resources\PolicyVersionResource::getUrl('view', ['record' => $record])) ->openUrlInNewTab(false), ]) ->bulkActions([]); } }