Files
construprogress/app/Livewire/Tasks/TaskManager.php
T

187 lines
5.3 KiB
PHP
Raw Normal View History

<?php
namespace App\Livewire\Tasks;
use App\Models\Project;
use App\Models\Task;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithPagination;
#[Layout('layouts.app')]
class TaskManager extends Component
{
use WithPagination;
public ?Project $project = null;
public $search = '';
public $statusFilter = '';
public $priorityFilter = '';
public $assigneeFilter = '';
public $phaseFilter = '';
public $showOverdueOnly = false;
public $perPage = 25;
public $sortField = 'created_at';
public $sortDirection = 'desc';
public $viewMode = 'table'; // 'table' or 'kanban'
protected $queryString = [
'search' => ['except' => ''],
'statusFilter' => ['except' => ''],
'priorityFilter' => ['except' => ''],
'assigneeFilter' => ['except' => ''],
'phaseFilter' => ['except' => ''],
'showOverdueOnly' => ['except' => false],
'perPage' => ['except' => 25],
'sortField' => ['except' => 'created_at'],
'sortDirection' => ['except' => 'desc'],
'viewMode' => ['except' => 'table'],
];
public function mount(?Project $project = null): void
{
$this->project = $project;
if ($project) {
abort_unless($this->canAccessProject() && Auth::user()->can('view tasks'), 403);
} else {
abort_unless(Auth::user()->can('view tasks'), 403);
}
}
private function canAccessProject(): bool
{
$user = Auth::user();
return $user->can('manage all')
|| ($this->project && $this->project->users()->where('user_id', $user->id)->exists());
}
#[On('tasksChanged')]
public function refreshTasks(): void
{
// Trigger re-render
}
public function sortBy(string $field): void
{
if ($this->sortField === $field) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
} else {
$this->sortField = $field;
$this->sortDirection = 'asc';
}
}
public function resetFilters(): void
{
$this->reset(['search', 'statusFilter', 'priorityFilter', 'assigneeFilter', 'phaseFilter', 'showOverdueOnly']);
$this->resetPage();
}
public function deleteTask(Task $task): void
{
abort_unless(Auth::user()->can('delete', $task), 403);
$task->delete();
session()->flash('message', 'Tarea eliminada');
$this->dispatch('tasksChanged');
}
public function toggleViewMode(): void
{
$this->viewMode = $this->viewMode === 'table' ? 'kanban' : 'table';
}
public function render()
{
$user = Auth::user();
$query = Task::with(['project', 'phase', 'assignee', 'creator', 'subtasks'])
->where(function ($q) use ($user) {
if (! $user->can('manage all tasks')) {
$q->whereHas('project', function ($sub) use ($user) {
$sub->whereHas('users', function ($sub2) use ($user) {
$sub2->where('user_id', $user->id);
});
});
}
});
if ($this->project) {
$query->where('project_id', $this->project->id);
}
if ($this->search) {
$query->where(function ($q) {
$q->where('title', 'like', '%'.$this->search.'%')
->orWhere('description', 'like', '%'.$this->search.'%');
});
}
if ($this->statusFilter) {
$query->where('status', $this->statusFilter);
}
if ($this->priorityFilter) {
$query->where('priority', $this->priorityFilter);
}
if ($this->assigneeFilter) {
$query->where('assigned_to', $this->assigneeFilter);
}
if ($this->phaseFilter) {
$query->where('phase_id', $this->phaseFilter);
}
if ($this->showOverdueOnly) {
$query->overdue();
}
// Sorting
$allowedSorts = ['title', 'status', 'priority', 'due_date', 'created_at', 'order'];
if (in_array($this->sortField, $allowedSorts)) {
$query->orderBy($this->sortField, $this->sortDirection);
} else {
$query->orderBy('order')->orderBy('created_at', 'desc');
}
$tasks = $query->paginate($this->perPage);
// Filter options
$assignees = User::whereHas('assignedTasks', function ($q) use ($user) {
if (! $user->can('manage all tasks')) {
$q->whereHas('project', function ($sub) use ($user) {
$sub->whereHas('users', function ($sub2) use ($user) {
$sub2->where('user_id', $user->id);
});
});
}
})->get(['id', 'name']);
$phases = $this->project
? $this->project->phases()->get(['id', 'name'])
: collect();
return view('livewire.tasks.task-manager', [
'tasks' => $tasks,
'assignees' => $assignees,
'phases' => $phases,
'statusOptions' => Task::statusOptions(),
'priorityOptions' => Task::priorityOptions(),
]);
}
}