## Summary - add the shared operator explanation layer with explanation families, trustworthiness semantics, count descriptors, and centralized badge mappings - adopt explanation-first rendering across baseline compare, governance operation run detail, baseline snapshot presentation, tenant review detail, and review register rows - extend reason translation, artifact-truth presentation, fallback ops UX messaging, and focused regression coverage for operator explanation semantics ## Testing - vendor/bin/sail bin pint --dirty --format agent - vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php - vendor/bin/sail artisan test --compact ## Notes - Livewire v4 compatible - panel provider registration remains in bootstrap/providers.php - no destructive Filament actions were added or changed in this PR - no new global-search behavior was introduced in this slice Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #191
93 lines
4.4 KiB
PHP
93 lines
4.4 KiB
PHP
@php
|
|
$state = $getState();
|
|
$state = is_array($state) ? $state : [];
|
|
|
|
$metrics = is_array($state['metrics'] ?? null) ? $state['metrics'] : [];
|
|
$highlights = is_array($state['highlights'] ?? null) ? $state['highlights'] : [];
|
|
$nextActions = is_array($state['next_actions'] ?? null) ? $state['next_actions'] : [];
|
|
$publishBlockers = is_array($state['publish_blockers'] ?? null) ? $state['publish_blockers'] : [];
|
|
$operatorExplanation = is_array($state['operator_explanation'] ?? null) ? $state['operator_explanation'] : [];
|
|
@endphp
|
|
|
|
<div class="space-y-4">
|
|
@if ($operatorExplanation !== [])
|
|
<div class="rounded-lg border border-gray-200 bg-white px-4 py-3 shadow-sm dark:border-gray-800 dark:bg-gray-900/70">
|
|
<div class="text-sm font-semibold text-gray-950 dark:text-white">
|
|
{{ $operatorExplanation['headline'] ?? 'Review explanation' }}
|
|
</div>
|
|
|
|
@if (filled($operatorExplanation['reliabilityStatement'] ?? null))
|
|
<div class="mt-2 text-sm text-gray-600 dark:text-gray-300">
|
|
{{ $operatorExplanation['reliabilityStatement'] }}
|
|
</div>
|
|
@endif
|
|
|
|
@if (filled(data_get($operatorExplanation, 'nextAction.text')))
|
|
<div class="mt-3 rounded-md border border-primary-100 bg-primary-50 px-3 py-2 text-sm text-primary-900 dark:border-primary-900/40 dark:bg-primary-950/30 dark:text-primary-100">
|
|
{{ data_get($operatorExplanation, 'nextAction.text') }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
<dl class="grid grid-cols-2 gap-3 xl:grid-cols-4">
|
|
@foreach ($metrics as $metric)
|
|
@php
|
|
$label = is_string($metric['label'] ?? null) ? $metric['label'] : null;
|
|
$value = is_string($metric['value'] ?? null) ? $metric['value'] : null;
|
|
@endphp
|
|
|
|
@continue($label === null || $value === null)
|
|
|
|
<div class="rounded-md border border-gray-100 bg-gray-50 px-3 py-2 dark:border-gray-800 dark:bg-gray-950/60">
|
|
<dt class="text-[11px] font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">{{ $label }}</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $value }}</dd>
|
|
</div>
|
|
@endforeach
|
|
</dl>
|
|
|
|
@if ($highlights !== [])
|
|
<div class="space-y-2">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Highlights</div>
|
|
<ul class="space-y-1 text-sm text-gray-700 dark:text-gray-300">
|
|
@foreach ($highlights as $highlight)
|
|
@continue(! is_string($highlight) || trim($highlight) === '')
|
|
|
|
<li class="rounded-md border border-gray-100 bg-gray-50 px-3 py-2 dark:border-gray-800 dark:bg-gray-950/60">{{ $highlight }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($nextActions !== [])
|
|
<div class="space-y-2">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Next actions</div>
|
|
<ul class="space-y-1 text-sm text-gray-700 dark:text-gray-300">
|
|
@foreach ($nextActions as $action)
|
|
@continue(! is_string($action) || trim($action) === '')
|
|
|
|
<li class="rounded-md border border-primary-100 bg-primary-50 px-3 py-2 dark:border-primary-900/40 dark:bg-primary-950/30">{{ $action }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="space-y-2">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Publication readiness</div>
|
|
|
|
@if ($publishBlockers === [])
|
|
<div class="rounded-md border border-emerald-100 bg-emerald-50 px-3 py-2 text-sm text-emerald-800 dark:border-emerald-900/40 dark:bg-emerald-950/30 dark:text-emerald-200">
|
|
This review is ready for publication and executive-pack export.
|
|
</div>
|
|
@else
|
|
<ul class="space-y-1 text-sm text-amber-800 dark:text-amber-200">
|
|
@foreach ($publishBlockers as $blocker)
|
|
@continue(! is_string($blocker) || trim($blocker) === '')
|
|
|
|
<li class="rounded-md border border-amber-100 bg-amber-50 px-3 py-2 dark:border-amber-900/40 dark:bg-amber-950/30">{{ $blocker }}</li>
|
|
@endforeach
|
|
</ul>
|
|
@endif
|
|
</div>
|
|
</div>
|