TenantAtlas/apps/platform/resources/views/filament/partials/accepted-risk-guidance-card.blade.php
ahmido a9c54205bf feat: finding exceptions accepted risk resolution guidance v1 (spec 354) (#425)
Implemented the accepted risk resolution guidance, including the AcceptedRiskResolutionAdapter, guidance cards, and updated related Filament views. Added unit, feature, and browser tests.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #425
2026-06-05 02:20:46 +00:00

166 lines
7.7 KiB
PHP

@php
$guidance = is_array($guidance ?? null) ? $guidance : [];
$primaryAction = is_array($guidance['primary_action'] ?? null) ? $guidance['primary_action'] : [];
$secondaryActions = is_array($guidance['secondary_actions'] ?? null) ? $guidance['secondary_actions'] : [];
$technicalDetails = is_array($guidance['technical_details'] ?? null) ? $guidance['technical_details'] : [];
$inlinePrimaryAction = (bool) ($inlinePrimaryAction ?? false);
$severity = (string) ($guidance['severity'] ?? 'warning');
$status = (string) ($guidance['status'] ?? '');
$title = (string) ($guidance['title'] ?? '');
$reason = (string) ($guidance['reason'] ?? '');
$impact = (string) ($guidance['impact'] ?? '');
$actionName = is_string($primaryAction['action_name'] ?? null) ? (string) $primaryAction['action_name'] : null;
$primaryActionUrl = is_string($primaryAction['url'] ?? null) ? (string) $primaryAction['url'] : null;
$primaryActionLabel = (string) ($primaryAction['label'] ?? '');
$primaryActionType = (string) ($primaryAction['type'] ?? '');
$primaryActionHeading = ($primaryActionType === 'none' || ($actionName === null && $primaryActionUrl === null))
? __('localization.accepted_risk_guidance.review_focus_label')
: __('localization.accepted_risk_guidance.primary_action_label');
[$badgeColor, $accentClasses] = match ($severity) {
'success' => [
'success',
'border-l-success-500 dark:border-l-success-400',
],
'danger' => [
'danger',
'border-l-danger-500 dark:border-l-danger-400',
],
default => [
'warning',
'border-l-warning-500 dark:border-l-warning-400',
],
};
@endphp
<div
class="rounded-xl border border-l-4 border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900 sm:p-5 {{ $accentClasses }}"
data-testid="accepted-risk-guidance-card"
data-guidance-key="{{ $guidance['key'] ?? '' }}"
>
<div class="grid gap-4 lg:grid-cols-[minmax(0,1fr)_18rem] lg:items-start">
<div class="space-y-4">
<div class="flex flex-wrap items-center gap-2">
@if ($status !== '')
<x-filament::badge :color="$badgeColor" size="sm" data-testid="accepted-risk-guidance-status">
{{ $status }}
</x-filament::badge>
@endif
@if ($title !== '')
<h2 class="text-sm font-semibold text-gray-950 dark:text-white sm:text-base" data-testid="accepted-risk-guidance-title">
{{ $title }}
</h2>
@endif
</div>
@if ($reason !== '')
<div class="space-y-1">
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ __('localization.accepted_risk_guidance.reason_label') }}
</div>
<p class="text-sm text-gray-800 dark:text-gray-100" data-testid="accepted-risk-guidance-reason">
{{ $reason }}
</p>
</div>
@endif
@if ($impact !== '')
<div class="space-y-1">
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ __('localization.accepted_risk_guidance.impact_label') }}
</div>
<p class="text-sm text-gray-700 dark:text-gray-200" data-testid="accepted-risk-guidance-impact">
{{ $impact }}
</p>
</div>
@endif
@if ($technicalDetails !== [])
<dl class="grid gap-3 sm:grid-cols-2" data-testid="accepted-risk-guidance-details">
@foreach ($technicalDetails as $label => $value)
<div class="rounded-lg border border-gray-100 bg-gray-50 px-3 py-3 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>
@endif
</div>
<div class="space-y-3">
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ $primaryActionHeading }}
</div>
@if ($inlinePrimaryAction && $actionName !== null)
<x-filament::button
color="primary"
wire:click="mountAction('{{ $actionName }}')"
wire:loading.attr="disabled"
class="w-full justify-center whitespace-normal text-center"
data-testid="accepted-risk-guidance-primary-action"
>
{{ $primaryActionLabel }}
</x-filament::button>
@elseif ($primaryActionUrl !== null)
<x-filament::button
color="primary"
tag="a"
href="{{ $primaryActionUrl }}"
class="w-full justify-center whitespace-normal text-center"
data-testid="accepted-risk-guidance-primary-action"
>
{{ $primaryActionLabel }}
</x-filament::button>
@elseif ($primaryActionLabel !== '')
<div
class="rounded-lg border border-gray-200 bg-gray-50 px-4 py-3 text-sm font-medium text-gray-900 dark:border-gray-800 dark:bg-gray-950 dark:text-gray-100"
data-testid="accepted-risk-guidance-primary-action"
>
{{ $primaryActionLabel }}
</div>
@endif
@if ($secondaryActions !== [])
<div class="space-y-2">
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{{ __('localization.accepted_risk_guidance.secondary_actions_label') }}
</div>
<div class="flex flex-wrap gap-2">
@foreach ($secondaryActions as $secondaryAction)
@php
if (! is_array($secondaryAction)) {
continue;
}
$secondaryUrl = is_string($secondaryAction['url'] ?? null) ? (string) $secondaryAction['url'] : null;
$secondaryLabel = (string) ($secondaryAction['label'] ?? '');
@endphp
@if ($secondaryUrl !== null && $secondaryLabel !== '')
<x-filament::button
color="gray"
size="sm"
tag="a"
href="{{ $secondaryUrl }}"
class="max-w-full whitespace-normal text-center"
data-testid="accepted-risk-guidance-secondary-action"
>
{{ $secondaryLabel }}
</x-filament::button>
@endif
@endforeach
</div>
</div>
@endif
</div>
</div>
</div>