modifyQueryUsing(fn (Builder $query) => $query->with('user')) ->columns([ Tables\Columns\TextColumn::make('user.name') ->label(__('User')) ->searchable(), Tables\Columns\TextColumn::make('user.email') ->label(__('Email')) ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('role') ->badge() ->sortable(), Tables\Columns\TextColumn::make('source') ->badge() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('created_at')->since(), ]) ->headerActions([ Actions\Action::make('add_member') ->label(__('Add member')) ->icon('heroicon-o-plus') ->visible(function (): bool { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { return false; } return Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant); }) ->form([ Forms\Components\Select::make('user_id') ->label(__('User')) ->required() ->searchable() ->options(fn () => User::query()->orderBy('name')->pluck('name', 'id')->all()), Forms\Components\Select::make('role') ->label(__('Role')) ->required() ->options([ 'owner' => __('Owner'), 'manager' => __('Manager'), 'operator' => __('Operator'), 'readonly' => __('Readonly'), ]), ]) ->action(function (array $data, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { abort(404); } $actor = auth()->user(); if (! $actor instanceof User) { abort(403); } if (! Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant)) { abort(403); } $member = User::query()->find((int) $data['user_id']); if (! $member) { Notification::make()->title(__('User not found'))->danger()->send(); return; } try { $manager->addMember( tenant: $tenant, actor: $actor, member: $member, role: (string) $data['role'], source: 'manual', ); } catch (\Throwable $throwable) { Notification::make() ->title(__('Failed to add member')) ->body($throwable->getMessage()) ->danger() ->send(); return; } Notification::make()->title(__('Member added'))->success()->send(); $this->resetTable(); }), ]) ->actions([ Actions\Action::make('change_role') ->label(__('Change role')) ->icon('heroicon-o-pencil') ->requiresConfirmation() ->visible(function (): bool { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { return false; } return Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant); }) ->form([ Forms\Components\Select::make('role') ->label(__('Role')) ->required() ->options([ 'owner' => __('Owner'), 'manager' => __('Manager'), 'operator' => __('Operator'), 'readonly' => __('Readonly'), ]), ]) ->action(function (TenantMembership $record, array $data, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { abort(404); } $actor = auth()->user(); if (! $actor instanceof User) { abort(403); } if (! Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant)) { abort(403); } try { $manager->changeRole( tenant: $tenant, actor: $actor, membership: $record, newRole: (string) $data['role'], ); } catch (\Throwable $throwable) { Notification::make() ->title(__('Failed to change role')) ->body($throwable->getMessage()) ->danger() ->send(); return; } Notification::make()->title(__('Role updated'))->success()->send(); $this->resetTable(); }), Actions\Action::make('remove') ->label(__('Remove')) ->color('danger') ->icon('heroicon-o-x-mark') ->requiresConfirmation() ->visible(function (): bool { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { return false; } return Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant); }) ->action(function (TenantMembership $record, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); if (! $tenant instanceof Tenant) { abort(404); } $actor = auth()->user(); if (! $actor instanceof User) { abort(403); } if (! Gate::allows(Capabilities::TENANT_MEMBERSHIP_MANAGE, $tenant)) { abort(403); } try { $manager->removeMember($tenant, $actor, $record); } catch (\Throwable $throwable) { Notification::make() ->title(__('Failed to remove member')) ->body($throwable->getMessage()) ->danger() ->send(); return; } Notification::make()->title(__('Member removed'))->success()->send(); $this->resetTable(); }), ]) ->bulkActions([]); } }