Fix todo due date also counting completed items

This commit is contained in:
2026-03-04 14:43:01 +01:00
parent 8ff955415c
commit 4ee1d01e38
4 changed files with 21 additions and 7 deletions
+7 -3
View File
@@ -91,15 +91,19 @@ ### Steps
cp .env.example .env cp .env.example .env
sudo php artisan key\:generate sudo php artisan key\:generate
``` ```
5. Run migrations and seeders: 5. Create a symbolic link for public storage
```bash
sudo php artisan storage:link
```
6. Run migrations and seeders:
```bash ```bash
sudo php artisan migrate --seed sudo php artisan migrate --seed
``` ```
6. Build frontend assets: 7. Build frontend assets:
```bash ```bash
npm run build npm run build
``` ```
7. Start the development server: 8. Start the development server:
```bash ```bash
php artisan serve php artisan serve
``` ```
+6 -1
View File
@@ -39,7 +39,12 @@ public function index()
// Process items to add latest_todo_due_date and remove todos array // Process items to add latest_todo_due_date and remove todos array
$laneArray['items'] = collect($laneArray['items'])->map(function ($item) { $laneArray['items'] = collect($laneArray['items'])->map(function ($item) {
$item['next_todo_due_date'] = $item['todos'][0]['due_date'] ?? null; // Find the first todo with status != 'COMPLETED'
$nextTodo = collect($item['todos'])->first(function ($todo) {
return strtolower($todo['status'] ?? '') !== 'completed';
});
$item['next_todo_due_date'] = $nextTodo['due_date'] ?? null;
unset($item['todos']); // Remove the todos array unset($item['todos']); // Remove the todos array
return $item; return $item;
})->toArray(); })->toArray();
@@ -19,14 +19,16 @@ public function index()
$query->where('notable_type', 'App\Models\PipelineItem'); $query->where('notable_type', 'App\Models\PipelineItem');
}]) }])
->withCount(['todos' => function ($query) { ->withCount(['todos' => function ($query) {
$query->where('todoable_type', 'App\Models\PipelineItem'); $query
->where('todoable_type', 'App\Models\PipelineItem')
->whereNotIn('status', ['completed', 'COMPLETED']);
}]) }])
->orderBy('position') ->orderBy('position')
->get(); ->get();
$pipelineItemsArray = $pipelineItems->map(function ($item) { $pipelineItemsArray = $pipelineItems->map(function ($item) {
$itemArray = $item->toArray(); $itemArray = $item->toArray();
$itemArray['next_todo_due_date'] = $item->todos->first()?->due_date?->toISOString() ?? null; $itemArray['next_todo_due_date'] = $item->todos()->where('status', '!=', 'COMPLETED')->first()?->due_date?->toISOString() ?? null;
unset($itemArray['todos']); // Remove the todos array unset($itemArray['todos']); // Remove the todos array
return $itemArray; return $itemArray;
}); });
@@ -43,7 +45,8 @@ public function single(int $id)
::with(['notes' => function ($query) { ::with(['notes' => function ($query) {
$query->where('notable_type', 'App\Models\PipelineItem')->orderBy('created_at', 'desc'); $query->where('notable_type', 'App\Models\PipelineItem')->orderBy('created_at', 'desc');
}])->with(['todos' => function ($query) { }])->with(['todos' => function ($query) {
$query->where('todoable_type', 'App\Models\PipelineItem')->orderBy('due_date', 'asc'); $query
->where('todoable_type', 'App\Models\PipelineItem')->orderBy('due_date', 'asc');
}])->orderBy('position')->findOrFail($id); }])->orderBy('position')->findOrFail($id);
return ApiDataTransformer::snakeToCamel($pipelineItem->toArray()); return ApiDataTransformer::snakeToCamel($pipelineItem->toArray());
+2
View File
@@ -133,6 +133,8 @@ const cardClasses = (item: PipelineItem): string => {
if (item.dueDate && isSoon(item.dueDate) || if (item.dueDate && isSoon(item.dueDate) ||
item.nextTodoDueDate && isSoon(item.nextTodoDueDate) item.nextTodoDueDate && isSoon(item.nextTodoDueDate)
) return "border-l-4 border-warning" ) return "border-l-4 border-warning"
return ""
} }
const badgeVariant = (date: string | null): "default" | "secondary" | "destructive" | "warning" | "outline" | null | undefined => { const badgeVariant = (date: string | null): "default" | "secondary" | "destructive" | "warning" | "outline" | null | undefined => {