170 lines
8.6 KiB
PHP
170 lines
8.6 KiB
PHP
@php
|
|
$diff = $getState() ?? ['summary' => [], 'added' => [], 'removed' => [], 'changed' => []];
|
|
$summary = $diff['summary'] ?? [];
|
|
|
|
$groupByBlock = static function (array $items): array {
|
|
$groups = [];
|
|
|
|
foreach ($items as $path => $value) {
|
|
if (! is_string($path) || $path === '') {
|
|
continue;
|
|
}
|
|
|
|
$parts = explode(' > ', $path, 2);
|
|
|
|
if (count($parts) === 2) {
|
|
[$group, $label] = $parts;
|
|
} else {
|
|
$group = 'Other';
|
|
$label = $path;
|
|
}
|
|
|
|
$groups[$group][$label] = $value;
|
|
}
|
|
|
|
ksort($groups);
|
|
|
|
return $groups;
|
|
};
|
|
|
|
$stringify = static function (mixed $value): string {
|
|
if ($value === null) {
|
|
return '—';
|
|
}
|
|
|
|
if (is_bool($value)) {
|
|
return $value ? 'Enabled' : 'Disabled';
|
|
}
|
|
|
|
if (is_scalar($value)) {
|
|
return (string) $value;
|
|
}
|
|
|
|
return json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?: '';
|
|
};
|
|
|
|
$isExpandable = static function (mixed $value): bool {
|
|
if (is_array($value)) {
|
|
return true;
|
|
}
|
|
|
|
return is_string($value) && strlen($value) > 160;
|
|
};
|
|
@endphp
|
|
|
|
<div class="space-y-4">
|
|
<x-filament::section
|
|
heading="Normalized diff"
|
|
:description="$summary['message'] ?? sprintf('%d added, %d removed, %d changed', $summary['added'] ?? 0, $summary['removed'] ?? 0, $summary['changed'] ?? 0)"
|
|
>
|
|
<div class="flex flex-wrap gap-2">
|
|
<x-filament::badge color="success">
|
|
{{ (int) ($summary['added'] ?? 0) }} added
|
|
</x-filament::badge>
|
|
<x-filament::badge color="danger">
|
|
{{ (int) ($summary['removed'] ?? 0) }} removed
|
|
</x-filament::badge>
|
|
<x-filament::badge color="warning">
|
|
{{ (int) ($summary['changed'] ?? 0) }} changed
|
|
</x-filament::badge>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
@foreach (['changed' => ['label' => 'Changed', 'collapsed' => false], 'added' => ['label' => 'Added', 'collapsed' => true], 'removed' => ['label' => 'Removed', 'collapsed' => true]] as $key => $meta)
|
|
@php
|
|
$items = $diff[$key] ?? [];
|
|
$groups = $groupByBlock(is_array($items) ? $items : []);
|
|
@endphp
|
|
|
|
@if ($groups !== [])
|
|
<x-filament::section
|
|
:heading="$meta['label']"
|
|
collapsible
|
|
:collapsed="$meta['collapsed']"
|
|
>
|
|
<div class="space-y-6">
|
|
@foreach ($groups as $group => $groupItems)
|
|
<div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="text-sm font-medium text-gray-900 dark:text-white">
|
|
{{ $group }}
|
|
</div>
|
|
<x-filament::badge size="sm" color="gray">
|
|
{{ count($groupItems) }}
|
|
</x-filament::badge>
|
|
</div>
|
|
|
|
<div class="mt-2 divide-y divide-gray-200 rounded-lg border border-gray-200 dark:divide-white/10 dark:border-white/10">
|
|
@foreach ($groupItems as $name => $value)
|
|
<div class="px-4 py-3">
|
|
@if ($key === 'changed' && is_array($value) && array_key_exists('from', $value) && array_key_exists('to', $value))
|
|
@php
|
|
$from = $value['from'];
|
|
$to = $value['to'];
|
|
$fromText = $stringify($from);
|
|
$toText = $stringify($to);
|
|
@endphp
|
|
<div class="grid grid-cols-1 gap-2 sm:grid-cols-3">
|
|
<div class="text-sm font-medium text-gray-900 dark:text-white">
|
|
{{ (string) $name }}
|
|
</div>
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
<span class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">From</span>
|
|
@if ($isExpandable($from))
|
|
<details class="mt-1">
|
|
<summary class="cursor-pointer text-sm text-gray-700 dark:text-gray-200">
|
|
View
|
|
</summary>
|
|
<pre class="mt-2 overflow-x-auto text-xs text-gray-800 dark:text-gray-200">{{ $fromText }}</pre>
|
|
</details>
|
|
@else
|
|
<div class="mt-1">{{ $fromText }}</div>
|
|
@endif
|
|
</div>
|
|
<div class="text-sm text-gray-600 dark:text-gray-300">
|
|
<span class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">To</span>
|
|
@if ($isExpandable($to))
|
|
<details class="mt-1">
|
|
<summary class="cursor-pointer text-sm text-gray-700 dark:text-gray-200">
|
|
View
|
|
</summary>
|
|
<pre class="mt-2 overflow-x-auto text-xs text-gray-800 dark:text-gray-200">{{ $toText }}</pre>
|
|
</details>
|
|
@else
|
|
<div class="mt-1">{{ $toText }}</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@else
|
|
@php
|
|
$text = $stringify($value);
|
|
@endphp
|
|
<div class="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
|
|
<div class="text-sm font-medium text-gray-900 dark:text-white">
|
|
{{ (string) $name }}
|
|
</div>
|
|
<div class="text-sm text-gray-700 dark:text-gray-200 sm:max-w-[70%]">
|
|
@if ($isExpandable($value))
|
|
<details>
|
|
<summary class="cursor-pointer text-sm text-gray-700 dark:text-gray-200">
|
|
View
|
|
</summary>
|
|
<pre class="mt-2 overflow-x-auto text-xs text-gray-800 dark:text-gray-200">{{ $text }}</pre>
|
|
</details>
|
|
@else
|
|
<div class="break-words">{{ $text }}</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
@endforeach
|
|
</div>
|