## Summary - harden the canonical operation run viewer so mismatched, missing, archived, onboarding, and selector-excluded tenant context no longer invalidates authorized canonical run viewing - extend canonical route, header-context, deep-link, and presentation coverage for Spec 144 and add the full spec artifact set under `specs/144-canonical-operation-viewer-context-decoupling/` - harden onboarding draft provider-connection resume logic so stale persisted provider connections fall back to the connect-provider step instead of resuming invalid state - add architecture-audit follow-up candidate material and prompt assets for the next governance hardening wave ## Testing - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/RunAuthorizationTenantIsolationTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Monitoring/HeaderContextBarTest.php tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php` ## Notes - branch: `144-canonical-operation-viewer-context-decoupling` - base: `dev` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #173
37 lines
1.6 KiB
PHP
37 lines
1.6 KiB
PHP
@php
|
|
$contextBanner = $this->canonicalContextBanner();
|
|
$pollInterval = $this->pollInterval();
|
|
@endphp
|
|
|
|
<x-filament-panels::page>
|
|
<div
|
|
x-data
|
|
x-init="$wire.set('opsUxIsTabHidden', document.hidden)"
|
|
x-on:visibilitychange.window="$wire.set('opsUxIsTabHidden', document.hidden)"
|
|
@if ($pollInterval !== null) wire:poll.{{ $pollInterval }} @endif
|
|
>
|
|
@if ($contextBanner !== null)
|
|
@php
|
|
$bannerClasses = match ($contextBanner['tone']) {
|
|
'amber' => 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-100',
|
|
'slate' => 'border-slate-200 bg-slate-50 text-slate-900 dark:border-slate-500/30 dark:bg-slate-500/10 dark:text-slate-100',
|
|
default => 'border-sky-200 bg-sky-50 text-sky-900 dark:border-sky-500/30 dark:bg-sky-500/10 dark:text-sky-100',
|
|
};
|
|
@endphp
|
|
|
|
<div class="mb-6 rounded-lg border px-4 py-3 text-sm {{ $bannerClasses }}">
|
|
<p class="font-semibold">{{ $contextBanner['title'] }}</p>
|
|
<p class="mt-1">{{ $contextBanner['body'] }}</p>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($this->redactionIntegrityNote())
|
|
<div class="mb-6 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-100">
|
|
{{ $this->redactionIntegrityNote() }}
|
|
</div>
|
|
@endif
|
|
|
|
{{ $this->infolist }}
|
|
</div>
|
|
</x-filament-panels::page>
|