diff --git a/app/Livewire/RoleForm.php b/app/Livewire/RoleForm.php new file mode 100644 index 0000000..ed03f3d --- /dev/null +++ b/app/Livewire/RoleForm.php @@ -0,0 +1,79 @@ +can(self::CORE_PERMISSION), 403); + + if ($role && $role->exists) { + $this->role = $role; + $this->name = $role->name; + $this->description = $role->description ?? ''; + $this->rolePermissions = $role->permissions->pluck('name')->toArray(); + } + } + + public function save() + { + $this->validate([ + 'name' => 'required|string|max:50|unique:roles,name' . ($this->role ? ',' . $this->role->id : ''), + 'description' => 'nullable|string|max:255', + ], [], ['name' => 'nombre', 'description' => 'descripción']); + + if ($this->role) { + $isProtected = in_array($this->role->name, self::PROTECTED_ROLES, true); + if (! $isProtected) { + $this->role->name = $this->name; + } + $this->role->description = $this->description ?: null; + $this->role->save(); + + $perms = $this->rolePermissions; + if ($this->role->name === 'Admin' && ! in_array(self::CORE_PERMISSION, $perms, true)) { + $perms[] = self::CORE_PERMISSION; + } + $this->role->syncPermissions($perms); + } else { + $role = Role::create([ + 'name' => $this->name, + 'description' => $this->description ?: null, + ]); + if (! empty($this->rolePermissions)) { + $role->syncPermissions($this->rolePermissions); + } + } + + app(PermissionRegistrar::class)->forgetCachedPermissions(); + session()->flash('message', 'Rol guardado correctamente.'); + + return $this->redirect(route('admin.roles'), navigate: true); + } + + public function render() + { + return view('livewire.roles.role-form', [ + 'permissions' => Permission::orderBy('name')->get(), + 'isProtected' => $this->role && in_array($this->role->name, self::PROTECTED_ROLES, true), + ]); + } +} diff --git a/app/Livewire/RoleManager.php b/app/Livewire/RoleManager.php index dd641e2..c62cff5 100644 --- a/app/Livewire/RoleManager.php +++ b/app/Livewire/RoleManager.php @@ -6,19 +6,11 @@ use Livewire\Component; use Livewire\Attributes\Layout; use Illuminate\Support\Facades\Auth; use Spatie\Permission\Models\Role; -use Spatie\Permission\Models\Permission; use Spatie\Permission\PermissionRegistrar; #[Layout('layouts.app')] class RoleManager extends Component { - // Create / edit modal - public bool $showForm = false; - public ?int $editingRole = null; - public string $name = ''; - public string $description = ''; - public array $rolePermissions = []; // selected permission names - // View modal public ?int $viewingRole = null; @@ -46,77 +38,6 @@ class RoleManager extends Component : []; } - // ── Create / Edit ──────────────────────────────────────────────────────── - - public function openCreate(): void - { - $this->resetForm(); - $this->showForm = true; - } - - public function openEdit(int $id): void - { - $role = Role::with('permissions')->findOrFail($id); - $this->editingRole = $role->id; - $this->name = $role->name; - $this->description = $role->description ?? ''; - $this->rolePermissions = $role->permissions->pluck('name')->toArray(); - $this->resetErrorBag(); - $this->viewingRole = null; // close the view modal if open - $this->showForm = true; - } - - public function save(): void - { - $this->validate([ - 'name' => 'required|string|max:50|unique:roles,name' . ($this->editingRole ? ',' . $this->editingRole : ''), - 'description' => 'nullable|string|max:255', - ], [], ['name' => 'nombre', 'description' => 'descripción']); - - if ($this->editingRole) { - $role = Role::findOrFail($this->editingRole); - $isProtected = in_array($role->name, self::PROTECTED_ROLES, true); - - // Protected roles can't be renamed - if (! $isProtected) { - $role->name = $this->name; - } - $role->description = $this->description ?: null; - $role->save(); - - $perms = $this->rolePermissions; - // Admin always keeps the core permission - if ($role->name === 'Admin' && ! in_array(self::CORE_PERMISSION, $perms, true)) { - $perms[] = self::CORE_PERMISSION; - } - $role->syncPermissions($perms); - } else { - $role = Role::create([ - 'name' => $this->name, - 'description' => $this->description ?: null, - ]); - if (! empty($this->rolePermissions)) { - $role->syncPermissions($this->rolePermissions); - } - } - - $this->flushCache(); - $this->closeForm(); - $this->dispatch('notify', 'Rol guardado correctamente'); - } - - public function closeForm(): void - { - $this->showForm = false; - $this->resetForm(); - } - - private function resetForm(): void - { - $this->reset(['editingRole', 'name', 'description', 'rolePermissions']); - $this->resetErrorBag(); - } - // ── View ───────────────────────────────────────────────────────────────── public function openView(int $id): void @@ -155,6 +76,7 @@ class RoleManager extends Component $deleted++; } $this->selected = []; + $this->selectAll = false; $this->flushCache(); $msg = "{$deleted} rol(es) eliminados"; if ($skipped) $msg .= " ({$skipped} protegido(s) omitido(s))"; @@ -164,9 +86,8 @@ class RoleManager extends Component public function render() { return view('livewire.role-manager', [ - 'roles' => Role::with('permissions')->withCount('users')->orderBy('name')->get(), - 'permissions' => Permission::orderBy('name')->get(), - 'viewing' => $this->viewingRole + 'roles' => Role::with('permissions')->withCount('users')->orderBy('name')->get(), + 'viewing' => $this->viewingRole ? Role::with('permissions')->withCount('users')->find($this->viewingRole) : null, ]); diff --git a/resources/views/livewire/role-manager.blade.php b/resources/views/livewire/role-manager.blade.php index aff05e2..4ac11a7 100644 --- a/resources/views/livewire/role-manager.blade.php +++ b/resources/views/livewire/role-manager.blade.php @@ -10,9 +10,9 @@ {{ __('Matrix view') }} - + {{ __('New role') }} - + @@ -68,9 +68,9 @@ - + - + @unless(in_array($role->name, ['Admin'], true)) - {{-- ════════════════ MODAL CREAR / EDITAR ════════════════ --}} - @if($showForm) - - - - {{ $editingRole ? __('Edit role') : __('New role') }} - - - - - {{-- Nombre --}} - - {{ __('Name') }} * - - @error('name') {{ $message }} @enderror - - - {{-- Descripción --}} - - {{ __('Description') }} - - @error('description') {{ $message }} @enderror - - - {{-- Permisos --}} - - {{ __('Permissions') }} - - @foreach($permissions as $perm) - - - {{ $perm->name }} - - @endforeach - - - - - {{ __('Cancel') }} - - - {{ $editingRole ? __('Update') : __('Create') }} - - - - - - - @endif - {{-- ════════════════ MODAL VER ════════════════ --}} @if($viewing) @@ -170,9 +114,9 @@ @endif - + {{ __('Edit') }} - + {{ __('Close') }} diff --git a/resources/views/livewire/roles/role-form.blade.php b/resources/views/livewire/roles/role-form.blade.php new file mode 100644 index 0000000..6b1580b --- /dev/null +++ b/resources/views/livewire/roles/role-form.blade.php @@ -0,0 +1,73 @@ + + + + + {{ $role ? __('Edit role') : __('New role') }} + + + {{ __('Back') }} + + + + + + + {{-- Nombre --}} + + + {{ __('Name') }} * + + + + @error('name') {{ $message }} @enderror + @if($isProtected) + {{ __('This role is protected and cannot be renamed.') }} + @endif + + + + {{-- Descripción --}} + + + {{ __('Description') }} + + + + @error('description') {{ $message }} @enderror + + + + {{-- Permisos --}} + + + {{ __('Permissions') }} + + + + @foreach($permissions as $perm) + + + {{ $perm->name }} + + @endforeach + + + + + + {{ __('Cancel') }} + + + + {{ $role ? __('Update role') : __('Create role') }} + + + + + diff --git a/routes/web.php b/routes/web.php index 488b833..53c3b3b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -137,6 +137,8 @@ Route::get('/reports/dashboard', ReportsDashboard::class)->name('reports.dashboa Route::get('/users/{user}', \App\Livewire\UserView::class)->name('users.show'); Route::get('/users/{user}/edit', \App\Livewire\UserForm::class)->name('users.edit'); Route::get('/roles', \App\Livewire\RoleManager::class)->name('roles'); + Route::get('/roles/create', \App\Livewire\RoleForm::class)->name('roles.create'); + Route::get('/roles/{role}/edit', \App\Livewire\RoleForm::class)->name('roles.edit'); Route::get('/permissions', \App\Livewire\RolePermissionManager::class)->name('permissions'); });
{{ $message }}
{{ __('This role is protected and cannot be renamed.') }}