feat(007): device config & compliance snapshot/restore improvements #9
@ -14,10 +14,114 @@ public function mount(PolicyVersion $version): void
|
|||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('livewire.policy-version-assignments-widget', [
|
return view('livewire.policy-version-assignments-widget', [
|
||||||
'version' => $this->version,
|
'version' => $this->version,
|
||||||
|
'compliance' => $this->complianceNotifications(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{total:int,templates:array<int,string>,items:array<int,array{rule_name:?string,template_id:string,template_key:string}>}
|
||||||
|
*/
|
||||||
|
private function complianceNotifications(): array
|
||||||
|
{
|
||||||
|
if ($this->version->policy_type !== 'deviceCompliancePolicy') {
|
||||||
|
return [
|
||||||
|
'total' => 0,
|
||||||
|
'templates' => [],
|
||||||
|
'items' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$snapshot = $this->version->snapshot;
|
||||||
|
|
||||||
|
if (! is_array($snapshot)) {
|
||||||
|
return [
|
||||||
|
'total' => 0,
|
||||||
|
'templates' => [],
|
||||||
|
'items' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$scheduled = $snapshot['scheduledActionsForRule'] ?? null;
|
||||||
|
|
||||||
|
if (! is_array($scheduled)) {
|
||||||
|
return [
|
||||||
|
'total' => 0,
|
||||||
|
'templates' => [],
|
||||||
|
'items' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
$templateIds = [];
|
||||||
|
|
||||||
|
foreach ($scheduled as $rule) {
|
||||||
|
if (! is_array($rule)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruleName = $rule['ruleName'] ?? null;
|
||||||
|
$configs = $rule['scheduledActionConfigurations'] ?? null;
|
||||||
|
|
||||||
|
if (! is_array($configs)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($configs as $config) {
|
||||||
|
if (! is_array($config)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($config['actionType'] ?? null) !== 'notification') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$templateKey = $this->resolveNotificationTemplateKey($config);
|
||||||
|
|
||||||
|
if ($templateKey === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$templateId = $config[$templateKey] ?? null;
|
||||||
|
|
||||||
|
if (! is_string($templateId) || $templateId === '' || $this->isEmptyGuid($templateId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$items[] = [
|
||||||
|
'rule_name' => is_string($ruleName) ? $ruleName : null,
|
||||||
|
'template_id' => $templateId,
|
||||||
|
'template_key' => $templateKey,
|
||||||
|
];
|
||||||
|
$templateIds[] = $templateId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'total' => count($items),
|
||||||
|
'templates' => array_values(array_unique($templateIds)),
|
||||||
|
'items' => $items,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveNotificationTemplateKey(array $config): ?string
|
||||||
|
{
|
||||||
|
if (array_key_exists('notificationTemplateId', $config)) {
|
||||||
|
return 'notificationTemplateId';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('notificationMessageTemplateId', $config)) {
|
||||||
|
return 'notificationMessageTemplateId';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isEmptyGuid(string $value): bool
|
||||||
|
{
|
||||||
|
return strtolower($value) === '00000000-0000-0000-0000-000000000000';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,4 +155,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@php
|
||||||
|
$complianceTotal = $compliance['total'] ?? 0;
|
||||||
|
$complianceTemplates = $compliance['templates'] ?? [];
|
||||||
|
@endphp
|
||||||
|
@if($complianceTotal > 0)
|
||||||
|
<div class="mt-6 rounded-lg bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||||
|
<div class="px-6 py-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-base font-semibold leading-6 text-gray-950 dark:text-white">
|
||||||
|
Compliance notifications
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
{{ $complianceTotal }} action(s) • {{ count($complianceTemplates) }} template(s)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="border-t border-gray-200 px-6 py-4 dark:border-white/10">
|
||||||
|
<div class="space-y-2">
|
||||||
|
@foreach($compliance['items'] ?? [] as $item)
|
||||||
|
@php
|
||||||
|
$ruleName = $item['rule_name'] ?? null;
|
||||||
|
$templateId = $item['template_id'] ?? null;
|
||||||
|
@endphp
|
||||||
|
<div class="flex items-center gap-2 text-sm">
|
||||||
|
<span class="text-gray-600 dark:text-gray-400">•</span>
|
||||||
|
<span class="font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ $ruleName ?: 'Unnamed rule' }}
|
||||||
|
</span>
|
||||||
|
@if($templateId)
|
||||||
|
<span class="text-xs text-gray-500 dark:text-gray-500">
|
||||||
|
Template: {{ $templateId }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -112,3 +112,35 @@
|
|||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
$response->assertSee('No assignments found for this version');
|
$response->assertSee('No assignments found for this version');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows compliance notifications when present', function () {
|
||||||
|
$version = PolicyVersion::factory()->create([
|
||||||
|
'tenant_id' => $this->tenant->id,
|
||||||
|
'policy_id' => $this->policy->id,
|
||||||
|
'version_number' => 1,
|
||||||
|
'policy_type' => 'deviceCompliancePolicy',
|
||||||
|
'assignments' => null,
|
||||||
|
'snapshot' => [
|
||||||
|
'scheduledActionsForRule' => [
|
||||||
|
[
|
||||||
|
'ruleName' => 'Test rule',
|
||||||
|
'scheduledActionConfigurations' => [
|
||||||
|
[
|
||||||
|
'actionType' => 'notification',
|
||||||
|
'notificationTemplateId' => 'template-123',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->actingAs($this->user);
|
||||||
|
|
||||||
|
$response = $this->get("/admin/policy-versions/{$version->id}");
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
$response->assertSee('Compliance notifications');
|
||||||
|
$response->assertSee('Test rule');
|
||||||
|
$response->assertSee('template-123');
|
||||||
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user