TenantAtlas/resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php

323 lines
16 KiB
PHP

@php
$fieldWrapperView = $getFieldWrapperView();
$run = $run ?? null;
$run = is_array($run) ? $run : null;
$runUrl = $runUrl ?? null;
$runUrl = is_string($runUrl) && $runUrl !== '' ? $runUrl : null;
$verificationReport = $verification_report ?? null;
$verificationReport = is_array($verificationReport) ? $verificationReport : null;
$status = $run['status'] ?? null;
$status = is_string($status) ? $status : null;
$outcome = $run['outcome'] ?? null;
$outcome = is_string($outcome) ? $outcome : null;
$targetScope = $run['target_scope'] ?? [];
$targetScope = is_array($targetScope) ? $targetScope : [];
$failures = $run['failures'] ?? [];
$failures = is_array($failures) ? $failures : [];
$completedAt = $run['completed_at'] ?? null;
$completedAt = is_string($completedAt) && $completedAt !== '' ? $completedAt : null;
$completedAtLabel = null;
if ($completedAt !== null) {
try {
$completedAtLabel = \Carbon\CarbonImmutable::parse($completedAt)->format('Y-m-d H:i');
} catch (\Throwable) {
$completedAtLabel = $completedAt;
}
}
$checks = is_array($verificationReport['checks'] ?? null) ? $verificationReport['checks'] : [];
$summaryOverall = is_array($verificationReport['summary'] ?? null) ? ($verificationReport['summary']['overall'] ?? null) : null;
$summaryOverall = is_string($summaryOverall) ? $summaryOverall : null;
$sortWeight = static function (array $check): int {
$status = is_array($check) ? ($check['status'] ?? null) : null;
$blocking = is_array($check) ? ($check['blocking'] ?? false) : false;
if ($status === 'fail' && $blocking === true) {
return 0;
}
if ($status === 'fail') {
return 1;
}
if ($status === 'warn') {
return 2;
}
if ($status === 'running') {
return 3;
}
if ($status === 'skip') {
return 4;
}
if ($status === 'pass') {
return 5;
}
return 6;
};
$hasReport = $verificationReport !== null;
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div class="space-y-4">
<x-filament::section
heading="Verification report"
:description="$completedAtLabel ? ('Completed: ' . $completedAtLabel) : 'Stored details for the latest verification run.'"
>
@if ($run === null)
<div class="text-sm text-gray-600 dark:text-gray-300">
No verification run has been started yet.
</div>
@elseif ($status !== 'completed')
<div class="text-sm text-gray-600 dark:text-gray-300">
@if (! $hasReport)
No report yet. Use “Refresh results” to update stored status.
@else
Partial results available. Use “Refresh results” to update stored status.
@endif
</div>
@else
@php
$sortedChecks = collect($checks)
->filter(fn ($check) => is_array($check))
->sortBy(fn (array $check) => $sortWeight($check))
->values()
->all();
$issueChecks = collect($sortedChecks)
->filter(fn (array $check) => in_array((string) ($check['status'] ?? ''), ['fail', 'warn', 'running'], true))
->values()
->all();
$otherChecks = collect($sortedChecks)
->filter(fn (array $check) => ! in_array((string) ($check['status'] ?? ''), ['fail', 'warn', 'running'], true))
->values()
->all();
@endphp
@if ($summaryOverall !== null)
@php
$overallSpec = \App\Support\Badges\BadgeRenderer::spec(\App\Support\Badges\BadgeDomain::VerificationReportOverall, $summaryOverall);
@endphp
<div class="flex flex-wrap items-center gap-2">
<div class="text-sm font-medium text-gray-900 dark:text-white">Overall</div>
<x-filament::badge :color="$overallSpec->color" :icon="$overallSpec->icon" size="sm">
{{ $overallSpec->label }}
</x-filament::badge>
</div>
@endif
@if ($sortedChecks === [])
@if ($outcome === 'succeeded')
<div class="text-sm text-gray-700 dark:text-gray-200">
All verification checks passed.
</div>
@elseif ($failures === [])
<div class="text-sm text-gray-600 dark:text-gray-300">
Report unavailable. The run completed, but no failure details were recorded.
</div>
@else
<div class="space-y-3">
<div class="text-sm font-medium text-gray-900 dark:text-white">
Findings
</div>
<ul class="space-y-2 text-sm text-gray-700 dark:text-gray-200">
@foreach ($failures as $failure)
@php
$reasonCode = is_array($failure) ? ($failure['reason_code'] ?? null) : null;
$message = is_array($failure) ? ($failure['message'] ?? null) : null;
$reasonCode = is_string($reasonCode) && $reasonCode !== '' ? $reasonCode : null;
$message = is_string($message) && $message !== '' ? $message : null;
@endphp
@if ($reasonCode !== null || $message !== null)
<li class="rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900">
@if ($reasonCode !== null)
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ $reasonCode }}
</div>
@endif
@if ($message !== null)
<div class="mt-1 text-sm text-gray-700 dark:text-gray-200">
{{ $message }}
</div>
@endif
</li>
@endif
@endforeach
</ul>
</div>
@endif
@else
@if ($issueChecks !== [])
<div class="space-y-3">
<div class="text-sm font-medium text-gray-900 dark:text-white">
Issues
</div>
<ul class="space-y-2 text-sm text-gray-700 dark:text-gray-200">
@foreach ($issueChecks as $check)
@php
$title = (string) ($check['title'] ?? 'Check');
$status = (string) ($check['status'] ?? 'fail');
$message = (string) ($check['message'] ?? '—');
$reasonCode = (string) ($check['reason_code'] ?? '');
$nextSteps = is_array($check['next_steps'] ?? null) ? $check['next_steps'] : [];
$statusSpec = \App\Support\Badges\BadgeRenderer::spec(\App\Support\Badges\BadgeDomain::VerificationCheckStatus, $status);
@endphp
<li class="rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900">
<div class="flex flex-wrap items-start justify-between gap-3">
<div class="min-w-0">
<div class="text-sm font-semibold text-gray-900 dark:text-white">
{{ $title }}
</div>
@if ($reasonCode !== '')
<div class="mt-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ $reasonCode }}
</div>
@endif
</div>
<x-filament::badge :color="$statusSpec->color" :icon="$statusSpec->icon" size="sm">
{{ $statusSpec->label }}
</x-filament::badge>
</div>
<div class="mt-2 text-sm text-gray-700 dark:text-gray-200">
{{ $message }}
</div>
@if ($nextSteps !== [])
<div class="mt-2 flex flex-col gap-1">
@foreach ($nextSteps as $step)
@php
$label = is_array($step) ? ($step['label'] ?? null) : null;
$url = is_array($step) ? ($step['url'] ?? null) : null;
$label = is_string($label) && $label !== '' ? $label : null;
$url = is_string($url) && $url !== '' ? $url : null;
@endphp
@if ($label !== null && $url !== null)
<a
href="{{ $url }}"
class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-400"
>
{{ $label }}
</a>
@endif
@endforeach
</div>
@endif
</li>
@endforeach
</ul>
</div>
@else
<div class="text-sm text-gray-700 dark:text-gray-200">
All verification checks passed.
</div>
@endif
@if ($otherChecks !== [])
<details class="mt-3">
<summary class="cursor-pointer text-sm font-medium text-gray-900 dark:text-white">
View all checks
</summary>
<div class="mt-3 space-y-2">
@foreach ($otherChecks as $check)
@php
$title = (string) ($check['title'] ?? 'Check');
$status = (string) ($check['status'] ?? 'skip');
$message = (string) ($check['message'] ?? '—');
$statusSpec = \App\Support\Badges\BadgeRenderer::spec(\App\Support\Badges\BadgeDomain::VerificationCheckStatus, $status);
@endphp
<div class="rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900">
<div class="flex flex-wrap items-start justify-between gap-3">
<div class="text-sm font-semibold text-gray-900 dark:text-white">
{{ $title }}
</div>
<x-filament::badge :color="$statusSpec->color" :icon="$statusSpec->icon" size="sm">
{{ $statusSpec->label }}
</x-filament::badge>
</div>
<div class="mt-2 text-sm text-gray-700 dark:text-gray-200">
{{ $message }}
</div>
</div>
@endforeach
</div>
</details>
@endif
@endif
@endif
@if ($targetScope !== [])
<div class="mt-4">
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
Target scope
</div>
<div class="mt-2 flex flex-col gap-1 text-sm text-gray-700 dark:text-gray-200">
@php
$entraTenantId = $targetScope['entra_tenant_id'] ?? null;
$entraTenantName = $targetScope['entra_tenant_name'] ?? null;
$entraTenantId = is_string($entraTenantId) && $entraTenantId !== '' ? $entraTenantId : null;
$entraTenantName = is_string($entraTenantName) && $entraTenantName !== '' ? $entraTenantName : null;
@endphp
@if ($entraTenantName !== null)
<div>
<span class="text-gray-500 dark:text-gray-400">Entra tenant:</span>
<span class="font-medium text-gray-900 dark:text-gray-100">{{ $entraTenantName }}</span>
</div>
@endif
@if ($entraTenantId !== null)
<div>
<span class="text-gray-500 dark:text-gray-400">Entra tenant ID:</span>
<span class="font-medium text-gray-900 dark:text-gray-100">{{ $entraTenantId }}</span>
</div>
@endif
</div>
</div>
@endif
@if ($runUrl !== null)
<div class="mt-4">
<a
href="{{ $runUrl }}"
class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-400"
>
Open run details
</a>
</div>
@endif
</x-filament::section>
</div>
</x-dynamic-component>