Implemented the first version of provider readiness resolution guidance. Added the ProviderReadinessResolutionAdapter, provider readiness guidance card, and updated EnvironmentRequiredPermissions, ProviderConnectionResource, and ListProviderConnections/ViewProviderConnection. Added tests and updated the design coverage matrix. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #424
258 lines
12 KiB
PHP
258 lines
12 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'] ?? '');
|
|
$primaryActionExternal = (bool) ($primaryAction['external'] ?? false);
|
|
$primaryActionDisabled = (bool) ($primaryAction['disabled'] ?? false);
|
|
$primaryActionMethod = is_string($primaryActionMethod ?? null) ? (string) $primaryActionMethod : $actionName;
|
|
$canRunPrimaryActionMethod = $inlinePrimaryAction
|
|
&& $primaryActionMethod !== null
|
|
&& $actionName === $primaryActionMethod;
|
|
|
|
[$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="provider-readiness-guidance-card"
|
|
data-guidance-key="{{ $guidance['key'] ?? '' }}"
|
|
>
|
|
<div class="grid gap-4 lg:grid-cols-[minmax(0,1fr)_18rem] lg:items-start">
|
|
<div class="min-w-0 space-y-3">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
@if ($status !== '')
|
|
<x-filament::badge
|
|
:color="$badgeColor"
|
|
size="sm"
|
|
data-testid="provider-readiness-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="provider-readiness-title">
|
|
{{ $title }}
|
|
</h2>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="space-y-3 lg:hidden">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
|
{{ __('localization.provider_guidance.primary_action_label') }}
|
|
</div>
|
|
|
|
@if ($canRunPrimaryActionMethod)
|
|
<x-filament::button
|
|
color="primary"
|
|
wire:click="{{ $primaryActionMethod }}"
|
|
wire:loading.attr="disabled"
|
|
class="w-full justify-center whitespace-normal text-center"
|
|
:disabled="$primaryActionDisabled"
|
|
>
|
|
{{ $primaryActionLabel }}
|
|
</x-filament::button>
|
|
@elseif ($inlinePrimaryAction && $primaryActionUrl !== null)
|
|
<x-filament::button
|
|
color="primary"
|
|
tag="a"
|
|
href="{{ $primaryActionUrl }}"
|
|
class="w-full justify-center whitespace-normal text-center"
|
|
:target="$primaryActionExternal ? '_blank' : null"
|
|
:rel="$primaryActionExternal ? 'noreferrer' : null"
|
|
:disabled="$primaryActionDisabled"
|
|
>
|
|
{{ $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">
|
|
{{ $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.provider_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'] ?? '');
|
|
$secondaryExternal = (bool) ($secondaryAction['external'] ?? false);
|
|
@endphp
|
|
|
|
@if ($secondaryUrl !== null && $secondaryLabel !== '')
|
|
<x-filament::button
|
|
color="gray"
|
|
size="sm"
|
|
tag="a"
|
|
href="{{ $secondaryUrl }}"
|
|
class="max-w-full whitespace-normal text-center"
|
|
:target="$secondaryExternal ? '_blank' : null"
|
|
:rel="$secondaryExternal ? 'noreferrer' : null"
|
|
>
|
|
{{ $secondaryLabel }}
|
|
</x-filament::button>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@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.provider_guidance.reason_label') }}
|
|
</div>
|
|
<p class="text-sm text-gray-800 dark:text-gray-100" data-testid="provider-readiness-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.provider_guidance.impact_label') }}
|
|
</div>
|
|
<p class="text-sm text-gray-700 dark:text-gray-200" data-testid="provider-readiness-impact">
|
|
{{ $impact }}
|
|
</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="hidden w-full space-y-3 lg:block">
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
|
{{ __('localization.provider_guidance.primary_action_label') }}
|
|
</div>
|
|
|
|
@if ($canRunPrimaryActionMethod)
|
|
<x-filament::button
|
|
color="primary"
|
|
wire:click="{{ $primaryActionMethod }}"
|
|
wire:loading.attr="disabled"
|
|
class="w-full justify-center whitespace-normal text-center"
|
|
:disabled="$primaryActionDisabled"
|
|
data-testid="provider-readiness-primary-action"
|
|
>
|
|
{{ $primaryActionLabel }}
|
|
</x-filament::button>
|
|
@elseif ($inlinePrimaryAction && $primaryActionUrl !== null)
|
|
<x-filament::button
|
|
color="primary"
|
|
tag="a"
|
|
href="{{ $primaryActionUrl }}"
|
|
class="w-full justify-center whitespace-normal text-center"
|
|
:target="$primaryActionExternal ? '_blank' : null"
|
|
:rel="$primaryActionExternal ? 'noreferrer' : null"
|
|
:disabled="$primaryActionDisabled"
|
|
data-testid="provider-readiness-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">
|
|
{{ $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.provider_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'] ?? '');
|
|
$secondaryExternal = (bool) ($secondaryAction['external'] ?? false);
|
|
@endphp
|
|
|
|
@if ($secondaryUrl !== null && $secondaryLabel !== '')
|
|
<x-filament::button
|
|
color="gray"
|
|
size="sm"
|
|
tag="a"
|
|
href="{{ $secondaryUrl }}"
|
|
class="max-w-full whitespace-normal text-center"
|
|
:target="$secondaryExternal ? '_blank' : null"
|
|
:rel="$secondaryExternal ? 'noreferrer' : null"
|
|
data-testid="provider-readiness-secondary-action"
|
|
>
|
|
{{ $secondaryLabel }}
|
|
</x-filament::button>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
@if ($technicalDetails !== [])
|
|
<details class="mt-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-800 dark:bg-gray-950" data-testid="provider-readiness-details">
|
|
<summary class="cursor-pointer text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
{{ __('localization.provider_guidance.details_label') }}
|
|
</summary>
|
|
|
|
<dl class="mt-3 grid gap-3 sm:grid-cols-2">
|
|
@foreach ($technicalDetails as $detail)
|
|
@php
|
|
if (! is_array($detail)) {
|
|
continue;
|
|
}
|
|
@endphp
|
|
|
|
<div>
|
|
<dt class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
|
{{ (string) ($detail['label'] ?? '') }}
|
|
</dt>
|
|
<dd class="mt-1 text-sm text-gray-700 dark:text-gray-200">
|
|
{{ (string) ($detail['value'] ?? '') }}
|
|
</dd>
|
|
</div>
|
|
@endforeach
|
|
</dl>
|
|
</details>
|
|
@endif
|
|
</div>
|