refactor(livewire): organizar componentes y vistas por dominio en subnamespaces
- app/Livewire: 34 componentes agrupados en Issues/, Projects/, Phases/, Companies/, Users/, Admin/, Inspections/, Layers/, Media/, Common/ (Client/, Reports/, Forms/, Actions/ ya estaban). Namespaces actualizados. - resources/views/livewire: vistas sueltas movidas a subcarpetas espejo (companies/, users/, phases/, roles/, inspections/, media/, common/); render() actualizado. - Referencias actualizadas sin romper nada: rutas (FQN, nombres de ruta intactos), tags <livewire:...>/@livewire() a alias con punto, y use de los tests. - No tocado: Volt de Breeze (auth/profile/navigation), y el portal cliente (user-nav/client-projects) que ya tenía referencias inconsistentes. Verificado: 69 rutas OK, vistas compilan, suite 69 passing (solo 2 pre-existentes sqlite). autoload regenerado con --ignore-platform-reqs (PHP 8.2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Users;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Layout;
|
||||
use App\Models\User;
|
||||
use App\Models\Project;
|
||||
use App\Models\Inspection;
|
||||
use App\Models\Issue;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\PermissionRegistrar;
|
||||
|
||||
#[Layout('layouts.app')]
|
||||
class UserView extends Component
|
||||
{
|
||||
public User $user;
|
||||
public string $activeTab = 'ficha';
|
||||
|
||||
// Projects tab
|
||||
public ?int $addProjectId = null;
|
||||
public string $addProjectRole = '';
|
||||
public $availableProjects;
|
||||
|
||||
// Notes tab
|
||||
public string $notes = '';
|
||||
public bool $editingNotes = false;
|
||||
|
||||
// Recent activity (loaded once)
|
||||
public $recentInspections;
|
||||
public $recentIssues;
|
||||
|
||||
public function mount(User $user): void
|
||||
{
|
||||
abort_unless(Auth::user()->can('view users'), 403);
|
||||
|
||||
$this->user = $user->load(['roles', 'company', 'projects.phases']);
|
||||
$this->notes = $user->notes ?? '';
|
||||
|
||||
$this->loadAvailableProjects();
|
||||
$this->loadActivity();
|
||||
}
|
||||
|
||||
private function loadAvailableProjects(): void
|
||||
{
|
||||
$assignedIds = $this->user->projects->pluck('id');
|
||||
$this->availableProjects = Project::whereNotIn('id', $assignedIds)
|
||||
->orderBy('name')->get();
|
||||
}
|
||||
|
||||
private function loadActivity(): void
|
||||
{
|
||||
$this->recentInspections = Inspection::where('user_id', $this->user->id)
|
||||
->with(['feature.layer.phase.project', 'template'])
|
||||
->latest()->take(8)->get();
|
||||
|
||||
$this->recentIssues = Issue::where('reported_by', $this->user->id)
|
||||
->with(['feature', 'project'])
|
||||
->latest()->take(8)->get();
|
||||
}
|
||||
|
||||
// ── Tabs ─────────────────────────────────────────────────────────────────
|
||||
|
||||
public function setTab(string $tab): void
|
||||
{
|
||||
$this->activeTab = $tab;
|
||||
}
|
||||
|
||||
// ── Projects ──────────────────────────────────────────────────────────────
|
||||
|
||||
public function assignProject(): void
|
||||
{
|
||||
$this->validate([
|
||||
'addProjectId' => 'required|exists:projects,id',
|
||||
'addProjectRole' => 'nullable|string|max:100',
|
||||
], [], ['addProjectId' => 'proyecto', 'addProjectRole' => 'rol en proyecto']);
|
||||
|
||||
$this->user->projects()->attach($this->addProjectId, [
|
||||
'role_in_project' => $this->addProjectRole ?: null,
|
||||
]);
|
||||
|
||||
$this->user->load('projects.phases');
|
||||
$this->addProjectId = null;
|
||||
$this->addProjectRole = '';
|
||||
$this->loadAvailableProjects();
|
||||
$this->dispatch('notify', 'Proyecto asignado.');
|
||||
}
|
||||
|
||||
public function removeProject(int $projectId): void
|
||||
{
|
||||
$this->user->projects()->detach($projectId);
|
||||
$this->user->load('projects.phases');
|
||||
$this->loadAvailableProjects();
|
||||
$this->dispatch('notify', 'Proyecto desasignado.');
|
||||
}
|
||||
|
||||
// ── Permissions (direct, per user) ─────────────────────────────────────────
|
||||
|
||||
public function togglePermission(string $name): void
|
||||
{
|
||||
if ($this->user->hasDirectPermission($name)) {
|
||||
$this->user->revokePermissionTo($name);
|
||||
} else {
|
||||
$this->user->givePermissionTo($name);
|
||||
}
|
||||
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
||||
$this->user->load('roles', 'permissions');
|
||||
$this->dispatch('notify', 'Permisos del usuario actualizados');
|
||||
}
|
||||
|
||||
public function setUserGroup(string $group, bool $enabled): void
|
||||
{
|
||||
foreach (Permission::where('group', $group)->pluck('name') as $name) {
|
||||
if ($enabled) {
|
||||
if (! $this->user->hasPermissionTo($name)) {
|
||||
$this->user->givePermissionTo($name);
|
||||
}
|
||||
} elseif ($this->user->hasDirectPermission($name)) {
|
||||
$this->user->revokePermissionTo($name);
|
||||
}
|
||||
}
|
||||
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
||||
$this->user->load('roles', 'permissions');
|
||||
$this->dispatch('notify', $enabled ? 'Permisos del grupo concedidos' : 'Permisos directos del grupo quitados');
|
||||
}
|
||||
|
||||
// ── Notes ─────────────────────────────────────────────────────────────────
|
||||
|
||||
public function saveNotes(): void
|
||||
{
|
||||
$this->validate(['notes' => 'nullable|string']);
|
||||
$this->user->update(['notes' => $this->notes ?: null]);
|
||||
$this->editingNotes = false;
|
||||
$this->dispatch('notify', 'Notas guardadas.');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$order = [
|
||||
'Proyectos', 'Fases y progreso', 'Capas y elementos', 'Inspecciones',
|
||||
'Incidencias', 'Empresas', 'Usuarios', 'Roles', 'Informes', 'Archivos', 'General',
|
||||
];
|
||||
|
||||
$grouped = Permission::orderBy('name')->get()
|
||||
->groupBy(fn ($perm) => $perm->group ?: 'General')
|
||||
->sortBy(function ($perms, $section) use ($order) {
|
||||
$i = array_search($section, $order, true);
|
||||
return $i === false ? 999 : $i;
|
||||
});
|
||||
|
||||
return view('livewire.users.user-view', [
|
||||
'grouped' => $grouped,
|
||||
'directPerms' => $this->user->getDirectPermissions()->pluck('name')->toArray(),
|
||||
'rolePerms' => $this->user->getPermissionsViaRoles()->pluck('name')->toArray(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user