@php use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\Links\RequiredPermissionsLinks; use Illuminate\Support\Carbon; $tenant = $this->currentTenant(); $vm = is_array($viewModel ?? null) ? $viewModel : []; $overview = is_array($vm['overview'] ?? null) ? $vm['overview'] : []; $counts = is_array($overview['counts'] ?? null) ? $overview['counts'] : []; $featureImpacts = is_array($overview['feature_impacts'] ?? null) ? $overview['feature_impacts'] : []; $freshness = is_array($overview['freshness'] ?? null) ? $overview['freshness'] : []; $filters = is_array($vm['filters'] ?? null) ? $vm['filters'] : []; $selectedFeatures = is_array($filters['features'] ?? null) ? $filters['features'] : []; $selectedStatus = (string) ($filters['status'] ?? 'missing'); $selectedType = (string) ($filters['type'] ?? 'all'); $searchTerm = (string) ($filters['search'] ?? ''); $featureOptions = collect($featureImpacts) ->filter(fn (mixed $impact): bool => is_array($impact) && is_string($impact['feature'] ?? null)) ->map(fn (array $impact): string => (string) $impact['feature']) ->filter() ->unique() ->sort() ->values() ->all(); $permissions = is_array($vm['permissions'] ?? null) ? $vm['permissions'] : []; $overall = $overview['overall'] ?? null; $overallSpec = $overall !== null ? BadgeRenderer::spec(BadgeDomain::VerificationReportOverall, $overall) : null; $copy = is_array($vm['copy'] ?? null) ? $vm['copy'] : []; $copyApplication = (string) ($copy['application'] ?? ''); $copyDelegated = (string) ($copy['delegated'] ?? ''); $missingApplication = (int) ($counts['missing_application'] ?? 0); $missingDelegated = (int) ($counts['missing_delegated'] ?? 0); $presentCount = (int) ($counts['present'] ?? 0); $errorCount = (int) ($counts['error'] ?? 0); $missingTotal = $missingApplication + $missingDelegated + $errorCount; $requiredTotal = $missingTotal + $presentCount; $adminConsentUrl = $tenant ? RequiredPermissionsLinks::adminConsentUrl($tenant) : null; $adminConsentPrimaryUrl = $tenant ? RequiredPermissionsLinks::adminConsentPrimaryUrl($tenant) : RequiredPermissionsLinks::adminConsentGuideUrl(); $adminConsentLabel = $adminConsentUrl ? 'Open admin consent' : 'Admin consent guide'; $reRunUrl = $this->reRunVerificationUrl(); $manageProviderConnectionUrl = $this->manageProviderConnectionUrl(); $lastRefreshedAt = is_string($freshness['last_refreshed_at'] ?? null) ? (string) $freshness['last_refreshed_at'] : null; $lastRefreshedLabel = $lastRefreshedAt ? Carbon::parse($lastRefreshedAt)->diffForHumans() : 'Unknown'; $isStale = (bool) ($freshness['is_stale'] ?? true); $hasStoredPermissionData = $lastRefreshedAt !== null; $issues = []; if ($missingApplication > 0) { $issues[] = [ 'severity' => 'Blocker', 'title' => 'Missing application permissions', 'description' => "{$missingApplication} required application permission(s) are missing.", 'links' => array_values(array_filter([ ['label' => $adminConsentLabel, 'url' => $adminConsentPrimaryUrl, 'external' => true], $manageProviderConnectionUrl ? ['label' => 'Manage provider connection', 'url' => $manageProviderConnectionUrl, 'external' => false] : null, ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], ])), ]; } if ($missingDelegated > 0) { $issues[] = [ 'severity' => 'Warning', 'title' => 'Missing delegated permissions', 'description' => "{$missingDelegated} delegated permission(s) are missing.", 'links' => [ ['label' => $adminConsentLabel, 'url' => $adminConsentPrimaryUrl, 'external' => true], ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], ], ]; } if ($errorCount > 0) { $issues[] = [ 'severity' => 'Warning', 'title' => 'Verification results need review', 'description' => "{$errorCount} permission row(s) are in an unknown/error state and require follow-up.", 'links' => [ ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], $manageProviderConnectionUrl ? ['label' => 'Manage provider connection', 'url' => $manageProviderConnectionUrl, 'external' => false] : ['label' => 'Admin consent guide', 'url' => RequiredPermissionsLinks::adminConsentGuideUrl(), 'external' => true], ], ]; } if ($isStale) { $issues[] = [ 'severity' => 'Warning', 'title' => 'Freshness warning', 'description' => $hasStoredPermissionData ? "Permission data is older than 30 days (last refresh {$lastRefreshedLabel})." : 'No stored verification data is available yet.', 'links' => [ ['label' => 'Start verification', 'url' => $reRunUrl, 'external' => false], ], ]; } @endphp
Review what’s missing for this tenant and copy the missing permissions for admin consent.
Stored-data view only. Last refreshed: {{ $lastRefreshedLabel }}{{ $isStale ? ' (stale)' : '' }}.
@if ($overallSpec) {{ $overallSpec->label }} @endif
Missing (app)
{{ (int) ($counts['missing_application'] ?? 0) }}
Missing (delegated)
{{ (int) ($counts['missing_delegated'] ?? 0) }}
Present
{{ (int) ($counts['present'] ?? 0) }}
Errors
{{ (int) ($counts['error'] ?? 0) }}
@if (! $hasStoredPermissionData)
Keine Daten verfügbar
Für diesen Tenant liegen noch keine gespeicherten Verifikationsdaten vor. Start verification.
@endif
Guidance
Who can fix this? Global Administrator / Privileged Role Administrator.
Primary next step: {{ $adminConsentLabel }}
@if ($reRunUrl)
After granting consent: Re-run verification
@endif
Copy missing application permissions Copy missing delegated permissions
@if (is_array($featureImpacts) && $featureImpacts !== [])
@foreach ($featureImpacts as $impact) @php $featureKey = is_array($impact) ? ($impact['feature'] ?? null) : null; $featureKey = is_string($featureKey) ? $featureKey : null; $missingCount = is_array($impact) ? (int) ($impact['missing'] ?? 0) : 0; $isBlocked = is_array($impact) ? (bool) ($impact['blocked'] ?? false) : false; if ($featureKey === null) { continue; } $selected = in_array($featureKey, $selectedFeatures, true); @endphp @endforeach
@if ($selectedFeatures !== [])
Clear feature filter
@endif @endif
Missing application permissions
Newline-separated list for admin consent.
Close
@if ($copyApplication === '')
Nothing to copy — no missing application permissions in the current feature filter.
@else
Copied Copy

                                
@endif
Missing delegated permissions
Newline-separated list for delegated consent.
Close
@if ($copyDelegated === '')
Nothing to copy — no missing delegated permissions in the current feature filter.
@else
Copied Copy

                                
@endif
@if ($issues === [])
No blockers or warnings detected from stored data.
@else
@foreach ($issues as $issue) @php $severity = (string) ($issue['severity'] ?? 'Warning'); $severityColor = $severity === 'Blocker' ? 'danger' : 'warning'; $title = (string) ($issue['title'] ?? 'Issue'); $description = (string) ($issue['description'] ?? ''); $links = is_array($issue['links'] ?? null) ? $issue['links'] : []; @endphp
{{ $severity }}
{{ $title }}
{{ $description }}
@if ($links !== [])
@foreach ($links as $link) @php $label = is_array($link) ? (string) ($link['label'] ?? '') : ''; $url = is_array($link) ? (string) ($link['url'] ?? '') : ''; $external = is_array($link) ? (bool) ($link['external'] ?? false) : false; @endphp @if ($label !== '' && $url !== '') {{ $label }} @endif @endforeach
@endif
@endforeach
@endif
{{ $presentCount }} permission(s) currently pass.
{{ $requiredTotal > 0 ? "Out of {$requiredTotal} required permissions, {$presentCount} are currently granted." : 'No required permissions are configured yet.' }}
Expand technical details
@if (! $tenant)
No tenant selected.
@else
Filters
Search doesn’t affect copy actions. Feature filters do.
Reset
@if ($featureOptions !== [])
@endif
@if ($requiredTotal === 0)
No permissions configured
No required permissions are currently configured in config/intune_permissions.php.
@elseif ($permissions === [])
@if ($selectedStatus === 'missing' && $missingTotal === 0 && $selectedType === 'all' && $selectedFeatures === [] && trim($searchTerm) === '')
All required permissions are present
Switch Status to “All” if you want to review the full matrix.
@else
No matches
No permissions match the current filters.
@endif
@else @php $featuresToRender = $featureImpacts; if ($selectedFeatures !== []) { $featuresToRender = collect($featureImpacts) ->filter(fn ($impact) => is_array($impact) && in_array((string) ($impact['feature'] ?? ''), $selectedFeatures, true)) ->values() ->all(); } @endphp @foreach ($featuresToRender as $impact) @php $featureKey = is_array($impact) ? ($impact['feature'] ?? null) : null; $featureKey = is_string($featureKey) ? $featureKey : null; if ($featureKey === null) { continue; } $rows = collect($permissions) ->filter(fn ($row) => is_array($row) && in_array($featureKey, (array) ($row['features'] ?? []), true)) ->values() ->all(); if ($rows === []) { continue; } @endphp
{{ $featureKey }}
@foreach ($rows as $row) @php $key = is_array($row) ? (string) ($row['key'] ?? '') : ''; $type = is_array($row) ? (string) ($row['type'] ?? '') : ''; $status = is_array($row) ? (string) ($row['status'] ?? '') : ''; $description = is_array($row) ? ($row['description'] ?? null) : null; $description = is_string($description) ? $description : null; $statusSpec = BadgeRenderer::spec(BadgeDomain::TenantPermissionStatus, $status); @endphp @endforeach
Permission Type Status
{{ $key }}
@if ($description)
{{ $description }}
@endif
{{ $type === 'delegated' ? 'Delegated' : 'Application' }} {{ $statusSpec->label }}
@endforeach @endif
@endif