- Implement Spec 116 baseline capture/compare + coverage guard\n- Add UI surfaces and widgets for baseline compare\n- Add tests and research report
157 lines
6.7 KiB
PHP
157 lines
6.7 KiB
PHP
<x-filament::page>
|
|
@php
|
|
$baselineCompareHasWarnings = in_array(($baselineCompareCoverageStatus ?? null), ['warning', 'unproven'], true);
|
|
@endphp
|
|
|
|
<x-filament::section>
|
|
<div class="flex flex-col gap-3">
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
Review new drift findings between the last two operation runs for the current scope.
|
|
</div>
|
|
|
|
@if (filled($scopeKey))
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
Scope: {{ $scopeKey }}
|
|
@if ($baselineRunId && $currentRunId)
|
|
· Baseline
|
|
@if ($this->getBaselineRunUrl())
|
|
<a class="text-primary-600 hover:underline" href="{{ $this->getBaselineRunUrl() }}">
|
|
#{{ $baselineRunId }}
|
|
</a>
|
|
@else
|
|
#{{ $baselineRunId }}
|
|
@endif
|
|
@if (filled($baselineFinishedAt))
|
|
({{ $baselineFinishedAt }})
|
|
@endif
|
|
· Current
|
|
@if ($this->getCurrentRunUrl())
|
|
<a class="text-primary-600 hover:underline" href="{{ $this->getCurrentRunUrl() }}">
|
|
#{{ $currentRunId }}
|
|
</a>
|
|
@else
|
|
#{{ $currentRunId }}
|
|
@endif
|
|
@if (filled($currentFinishedAt))
|
|
({{ $currentFinishedAt }})
|
|
@endif
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
@if ($baselineCompareRunId)
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
Baseline compare
|
|
@if ($this->getBaselineCompareRunUrl())
|
|
<a class="text-primary-600 hover:underline" href="{{ $this->getBaselineCompareRunUrl() }}">
|
|
#{{ $baselineCompareRunId }}
|
|
</a>
|
|
@else
|
|
#{{ $baselineCompareRunId }}
|
|
@endif
|
|
|
|
@if (filled($baselineCompareCoverageStatus))
|
|
· Coverage
|
|
<x-filament::badge :color="$baselineCompareCoverageStatus === 'ok' ? 'success' : 'warning'" size="sm">
|
|
{{ $baselineCompareCoverageStatus === 'ok' ? 'OK' : 'Warnings' }}
|
|
</x-filament::badge>
|
|
@endif
|
|
|
|
@if (filled($baselineCompareFidelity))
|
|
· Fidelity {{ Str::title($baselineCompareFidelity) }}
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
@if ($baselineCompareRunId && $baselineCompareHasWarnings)
|
|
<div class="rounded-lg border border-warning-300 bg-warning-50 p-4 text-warning-900 dark:border-warning-700 dark:bg-warning-950/40 dark:text-warning-100">
|
|
<div class="flex flex-col gap-1">
|
|
<div class="text-sm font-semibold">Baseline compare coverage warnings</div>
|
|
<div class="text-sm">
|
|
@if (($baselineCompareCoverageStatus ?? null) === 'unproven')
|
|
Coverage proof was missing or unreadable for the last baseline comparison, so findings were suppressed for safety.
|
|
@else
|
|
Some policy types were uncovered in the last baseline comparison, so findings may be incomplete.
|
|
@endif
|
|
</div>
|
|
|
|
@if (! empty($baselineCompareUncoveredTypes))
|
|
<div class="mt-1 text-xs">
|
|
Uncovered: {{ implode(', ', array_slice($baselineCompareUncoveredTypes, 0, 6)) }}@if (count($baselineCompareUncoveredTypes) > 6)…@endif
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($state === 'blocked')
|
|
<x-filament::badge color="gray">
|
|
Blocked
|
|
</x-filament::badge>
|
|
|
|
@if (filled($message))
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
{{ $message }}
|
|
</div>
|
|
@endif
|
|
@elseif ($state === 'generating')
|
|
<x-filament::badge color="warning">
|
|
Generating
|
|
</x-filament::badge>
|
|
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
Drift generation has been queued. Refresh this page once it finishes.
|
|
</div>
|
|
|
|
@if ($this->getOperationRunUrl())
|
|
<div class="text-sm">
|
|
<a class="text-primary-600 hover:underline" href="{{ $this->getOperationRunUrl() }}">
|
|
View run #{{ $operationRunId }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
@elseif ($state === 'error')
|
|
<x-filament::badge color="danger">
|
|
Error
|
|
</x-filament::badge>
|
|
|
|
@if (filled($message))
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
{{ $message }}
|
|
</div>
|
|
@endif
|
|
|
|
@if ($this->getOperationRunUrl())
|
|
<div class="text-sm">
|
|
<a class="text-primary-600 hover:underline" href="{{ $this->getOperationRunUrl() }}">
|
|
View run #{{ $operationRunId }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
@elseif ($state === 'ready')
|
|
<div class="flex flex-wrap gap-3">
|
|
<x-filament::badge color="success">
|
|
New: {{ (int) ($statusCounts['new'] ?? 0) }}
|
|
</x-filament::badge>
|
|
</div>
|
|
|
|
@if (filled($message))
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
{{ $message }}
|
|
</div>
|
|
@endif
|
|
@else
|
|
<x-filament::badge color="gray">
|
|
Ready
|
|
</x-filament::badge>
|
|
@endif
|
|
|
|
<div class="flex flex-wrap gap-3">
|
|
<x-filament::button tag="a" :href="$this->getFindingsUrl()">
|
|
Findings
|
|
</x-filament::button>
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
</x-filament::page>
|