Implements Spec 089: moves Provider Connections to canonical tenantless route under `/admin/provider-connections`, enforces 404/403 semantics (workspace/tenant membership vs capability), adds tenant transparency (tenant column + filter + deep links), adds legacy redirects for old tenant-scoped URLs without leaking Location for 404 cases, and adds regression test coverage (RBAC semantics, filters, UI enforcement tooltips, Microsoft-only MVP scope, navigation placement). Notes: - Filament v5 / Livewire v4 compatible. - Global search remains disabled for Provider Connections. - Destructive/manage actions require confirmation and are policy-gated. Tests: - `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #107
61 lines
2.7 KiB
PHP
61 lines
2.7 KiB
PHP
@php
|
|
$state = $getState();
|
|
$state = is_array($state) ? $state : [];
|
|
|
|
$connectionState = is_string($state['state'] ?? null) ? (string) $state['state'] : 'needs_action';
|
|
$ctaUrl = is_string($state['cta_url'] ?? null) ? (string) $state['cta_url'] : '#';
|
|
|
|
$displayName = is_string($state['display_name'] ?? null) ? (string) $state['display_name'] : null;
|
|
$provider = is_string($state['provider'] ?? null) ? (string) $state['provider'] : null;
|
|
$status = is_string($state['status'] ?? null) ? (string) $state['status'] : null;
|
|
$healthStatus = is_string($state['health_status'] ?? null) ? (string) $state['health_status'] : null;
|
|
$lastCheck = is_string($state['last_health_check_at'] ?? null) ? (string) $state['last_health_check_at'] : null;
|
|
$lastErrorReason = is_string($state['last_error_reason_code'] ?? null) ? (string) $state['last_error_reason_code'] : null;
|
|
|
|
$isMissing = $connectionState === 'needs_action';
|
|
@endphp
|
|
|
|
<div class="space-y-3 rounded-md border border-gray-200 bg-white p-4 shadow-sm">
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div>
|
|
<div class="text-sm font-semibold text-gray-800">Provider connection</div>
|
|
@if ($isMissing)
|
|
<div class="mt-1 text-sm text-amber-700">Needs action: no default Microsoft provider connection is configured.</div>
|
|
@else
|
|
<div class="mt-1 text-sm text-gray-700">{{ $displayName ?? 'Unnamed connection' }}</div>
|
|
@endif
|
|
</div>
|
|
|
|
<a href="{{ $ctaUrl }}" class="inline-flex items-center rounded-md border border-gray-300 px-3 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-50">
|
|
Open Provider Connections
|
|
</a>
|
|
</div>
|
|
|
|
@unless ($isMissing)
|
|
<dl class="grid grid-cols-1 gap-2 text-sm text-gray-700 sm:grid-cols-2">
|
|
<div>
|
|
<dt class="text-xs uppercase tracking-wide text-gray-500">Provider</dt>
|
|
<dd>{{ $provider ?? 'n/a' }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="text-xs uppercase tracking-wide text-gray-500">Status</dt>
|
|
<dd>{{ $status ?? 'n/a' }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="text-xs uppercase tracking-wide text-gray-500">Health</dt>
|
|
<dd>{{ $healthStatus ?? 'n/a' }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="text-xs uppercase tracking-wide text-gray-500">Last check</dt>
|
|
<dd>{{ $lastCheck ?? 'n/a' }}</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
@if ($lastErrorReason)
|
|
<div class="rounded-md border border-amber-300 bg-amber-50 p-2 text-xs text-amber-800">
|
|
Last error reason: {{ $lastErrorReason }}
|
|
</div>
|
|
@endif
|
|
@endunless
|
|
</div>
|