Permet de créer une tâche directement depuis le tableau de bord

Ajoute un formulaire rapide dans la carte "Tâches ouvertes" du dashboard, évitant de passer par la page ToDo dédiée pour les créations simples.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
mrKamoo
2026-08-21 09:14:28 +02:00
co-authored by Claude Sonnet 5
parent c35833ed0b
commit 74c0b01a2e
@@ -1,6 +1,8 @@
<?php <?php
use App\Models\Organization; use App\Models\Organization;
use App\Models\Todo;
use App\Models\User;
use App\Services\Glpi\GlpiClient; use App\Services\Glpi\GlpiClient;
use Livewire\Component; use Livewire\Component;
@@ -11,6 +13,13 @@ new class extends Component
public string $newLogCategory = 'info'; public string $newLogCategory = 'info';
public string $newLogNote = ''; public string $newLogNote = '';
public bool $showTodoForm = false;
public string $newTodoTitle = '';
public string $newTodoCategory = 'infra';
public string $newTodoCriticality = 'medium';
public ?string $newTodoDueDate = null;
public ?int $newTodoAssignedTo = null;
public int $activityPage = 1; public int $activityPage = 1;
const ACTIVITY_PER_PAGE = 4; const ACTIVITY_PER_PAGE = 4;
@@ -45,6 +54,33 @@ new class extends Component
]); ]);
} }
public function toggleTodoForm(): void
{
$this->showTodoForm = ! $this->showTodoForm;
}
public function addTodo(): void
{
$validated = $this->validate([
'newTodoTitle' => 'required|string|max:255',
'newTodoCategory' => 'required|in:'.implode(',', array_keys(Todo::CATEGORIES)),
'newTodoCriticality' => 'required|in:'.implode(',', array_keys(Todo::CRITICALITIES)),
'newTodoDueDate' => 'nullable|date',
'newTodoAssignedTo' => 'nullable|exists:users,id',
]);
$this->organization->todos()->create([
'title' => $validated['newTodoTitle'],
'category' => $validated['newTodoCategory'],
'criticality' => $validated['newTodoCriticality'],
'due_date' => $validated['newTodoDueDate'],
'assigned_to' => $validated['newTodoAssignedTo'],
'created_by' => auth()->id(),
]);
$this->reset(['newTodoTitle', 'newTodoCategory', 'newTodoCriticality', 'newTodoDueDate', 'newTodoAssignedTo', 'showTodoForm']);
}
public function previousActivityPage(): void public function previousActivityPage(): void
{ {
$this->activityPage = max(1, $this->activityPage - 1); $this->activityPage = max(1, $this->activityPage - 1);
@@ -155,6 +191,7 @@ new class extends Component
'recentActivity' => $recentActivity, 'recentActivity' => $recentActivity,
'activityPageCount' => $activityPageCount, 'activityPageCount' => $activityPageCount,
'openTodos' => $openTodos, 'openTodos' => $openTodos,
'assignableUsers' => User::role(['Administrateur', 'Technicien'])->orderBy('name')->get(),
'logEntries' => $this->organization->logEntries()->with('creator')->limit(20)->get(), 'logEntries' => $this->organization->logEntries()->with('creator')->limit(20)->get(),
'categories' => \App\Models\OrganizationLogEntry::CATEGORIES, 'categories' => \App\Models\OrganizationLogEntry::CATEGORIES,
]; ];
@@ -251,12 +288,12 @@ new class extends Component
@if ($activityPageCount > 1) @if ($activityPageCount > 1)
<div class="mt-3 flex items-center justify-between border-t border-slate-100 pt-3 text-xs text-slate-500"> <div class="mt-3 flex items-center justify-between border-t border-slate-100 pt-3 text-xs text-slate-500">
<button type="button" wire:click="previousActivityPage" @disabled($activityPage <= 1) <button type="button" wire:click="previousActivityPage" @disabled($activityPage <= 1)
class="text-slate-600 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:text-slate-300"> class="cursor-pointer text-slate-600 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:text-slate-300">
&larr; Précédent &larr; Précédent
</button> </button>
<span>Page {{ $activityPage }} / {{ $activityPageCount }}</span> <span>Page {{ $activityPage }} / {{ $activityPageCount }}</span>
<button type="button" wire:click="nextActivityPage" @disabled($activityPage >= $activityPageCount) <button type="button" wire:click="nextActivityPage" @disabled($activityPage >= $activityPageCount)
class="text-slate-600 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:text-slate-300"> class="cursor-pointer text-slate-600 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:text-slate-300">
Suivant &rarr; Suivant &rarr;
</button> </button>
</div> </div>
@@ -268,10 +305,54 @@ new class extends Component
<div class="rounded border border-slate-200 bg-white p-4"> <div class="rounded border border-slate-200 bg-white p-4">
<div class="mb-3 flex items-center justify-between"> <div class="mb-3 flex items-center justify-between">
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Tâches ouvertes</h2> <h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Tâches ouvertes</h2>
<div class="flex items-center gap-3">
<button type="button" wire:click="toggleTodoForm"
class="cursor-pointer text-xs text-slate-500 hover:text-slate-900">
{{ $showTodoForm ? 'Annuler' : '+ Nouvelle tâche' }}
</button>
<a href="{{ route('organizations.todos.index', $organization) }}" class="text-xs text-slate-500 hover:text-slate-900"> <a href="{{ route('organizations.todos.index', $organization) }}" class="text-xs text-slate-500 hover:text-slate-900">
Voir toutes les tâches &rarr; Voir toutes les tâches &rarr;
</a> </a>
</div> </div>
</div>
@if ($showTodoForm)
<form wire:submit="addTodo" class="mb-4 space-y-2 rounded border border-slate-100 bg-slate-50 p-3">
<div>
<input type="text" wire:model="newTodoTitle" placeholder="Titre de la tâche"
class="w-full rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500">
@error('newTodoTitle') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div class="grid grid-cols-2 gap-2 sm:grid-cols-4">
<select wire:model="newTodoCategory"
class="rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500">
@foreach (Todo::CATEGORIES as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
<select wire:model="newTodoCriticality"
class="rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500">
@foreach (Todo::CRITICALITIES as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
<input type="date" wire:model="newTodoDueDate"
class="rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500">
<select wire:model="newTodoAssignedTo"
class="rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500">
<option value="">Assigné à —</option>
@foreach ($assignableUsers as $user)
<option value="{{ $user->id }}">{{ $user->name }}</option>
@endforeach
</select>
</div>
<div class="flex items-center gap-3 pt-1">
<button type="submit" class="cursor-pointer rounded bg-slate-900 px-3 py-1.5 text-sm text-white hover:bg-slate-700">
Créer la tâche
</button>
</div>
</form>
@endif
<ul class="divide-y divide-slate-100"> <ul class="divide-y divide-slate-100">
@forelse ($openTodos as $todo) @forelse ($openTodos as $todo)
@@ -322,7 +403,7 @@ new class extends Component
</select> </select>
<textarea wire:model="newLogNote" rows="2" placeholder="Projet en cours, point d'attention, intervention prévue..." <textarea wire:model="newLogNote" rows="2" placeholder="Projet en cours, point d'attention, intervention prévue..."
class="flex-1 rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500"></textarea> class="flex-1 rounded border-slate-300 text-sm shadow-sm focus:border-slate-500 focus:ring-slate-500"></textarea>
<button type="submit" class="rounded bg-slate-900 px-3 py-1.5 text-sm text-white hover:bg-slate-700">Ajouter</button> <button type="submit" class="cursor-pointer rounded bg-slate-900 px-3 py-1.5 text-sm text-white hover:bg-slate-700">Ajouter</button>
</div> </div>
@error('newLogNote') <p class="text-sm text-red-600">{{ $message }}</p> @enderror @error('newLogNote') <p class="text-sm text-red-600">{{ $message }}</p> @enderror
</form> </form>
@@ -345,7 +426,7 @@ new class extends Component
</div> </div>
<button type="button" wire:click="deleteLogEntry({{ $entry->id }})" <button type="button" wire:click="deleteLogEntry({{ $entry->id }})"
wire:confirm="Supprimer cette entrée ?" wire:confirm="Supprimer cette entrée ?"
class="shrink-0 text-xs text-red-500 hover:text-red-700"> class="cursor-pointer shrink-0 text-xs text-red-500 hover:text-red-700">
Supprimer Supprimer
</button> </button>
</div> </div>