label('Capture snapshot') ->requiresConfirmation() ->modalHeading('Capture snapshot now') ->modalSubheading('This queues a background job that fetches the latest configuration from Microsoft Graph and stores a new policy version.') ->form([ Forms\Components\Checkbox::make('include_assignments') ->label('Include assignments') ->default(true) ->helperText('Captures assignment include/exclude targeting and filters.'), Forms\Components\Checkbox::make('include_scope_tags') ->label('Include scope tags') ->default(true) ->helperText('Captures policy scope tag IDs.'), ]) ->action(function (array $data) { $policy = $this->record; $tenant = $policy->tenant; $user = auth()->user(); if (! $tenant || ! $user) { Notification::make() ->title('Missing tenant or user context.') ->danger() ->send(); return; } $idempotencyKey = RunIdempotency::buildKey( tenantId: $tenant->getKey(), operationType: 'policy.capture_snapshot', targetId: $policy->getKey() ); $existingRun = RunIdempotency::findActiveBulkOperationRun( tenantId: $tenant->getKey(), idempotencyKey: $idempotencyKey ); if ($existingRun) { Notification::make() ->title('Snapshot already in progress') ->body('An active run already exists for this policy. Opening run details.') ->actions([ \Filament\Actions\Action::make('view_run') ->label('View run') ->url(BulkOperationRunResource::getUrl('view', ['record' => $existingRun], tenant: $tenant)), ]) ->info() ->send(); $this->redirect(BulkOperationRunResource::getUrl('view', ['record' => $existingRun], tenant: $tenant)); return; } $bulkOperationService = app(BulkOperationService::class); $run = $bulkOperationService->createRun( tenant: $tenant, user: $user, resource: 'policies', action: 'capture_snapshot', itemIds: [(string) $policy->getKey()], totalItems: 1 ); $run->update(['idempotency_key' => $idempotencyKey]); CapturePolicySnapshotJob::dispatch( bulkOperationRunId: $run->getKey(), policyId: $policy->getKey(), includeAssignments: (bool) ($data['include_assignments'] ?? false), includeScopeTags: (bool) ($data['include_scope_tags'] ?? false), createdBy: $user->email ? Str::limit($user->email, 255, '') : null ); Notification::make() ->title('Snapshot queued') ->body('A background job has been queued. You can monitor progress in the run details.') ->actions([ \Filament\Actions\Action::make('view_run') ->label('View run') ->url(BulkOperationRunResource::getUrl('view', ['record' => $run], tenant: $tenant)), ]) ->success() ->send(); $this->redirect(BulkOperationRunResource::getUrl('view', ['record' => $run], tenant: $tenant)); }) ->color('primary'), ]; } }