Implemented the first version of the PDF and HTML renderer for review packs. Added ReviewPackRenderedReportController and related blade views to render reports. Updated EnvironmentReviewResource, ReviewPackResource, ReviewPackService, and routing. Added new tests for the renderer and download actions, and updated UI documentation. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #427
145 lines
6.5 KiB
PHP
145 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\ReviewPackResource\Pages;
|
|
|
|
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
|
use App\Filament\Resources\ReviewPackResource;
|
|
use App\Models\ReviewPack;
|
|
use App\Services\ReviewPackService;
|
|
use App\Support\Auth\Capabilities;
|
|
use App\Support\Rbac\UiEnforcement;
|
|
use App\Support\ReviewPackStatus;
|
|
use Filament\Actions;
|
|
use Filament\Forms\Components\Toggle;
|
|
use Filament\Resources\Pages\ViewRecord;
|
|
use Filament\Schemas\Components\Section;
|
|
|
|
class ViewReviewPack extends ViewRecord
|
|
{
|
|
protected static string $resource = ReviewPackResource::class;
|
|
|
|
protected function getHeaderActions(): array
|
|
{
|
|
if (ReviewPackResource::isCustomerWorkspaceFlow()) {
|
|
return [
|
|
$this->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<string, scalar|null> $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,
|
|
array_filter($parameters, static fn (mixed $value): bool => $value !== null && $value !== ''),
|
|
))
|
|
->openUrlInNewTab();
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|