openRenderedReportAction([ 'source_surface' => CustomerReviewWorkspace::SOURCE_SURFACE, CustomerReviewWorkspace::DETAIL_CONTEXT_QUERY_KEY => 1, 'review_id' => $this->record->environment_review_id, 'tenant_filter_id' => request()->query('tenant_filter_id'), 'interpretation_version' => $this->record->environmentReview?->controlInterpretationVersion(), ], 'primary'), Actions\Action::make('download') ->label(fn (): string => ReviewPackResource::downloadActionLabelFor($this->record)) ->icon('heroicon-o-arrow-down-tray') ->color('gray') ->visible(fn (): bool => $this->record->status === ReviewPackStatus::Ready->value) ->url(fn (): string => app(ReviewPackService::class)->generateDownloadUrl($this->record, [ 'source_surface' => CustomerReviewWorkspace::SOURCE_SURFACE, ])) ->openUrlInNewTab(), ]; } $regenerateAction = UiEnforcement::forAction( Actions\Action::make('regenerate') ->label('Regenerate') ->icon('heroicon-o-arrow-path') ->color('primary') ->disabled(fn (): bool => ReviewPackResource::reviewPackGenerationBlocked($this->record->tenant)) ->requiresConfirmation() ->modalDescription('This will generate a new review pack with the same options. The current pack will remain available until it expires.') ->action(function (array $data): void { /** @var ReviewPack $record */ $record = $this->record; $options = array_merge($record->options ?? [], [ 'include_pii' => (bool) ($data['include_pii'] ?? ($record->options['include_pii'] ?? true)), 'include_operations' => (bool) ($data['include_operations'] ?? ($record->options['include_operations'] ?? true)), ]); ReviewPackResource::executeGeneration($options); }) ->form(function (): array { /** @var ReviewPack $record */ $record = $this->record; $currentOptions = $record->options ?? []; return [ Section::make('Pack options') ->schema([ Toggle::make('include_pii') ->label('Include PII') ->helperText('Include personally identifiable information in the export.') ->default((bool) ($currentOptions['include_pii'] ?? true)), Toggle::make('include_operations') ->label('Include operations') ->helperText('Include recent operation history in the export.') ->default((bool) ($currentOptions['include_operations'] ?? true)), ]), ]; }) ) ->requireCapability(Capabilities::REVIEW_PACK_MANAGE) ->preserveDisabled() ->apply(); $regenerateAction->tooltip(fn (): ?string => ReviewPackResource::reviewPackGenerationActionTooltip($this->record->tenant)); return [ $this->openRenderedReportAction([ 'source_surface' => 'review_pack', 'review_id' => $this->record->environment_review_id, 'tenant_filter_id' => request()->query('tenant_filter_id'), 'interpretation_version' => $this->record->environmentReview?->controlInterpretationVersion(), ]), Actions\Action::make('download') ->label(fn (): string => ReviewPackResource::downloadActionLabelFor($this->record)) ->icon('heroicon-o-arrow-down-tray') ->color('gray') ->visible(fn (): bool => $this->record->status === ReviewPackStatus::Ready->value) ->url(fn (): string => app(ReviewPackService::class)->generateDownloadUrl($this->record)) ->openUrlInNewTab(), $regenerateAction, ]; } /** * @param array $parameters */ private function openRenderedReportAction(array $parameters = [], string $color = 'primary'): Actions\Action { return Actions\Action::make('open_rendered_report') ->label(fn (): string => \App\Filament\Resources\EnvironmentReviewResource::renderedReportActionLabelFor($this->record->environmentReview)) ->icon('heroicon-o-document-text') ->color($color) ->visible(fn (): bool => $this->canOpenRenderedReport()) ->url(fn (): string => app(ReviewPackService::class)->generateRenderedReportUrl( $this->record, $this->renderedReportParameters($parameters), )) ->openUrlInNewTab(); } /** * @param array $parameters * @return array */ private function renderedReportParameters(array $parameters): array { $parameters = array_filter($parameters, static fn (mixed $value): bool => $value !== null && $value !== ''); $review = $this->record->environmentReview; if (! $review instanceof EnvironmentReview) { return $parameters; } if (! array_key_exists(ReportProfileRegistry::QUERY_PARAMETER, $parameters)) { $guidance = ReviewPackOutputResolutionGuidance::fromReadiness( ReviewPackOutputResolutionGuidance::readinessForReview($review), ); $parameters[ReportProfileRegistry::QUERY_PARAMETER] = ReportProfileRegistry::defaultForRenderedReportState( (string) ($guidance['state'] ?? ReviewPackOutputResolutionGuidance::STATE_UNKNOWN), array_key_exists(CustomerReviewWorkspace::DETAIL_CONTEXT_QUERY_KEY, $parameters), ); } return $parameters; } private function canOpenRenderedReport(): bool { /** @var ReviewPack $record */ $record = $this->record; if ($record->status !== ReviewPackStatus::Ready->value) { return false; } if ($record->expires_at !== null && $record->expires_at->isPast()) { return false; } if (! $record->environmentReview instanceof \App\Models\EnvironmentReview) { return false; } return (int) ($record->environmentReview->current_export_review_pack_id ?? 0) === (int) $record->getKey(); } }