TenantAtlas/resources/views/filament/pages/workspaces/managed-tenant-onboarding-wizard.blade.php
Ahmed Darrazi 7b0a383182 feat: unified managed tenant onboarding wizard
Implements workspace-scoped managed tenant onboarding wizard (Filament v5 / Livewire v4) with strict RBAC (404/403 semantics), resumable sessions, provider connection selection/creation, verification OperationRun, and optional bootstrap. Removes legacy onboarding entrypoints and adds Pest coverage + spec artifacts (073).
2026-02-03 18:27:39 +01:00

171 lines
9.5 KiB
PHP

<x-filament-panels::page>
<x-filament::section>
<div class="flex flex-col gap-4">
<div class="text-sm text-gray-600 dark:text-gray-300">
Workspace: <span class="font-medium text-gray-900 dark:text-gray-100">{{ $this->workspace->name }}</span>
</div>
<div class="rounded-md border border-gray-200 bg-gray-50 p-4 text-sm text-gray-700 dark:border-gray-800 dark:bg-gray-900 dark:text-gray-200">
<div class="font-medium text-gray-900 dark:text-gray-100">
Managed tenant onboarding
</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">
This wizard will guide you through identifying a managed tenant and verifying access.
</div>
</div>
@if ($this->managedTenant)
<div class="rounded-md border border-gray-200 bg-white p-4 text-sm text-gray-700 dark:border-gray-800 dark:bg-gray-950 dark:text-gray-200">
<div class="font-medium text-gray-900 dark:text-gray-100">Identified tenant</div>
<dl class="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
<div>
<dt class="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">Name</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $this->managedTenant->name }}</dd>
</div>
<div>
<dt class="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">Tenant ID</dt>
<dd class="mt-1 font-mono text-sm text-gray-900 dark:text-gray-100">{{ $this->managedTenant->tenant_id }}</dd>
</div>
</dl>
</div>
@endif
@php
$verificationSucceeded = $this->verificationSucceeded();
$hasTenant = (bool) $this->managedTenant;
$hasConnection = $hasTenant && is_int($this->selectedProviderConnectionId) && $this->selectedProviderConnectionId > 0;
@endphp
<div class="grid grid-cols-1 gap-3 lg:grid-cols-2">
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-950">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Step 1 Identify managed tenant</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">Provide tenant ID + display name to start or resume the flow.</div>
</div>
<div class="text-xs font-medium {{ $hasTenant ? 'text-emerald-700 dark:text-emerald-400' : 'text-gray-500 dark:text-gray-400' }}">
{{ $hasTenant ? 'Done' : 'Pending' }}
</div>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row">
<x-filament::button
type="button"
color="primary"
wire:click="mountAction('identifyManagedTenant')"
>
{{ $hasTenant ? 'Change tenant' : 'Identify tenant' }}
</x-filament::button>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-950">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Step 2 Provider connection</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">Create or pick the connection used to verify access.</div>
</div>
<div class="text-xs font-medium {{ $hasConnection ? 'text-emerald-700 dark:text-emerald-400' : 'text-gray-500 dark:text-gray-400' }}">
{{ $hasConnection ? 'Selected' : ($hasTenant ? 'Pending' : 'Locked') }}
</div>
</div>
@if ($hasTenant)
<div class="mt-3 text-sm text-gray-700 dark:text-gray-200">
<span class="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">Selected connection ID</span>
<div class="mt-1 font-mono">{{ $this->selectedProviderConnectionId ?? '—' }}</div>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row">
<x-filament::button
type="button"
color="gray"
wire:click="mountAction('createProviderConnection')"
>
Create connection
</x-filament::button>
<x-filament::button
type="button"
color="gray"
wire:click="mountAction('selectProviderConnection')"
>
Select connection
</x-filament::button>
</div>
@endif
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-950">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Step 3 Verify access</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">Runs a verification operation and records the result.</div>
</div>
<div class="text-xs font-medium {{ $verificationSucceeded ? 'text-emerald-700 dark:text-emerald-400' : 'text-gray-500 dark:text-gray-400' }}">
{{ $verificationSucceeded ? 'Succeeded' : ($hasConnection ? 'Pending' : 'Locked') }}
</div>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row">
<x-filament::button
type="button"
color="primary"
:disabled="! $hasConnection"
wire:click="mountAction('startVerification')"
>
Run verification
</x-filament::button>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-950">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Step 4 Bootstrap (optional)</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">Start inventory/compliance sync after verification.</div>
</div>
<div class="text-xs font-medium text-gray-500 dark:text-gray-400">
{{ $verificationSucceeded ? 'Available' : 'Locked' }}
</div>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row">
<x-filament::button
type="button"
color="gray"
:disabled="! $verificationSucceeded"
wire:click="mountAction('startBootstrap')"
>
Start bootstrap
</x-filament::button>
</div>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-950">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Step 5 Complete onboarding</div>
<div class="mt-1 text-sm text-gray-600 dark:text-gray-300">Marks the tenant as active after successful verification.</div>
</div>
<div class="text-xs font-medium {{ $verificationSucceeded ? 'text-emerald-700 dark:text-emerald-400' : 'text-gray-500 dark:text-gray-400' }}">
{{ $verificationSucceeded ? 'Ready' : 'Locked' }}
</div>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row">
<x-filament::button
type="button"
color="success"
:disabled="! $verificationSucceeded"
wire:click="mountAction('completeOnboarding')"
>
Complete onboarding
</x-filament::button>
</div>
</div>
</div>
</x-filament::section>
</x-filament-panels::page>