makeCaptureSnapshotAction()]; } private function makeCaptureSnapshotAction(): Action { $action = UiEnforcement::forAction( Action::make('capture_snapshot') ->label($this->text('resource.capture_snapshot_action')) ->requiresConfirmation() ->modalHeading($this->text('resource.capture_snapshot_modal_heading')) ->modalSubheading($this->text('resource.capture_snapshot_modal_subheading').' '.$this->text('common.source_microsoft_intune')) ->disabled(fn (): bool => $this->record instanceof Policy && $this->record->isProviderMissing()) ->tooltip(fn (): ?string => $this->record instanceof Policy && $this->record->isProviderMissing() ? $this->record->currentBackupBlockedReasonLabel() : null) ->form([ Forms\Components\Checkbox::make('include_assignments') ->label($this->text('resource.capture_snapshot_include_assignments')) ->default(true) ->helperText($this->text('resource.capture_snapshot_include_assignments_helper')), Forms\Components\Checkbox::make('include_scope_tags') ->label($this->text('resource.capture_snapshot_include_scope_tags')) ->default(true) ->helperText($this->text('resource.capture_snapshot_include_scope_tags_helper')), ]) ->action(function (array $data, AuditLogger $auditLogger) { $policy = $this->record; if ($policy instanceof Policy && $policy->isProviderMissing()) { Notification::make() ->title($this->text('resource.capture_snapshot_unavailable_title')) ->body($policy->currentBackupBlockedReasonLabel()) ->warning() ->send(); return; } $tenant = $policy->tenant; $user = auth()->user(); if (! $tenant || ! $user) { Notification::make() ->title('Missing tenant or user context.') ->danger() ->send(); return; } /** @var BulkSelectionIdentity $selection */ $selection = app(BulkSelectionIdentity::class); $selectionIdentity = $selection->fromIds([(string) $policy->getKey()]); /** @var OperationRunService $runs */ $runs = app(OperationRunService::class); $includeAssignments = (bool) ($data['include_assignments'] ?? false); $includeScopeTags = (bool) ($data['include_scope_tags'] ?? false); $opRun = $runs->enqueueBulkOperation( tenant: $tenant, type: 'policy.capture_snapshot', targetScope: [ 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $policy, $user, $includeAssignments, $includeScopeTags): void { CapturePolicySnapshotJob::dispatch( tenantId: (int) $tenant->getKey(), userId: (int) $user->getKey(), policyId: (int) $policy->getKey(), includeAssignments: $includeAssignments, includeScopeTags: $includeScopeTags, createdBy: $user->email ? Str::limit($user->email, 255, '') : null, operationRun: $operationRun, context: [], ); }, initiator: $user, extraContext: [ 'policy_id' => (int) $policy->getKey(), 'include_assignments' => $includeAssignments, 'include_scope_tags' => $includeScopeTags, ], emitQueuedNotification: false, ); if (! $opRun->wasRecentlyCreated) { Notification::make() ->title($this->text('resource.capture_snapshot_in_progress_title')) ->body($this->text('resource.capture_snapshot_in_progress_body')) ->actions([ \Filament\Actions\Action::make('view_run') ->label($this->text('common.open_operation')) ->url(OperationRunLinks::view($opRun, $tenant)), ]) ->info() ->send(); $this->redirect(OperationRunLinks::view($opRun, $tenant)); return; } $auditLogger->log( tenant: $tenant, action: 'policy.capture_snapshot_dispatched', resourceType: 'operation_run', resourceId: (string) $opRun->getKey(), status: 'success', context: [ 'metadata' => [ 'policy_id' => (int) $policy->getKey(), 'operation_run_id' => (int) $opRun->getKey(), 'include_assignments' => $includeAssignments, 'include_scope_tags' => $includeScopeTags, ], ], actorId: (int) $user->getKey(), actorEmail: $user->email, actorName: $user->name, ); OperationUxPresenter::queuedToast('policy.capture_snapshot') ->actions([ \Filament\Actions\Action::make('view_run') ->label($this->text('common.open_operation')) ->url(OperationRunLinks::view($opRun, $tenant)), ]) ->send(); $this->redirect(OperationRunLinks::view($opRun, $tenant)); }) ->color('primary') ) ->requireCapability(Capabilities::TENANT_SYNC) ->tooltip($this->text('resource.capture_snapshot_permission_tooltip')) ->preserveDisabled() ->apply(); if (! $action instanceof Action) { throw new \RuntimeException('Capture snapshot action must resolve to a Filament action.'); } return $action; } private function text(string $key, array $replace = []): string { return __('localization.policy.'.$key, $replace); } }