소스 검색

project kanban

moell 1 년 전
부모
커밋
27b885afaf

+ 10 - 0
app/Http/Controllers/API/ProjectController.php

@@ -24,6 +24,7 @@ use App\Models\ProjectPlan;
 use App\Models\ProjectRequirement;
 use App\Models\Requirement;
 use App\Repositories\ActionRepository;
+use App\Services\Project\ProjectKanbanService;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
@@ -332,4 +333,13 @@ class ProjectController extends Controller
             'data' => ActionRepository::dynamic($project, $request->all())
         ]);
     }
+
+    public function kanban(Request $request, ProjectKanbanService $service, string $id)
+    {
+        $project = Project::findOrFail($id);
+
+        return $this->success([
+            'data' => $service->kanban($project, $request->get("group", "requirement_asc"))
+        ]);
+    }
 }

+ 24 - 0
app/Http/Resources/API/KanbanTaskResource.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Resources\API;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class KanbanTaskResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @return array<string, mixed>
+     */
+    public function toArray(Request $request): array
+    {
+        return [
+            'id' => $this->id,
+            'name' => $this->name,
+            'end' => $this->end,
+            'assign' => new UserProfileResource($this->assignTo),
+        ];
+    }
+}

+ 5 - 0
app/Models/Project.php

@@ -40,4 +40,9 @@ class Project extends Model
     {
         return $this->hasMany(TeamMember::class);
     }
+
+    public function tasks(): \Illuminate\Database\Eloquent\Relations\HasMany
+    {
+        return $this->hasMany(Task::class);
+    }
 }

+ 70 - 0
app/Services/Project/ProjectKanbanService.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Services\Project;
+
+use App\Http\Resources\API\KanbanTaskResource;
+use App\Http\Resources\API\UserProfileResource;
+use App\Models\Enums\ProjectStatus;
+use App\Models\Project;
+use App\Models\Requirement;
+use App\Models\User;
+
+class ProjectKanbanService
+{
+    public function kanban(Project $project, $group = "requirement_asc")
+    {
+        $groupKey = match ($group) {
+            "assign" => "assign",
+            "finished_by" => "finished_by",
+            default => "requirement_id"
+        };
+
+        $groupTasks = $project->tasks()->with(['assignTo'])->get()->groupBy($groupKey);
+
+        $statusItems = array_column(ProjectStatus::cases(), 'value');
+
+        $items = [];
+        $groupIds = [];
+        foreach ($groupTasks as $groupId => $tasks) {
+            $groupItems = [];
+
+            foreach ($statusItems as $status) {
+                $groupItems[$status] = [];
+            }
+
+            foreach ($tasks as $task) {
+                $groupItems[$task->status][] = new KanbanTaskResource($task);
+            }
+
+            $items[$groupId ?: "empty"] = $groupItems;
+            $groupIds[] = $groupId;
+        }
+
+        return [
+            'group_data' => $this->getKanbanGroupData($groupIds, $group),
+            'group' => $group,
+            'tasks' => $items,
+            'status_items' => $statusItems,
+        ];
+    }
+
+    protected function getKanbanGroupData(array $ids, string $group)
+    {
+        $orderBy = match ($group) {
+            "requirement_asc" => ['id', 'asc'],
+            "requirement_desc" => ['id', 'desc'],
+            "requirement_priority_asc" => ['priority', 'asc'],
+            "requirement_priority_desc" => ['priority', 'desc'],
+            default => null
+        };
+
+        return match ($group) {
+            "assign", "finished_by" => UserProfileResource::collection(User::query()->whereIn("id", $ids)->get()),
+            default => Requirement::query()->whereIn("id", $ids)
+                ->when($orderBy, fn($query) => $query->orderBy(...$orderBy))
+                ->get([
+                    'id', 'title', 'priority', 'status'
+                ]),
+        };
+    }
+}

+ 1 - 0
routes/api.php

@@ -45,6 +45,7 @@ Route::middleware(['auth:sanctum'])->group(function () {
         Route::patch("requirement/plan/unlink", [API\RequirementController::class, "unlinkPlan"])->name("requirement.unlinkPlan");
 
         Route::get("project/{project}/dynamic", [API\ProjectController::class, "dynamic"])->name("project.dynamic");
+        Route::get("project/{project}/kanban", [API\ProjectController::class, "kanban"])->name("project.kanban");
         Route::patch("project/{project}/closed", [API\ProjectController::class, "closed"])->name("project.closed");
         Route::patch("project/{project}/start", [API\ProjectController::class, "start"])->name("project.start");
         Route::patch("project/{project}/pause", [API\ProjectController::class, "pause"])->name("project.pause");