merge: agent session work
This commit is contained in:
commit
028fa817d1
@ -52,8 +52,25 @@ public static function infolist(Schema $schema): Schema
|
||||
|
||||
// For Settings Catalog policies: Tabs with Settings table + JSON viewer
|
||||
Tabs::make('policy_content')
|
||||
->activeTab(1)
|
||||
->persistTabInQueryString()
|
||||
->tabs([
|
||||
Tab::make('General')
|
||||
->id('general')
|
||||
->schema([
|
||||
ViewEntry::make('policy_general')
|
||||
->label('')
|
||||
->view('filament.infolists.entries.policy-general')
|
||||
->state(function (Policy $record) {
|
||||
$normalized = static::normalizedPolicyState($record);
|
||||
$split = static::splitGeneralBlock($normalized);
|
||||
|
||||
return $split['general'];
|
||||
}),
|
||||
])
|
||||
->visible(fn (Policy $record) => $record->versions()->exists()),
|
||||
Tab::make('Settings')
|
||||
->id('settings')
|
||||
->schema([
|
||||
ViewEntry::make('settings_catalog')
|
||||
->label('')
|
||||
@ -87,20 +104,8 @@ public static function infolist(Schema $schema): Schema
|
||||
->helperText('This policy has been inventoried but no configuration snapshot has been captured yet.')
|
||||
->visible(fn (Policy $record) => ! $record->versions()->exists()),
|
||||
]),
|
||||
Tab::make('General')
|
||||
->schema([
|
||||
ViewEntry::make('policy_general')
|
||||
->label('')
|
||||
->view('filament.infolists.entries.policy-general')
|
||||
->state(function (Policy $record) {
|
||||
$normalized = static::normalizedPolicyState($record);
|
||||
$split = static::splitGeneralBlock($normalized);
|
||||
|
||||
return $split['general'];
|
||||
}),
|
||||
])
|
||||
->visible(fn (Policy $record) => $record->versions()->exists()),
|
||||
Tab::make('JSON')
|
||||
->id('json')
|
||||
->schema([
|
||||
ViewEntry::make('snapshot_json')
|
||||
->view('filament.infolists.entries.snapshot-json')
|
||||
@ -336,12 +341,15 @@ private static function latestSnapshot(Policy $record): array
|
||||
*/
|
||||
private static function normalizedPolicyState(Policy $record): array
|
||||
{
|
||||
static $cache = [];
|
||||
$cacheKey = 'tenantpilot.normalizedPolicyState.'.(string) $record->getKey();
|
||||
$request = request();
|
||||
|
||||
$cacheKey = (string) $record->getKey();
|
||||
if ($request->attributes->has($cacheKey)) {
|
||||
$cached = $request->attributes->get($cacheKey);
|
||||
|
||||
if (isset($cache[$cacheKey])) {
|
||||
return $cache[$cacheKey];
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
|
||||
$snapshot = static::latestSnapshot($record);
|
||||
@ -355,7 +363,7 @@ private static function normalizedPolicyState(Policy $record): array
|
||||
$normalized['context'] = 'policy';
|
||||
$normalized['record_id'] = (string) $record->getKey();
|
||||
|
||||
$cache[$cacheKey] = $normalized;
|
||||
$request->attributes->set($cacheKey, $normalized);
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
@ -25,8 +25,18 @@
|
||||
@endif
|
||||
|
||||
@if (! empty($settingsTableRows))
|
||||
<div class="space-y-2 rounded-md border border-gray-200 bg-white p-3 shadow-sm">
|
||||
<div class="text-sm font-semibold text-gray-800">{{ is_array($settingsTable) ? ($settingsTable['title'] ?? 'Settings') : 'Settings' }}</div>
|
||||
@php
|
||||
$settingsTableTitle = is_array($settingsTable) ? ($settingsTable['title'] ?? null) : null;
|
||||
$shouldShowTitle = is_string($settingsTableTitle)
|
||||
&& $settingsTableTitle !== ''
|
||||
&& ! ($context === 'policy' && strtolower($settingsTableTitle) === 'settings');
|
||||
@endphp
|
||||
|
||||
<div class="space-y-2">
|
||||
@if ($shouldShowTitle)
|
||||
<div class="text-sm font-semibold text-gray-800">{{ $settingsTableTitle }}</div>
|
||||
@endif
|
||||
|
||||
<livewire:settings-catalog-settings-table
|
||||
:settings-rows="$settingsTableRows"
|
||||
:context="$context"
|
||||
|
||||
@ -90,16 +90,16 @@
|
||||
$isNumericValue = is_numeric($value);
|
||||
@endphp
|
||||
|
||||
<div class="group relative overflow-hidden rounded-xl border border-gray-200/70 bg-gradient-to-br from-white via-amber-50/40 to-amber-100/60 p-4 shadow-sm transition duration-200 hover:-translate-y-0.5 hover:border-amber-200/70 hover:shadow-md dark:border-gray-700/60 dark:from-gray-950 dark:via-gray-900 dark:to-amber-950/30 dark:hover:border-amber-700/60">
|
||||
<div class="tp-policy-general-card group relative overflow-hidden rounded-xl border border-gray-200/70 bg-white p-4 shadow-sm transition duration-200 hover:-translate-y-0.5 hover:border-gray-300/70 hover:shadow-md dark:border-gray-700/60 dark:bg-gray-900 dark:hover:border-gray-600">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-lg ring-1 {{ $tone['ring'] ?? '' }} {{ $toneClass }}">
|
||||
<x-filament::icon icon="{{ $tone['icon'] ?? 'heroicon-o-document-text' }}" class="h-5 w-5" />
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<dt class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||
<dt class="text-xs font-semibold tracking-wide text-gray-500 dark:text-gray-400">
|
||||
{{ $entry['key'] ?? '-' }}
|
||||
</dt>
|
||||
<dd class="mt-2">
|
||||
<dd class="mt-2 text-left">
|
||||
@if ($isListValue)
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@foreach ($value as $item)
|
||||
@ -121,11 +121,11 @@
|
||||
{{ $boolLabel }}
|
||||
</x-filament::badge>
|
||||
@elseif ($isNumericValue)
|
||||
<div class="text-lg font-semibold text-gray-900 dark:text-white tabular-nums">
|
||||
<div class="text-sm font-semibold text-gray-900 dark:text-white tabular-nums">
|
||||
{{ number_format((float) $value) }}
|
||||
</div>
|
||||
@else
|
||||
<div class="text-sm text-gray-900 dark:text-white whitespace-pre-wrap break-words">
|
||||
<div class="text-sm text-gray-900 dark:text-white whitespace-pre-wrap break-words text-left">
|
||||
{{ is_string($value) ? $value : json_encode($value, JSON_PRETTY_PRINT) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
// Normalize payload to array for the JSON viewer
|
||||
$payloadArray = is_string($payload) ? (json_decode($payload, true) ?? []) : ($payload ?? []);
|
||||
$rawJson = json_encode($payloadArray, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
// Provide the small set of helpers the pepperfm json view expects
|
||||
$getState = fn () => $payloadArray;
|
||||
@ -17,10 +18,51 @@
|
||||
$getRenderMode = fn () => \PepperFM\FilamentJson\Enums\RenderModeEnum::Tree;
|
||||
$getInitiallyCollapsed = fn () => 1;
|
||||
$getExpandAllToggle = fn () => false;
|
||||
$getCopyJsonAction = fn () => true;
|
||||
$getCopyJsonAction = fn () => false;
|
||||
$getMaxDepth = fn () => 3;
|
||||
$applyLimit = fn ($v) => $v;
|
||||
@endphp
|
||||
|
||||
<div
|
||||
class="space-y-2"
|
||||
x-data="{
|
||||
text: @js($rawJson),
|
||||
async copyJson() {
|
||||
try {
|
||||
if (navigator.clipboard && (location.protocol === 'https:' || location.hostname === 'localhost')) {
|
||||
await navigator.clipboard.writeText(this.text);
|
||||
} else {
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = this.text;
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.inset = '0';
|
||||
document.body.appendChild(ta);
|
||||
ta.focus();
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
ta.remove();
|
||||
}
|
||||
|
||||
new FilamentNotification()
|
||||
.title('Copied!')
|
||||
.icon('heroicon-o-clipboard-document-check')
|
||||
.success()
|
||||
.send();
|
||||
} catch (e) {
|
||||
new FilamentNotification()
|
||||
.title('Copy failed!')
|
||||
.danger()
|
||||
.send();
|
||||
}
|
||||
}
|
||||
}"
|
||||
>
|
||||
<div class="flex items-center justify-end">
|
||||
<x-filament::button size="xs" color="gray" x-on:click="copyJson()">
|
||||
Copy JSON
|
||||
</x-filament::button>
|
||||
</div>
|
||||
|
||||
{{-- Render pepperfm filament-json viewer --}}
|
||||
@include('filament-json::json')
|
||||
</div>
|
||||
|
||||
@ -80,7 +80,8 @@
|
||||
$response->assertSee('Settings'); // Settings tab should appear for Settings Catalog
|
||||
$response->assertSee('General');
|
||||
$response->assertSee('JSON');
|
||||
$response->assertSee('bg-gradient-to-br');
|
||||
$response->assertSee('tp-policy-general-card');
|
||||
$response->assertSee('Copy JSON');
|
||||
});
|
||||
|
||||
it('shows display names instead of definition IDs', function () {
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
$user = User::factory()->create();
|
||||
|
||||
$policyResponse = $this->actingAs($user)
|
||||
->get(PolicyResource::getUrl('view', ['record' => $policy]));
|
||||
->get(PolicyResource::getUrl('view', ['record' => $policy]).'?tab=settings');
|
||||
|
||||
$policyResponse->assertOk();
|
||||
$policyResponse->assertSee('fi-width-full');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user