Files
construprogress/app/Livewire/RoleManager.php
T
javier 5092896a1e refactor(roles): role create/edit as a full page instead of a modal
Per feedback, 'New role' (and Edit) now open a dedicated page instead of a
modal:
- New RoleForm full-page component + view at /admin/roles/create and
  /admin/roles/{role}/edit (name, description, permission checkboxes; saves
  and redirects back to the list).
- RoleManager trimmed: the create/edit modal and its logic removed; 'New role'
  and the per-row/view-modal Edit are now links to the new pages.
- Kept the read-only View modal, single + bulk delete, and protections.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 17:05:01 +02:00

96 lines
2.9 KiB
PHP

<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\Attributes\Layout;
use Illuminate\Support\Facades\Auth;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
#[Layout('layouts.app')]
class RoleManager extends Component
{
// View modal
public ?int $viewingRole = null;
// Bulk selection
public array $selected = [];
public bool $selectAll = false;
private const PROTECTED_ROLES = ['Admin'];
private const CORE_PERMISSION = 'manage all';
public function mount(): void
{
abort_unless(Auth::user()?->can(self::CORE_PERMISSION), 403);
}
private function flushCache(): void
{
app(PermissionRegistrar::class)->forgetCachedPermissions();
}
public function updatedSelectAll($value): void
{
$this->selected = $value
? Role::pluck('id')->map(fn ($id) => (string) $id)->toArray()
: [];
}
// ── View ─────────────────────────────────────────────────────────────────
public function openView(int $id): void
{
$this->viewingRole = $id;
}
public function closeView(): void
{
$this->viewingRole = null;
}
// ── Delete (single / bulk) ─────────────────────────────────────────────────
public function delete(int $id): void
{
$role = Role::findOrFail($id);
if (in_array($role->name, self::PROTECTED_ROLES, true)) {
$this->dispatch('notify', "El rol '{$role->name}' está protegido y no se puede borrar.");
return;
}
$role->delete();
$this->selected = array_values(array_diff($this->selected, [(string) $id, $id]));
$this->flushCache();
$this->dispatch('notify', 'Rol eliminado');
}
public function bulkDelete(): void
{
$roles = Role::whereIn('id', $this->selected)->get();
$deleted = 0;
$skipped = 0;
foreach ($roles as $role) {
if (in_array($role->name, self::PROTECTED_ROLES, true)) { $skipped++; continue; }
$role->delete();
$deleted++;
}
$this->selected = [];
$this->selectAll = false;
$this->flushCache();
$msg = "{$deleted} rol(es) eliminados";
if ($skipped) $msg .= " ({$skipped} protegido(s) omitido(s))";
$this->dispatch('notify', $msg);
}
public function render()
{
return view('livewire.role-manager', [
'roles' => Role::with('permissions')->withCount('users')->orderBy('name')->get(),
'viewing' => $this->viewingRole
? Role::with('permissions')->withCount('users')->find($this->viewingRole)
: null,
]);
}
}