147 lines
4.7 KiB
PHP
147 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Pages\ManagedTenants;
|
|
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\Auth\CapabilityResolver;
|
|
use App\Support\Auth\Capabilities;
|
|
use App\Support\Rbac\UiEnforcement;
|
|
use BackedEnum;
|
|
use Filament\Actions\Action;
|
|
use Filament\Facades\Filament;
|
|
use Filament\Pages\Page;
|
|
use Filament\Tables\Columns\TextColumn;
|
|
use Filament\Tables\Concerns\InteractsWithTable;
|
|
use Filament\Tables\Contracts\HasTable;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use UnitEnum;
|
|
|
|
class Index extends Page implements HasTable
|
|
{
|
|
use InteractsWithTable;
|
|
|
|
protected static bool $isDiscovered = false;
|
|
|
|
protected static bool $shouldRegisterNavigation = true;
|
|
|
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-building-office-2';
|
|
|
|
protected static string|UnitEnum|null $navigationGroup = 'Managed tenants';
|
|
|
|
protected static ?string $navigationLabel = 'Managed tenants';
|
|
|
|
protected static ?string $slug = 'managed-tenants';
|
|
|
|
protected static ?string $title = 'Managed tenants';
|
|
|
|
protected string $view = 'filament.pages.managed-tenants.index';
|
|
|
|
public function mount(): void
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if (! $user instanceof User) {
|
|
abort(403);
|
|
}
|
|
|
|
if (! $user->tenantMemberships()->exists()) {
|
|
abort(404);
|
|
}
|
|
|
|
/** @var CapabilityResolver $resolver */
|
|
$resolver = app(CapabilityResolver::class);
|
|
|
|
$canViewAny = Tenant::query()
|
|
->whereIn('id', $user->tenants()->withTrashed()->pluck('tenants.id'))
|
|
->cursor()
|
|
->contains(fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_MANAGED_TENANTS_VIEW));
|
|
|
|
if (! $canViewAny) {
|
|
abort(403);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array<Action>
|
|
*/
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [
|
|
Action::make('add_managed_tenant')
|
|
->label('Add managed tenant')
|
|
->icon('heroicon-o-plus')
|
|
->url('/admin/managed-tenants/onboarding'),
|
|
];
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->query($this->managedTenantsQuery())
|
|
->columns([
|
|
TextColumn::make('name')->searchable(),
|
|
TextColumn::make('tenant_id')->label('Tenant ID')->copyable()->searchable(),
|
|
TextColumn::make('environment')->badge()->sortable(),
|
|
TextColumn::make('status')->badge()->sortable(),
|
|
])
|
|
->actions([
|
|
UiEnforcement::forTableAction(
|
|
Action::make('open')
|
|
->label('Open')
|
|
->icon('heroicon-o-arrow-top-right-on-square')
|
|
->url(fn (Tenant $record): string => "/admin/managed-tenants/{$record->getKey()}/open"),
|
|
fn () => Filament::getTenant(),
|
|
)
|
|
->requireCapability(Capabilities::TENANT_MANAGED_TENANTS_VIEW)
|
|
->apply(),
|
|
|
|
UiEnforcement::forTableAction(
|
|
Action::make('view')
|
|
->label('View')
|
|
->url(fn (Tenant $record): string => ViewManagedTenant::getUrl(['managedTenant' => $record])),
|
|
fn () => Filament::getTenant(),
|
|
)
|
|
->requireCapability(Capabilities::TENANT_MANAGED_TENANTS_VIEW)
|
|
->apply(),
|
|
|
|
UiEnforcement::forTableAction(
|
|
Action::make('edit')
|
|
->label('Edit')
|
|
->url(fn (Tenant $record): string => EditManagedTenant::getUrl(['managedTenant' => $record])),
|
|
fn () => Filament::getTenant(),
|
|
)
|
|
->requireCapability(Capabilities::TENANT_MANAGED_TENANTS_MANAGE)
|
|
->apply(),
|
|
])
|
|
->emptyStateHeading('No managed tenants')
|
|
->emptyStateDescription('Add your first managed tenant to begin onboarding.')
|
|
->emptyStateActions([
|
|
Action::make('empty_add_managed_tenant')
|
|
->label('Add managed tenant')
|
|
->icon('heroicon-o-plus')
|
|
->url('/admin/managed-tenants/onboarding'),
|
|
]);
|
|
}
|
|
|
|
private function managedTenantsQuery(): Builder
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if (! $user instanceof User) {
|
|
return Tenant::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
$tenantIds = $user->tenants()
|
|
->withTrashed()
|
|
->pluck('tenants.id');
|
|
|
|
return Tenant::query()
|
|
->withTrashed()
|
|
->whereIn('id', $tenantIds);
|
|
}
|
|
}
|