TenantAtlas/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
Ahmed Darrazi a98323d2f4 fix: enterprise UX overhaul for baseline governance
- Fix display_name → name column on Tenant model (3 files)
- Rename 'Soll vs Ist' to 'Baseline Compare' (English consistency)
- Redesign landing page: stats overview grid, critical drift banner,
  severity breakdown section, proper empty states with icons
- Upgrade dashboard widget: severity badges, inline critical alert,
  last compared timestamp, compliance status indicator
- Move Findings + DriftLanding from 'Drift' to 'Governance' nav group
2026-02-20 00:23:44 +01:00

143 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Resources\BaselineProfileResource\Pages;
use App\Filament\Resources\BaselineProfileResource;
use App\Models\BaselineProfile;
use App\Models\Tenant;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Baselines\BaselineCaptureService;
use App\Support\Auth\Capabilities;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Forms\Components\Select;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ViewRecord;
class ViewBaselineProfile extends ViewRecord
{
protected static string $resource = BaselineProfileResource::class;
protected function getHeaderActions(): array
{
return [
$this->captureAction(),
EditAction::make()
->visible(fn (): bool => $this->hasManageCapability()),
];
}
private function captureAction(): Action
{
return Action::make('capture')
->label('Capture Snapshot')
->icon('heroicon-o-camera')
->color('primary')
->visible(fn (): bool => $this->hasManageCapability())
->disabled(fn (): bool => ! $this->hasManageCapability())
->tooltip(fn (): ?string => ! $this->hasManageCapability() ? 'You need manage permission to capture snapshots.' : null)
->requiresConfirmation()
->modalHeading('Capture Baseline Snapshot')
->modalDescription('Select the source tenant whose current inventory will be captured as the baseline snapshot.')
->form([
Select::make('source_tenant_id')
->label('Source Tenant')
->options(fn (): array => $this->getWorkspaceTenantOptions())
->required()
->searchable(),
])
->action(function (array $data): void {
$user = auth()->user();
if (! $user instanceof User || ! $this->hasManageCapability()) {
Notification::make()
->title('Permission denied')
->danger()
->send();
return;
}
/** @var BaselineProfile $profile */
$profile = $this->getRecord();
$sourceTenant = Tenant::query()->find((int) $data['source_tenant_id']);
if (! $sourceTenant instanceof Tenant) {
Notification::make()
->title('Source tenant not found')
->danger()
->send();
return;
}
$service = app(BaselineCaptureService::class);
$result = $service->startCapture($profile, $sourceTenant, $user);
if (! $result['ok']) {
Notification::make()
->title('Cannot start capture')
->body('Reason: '.str_replace('.', ' ', (string) ($result['reason_code'] ?? 'unknown')))
->danger()
->send();
return;
}
Notification::make()
->title('Capture enqueued')
->body('Baseline snapshot capture has been started.')
->success()
->send();
});
}
/**
* @return array<int, string>
*/
private function getWorkspaceTenantOptions(): array
{
$workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());
if ($workspaceId === null) {
return [];
}
return Tenant::query()
->where('workspace_id', $workspaceId)
->orderBy('name')
->pluck('name', 'id')
->all();
}
private function hasManageCapability(): bool
{
$user = auth()->user();
if (! $user instanceof User) {
return false;
}
$workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());
if ($workspaceId === null) {
return false;
}
$workspace = Workspace::query()->whereKey($workspaceId)->first();
if (! $workspace instanceof Workspace) {
return false;
}
$resolver = app(\App\Services\Auth\WorkspaceCapabilityResolver::class);
return $resolver->isMember($user, $workspace)
&& $resolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_MANAGE);
}
}