diff --git a/app/api/leantime/status-labels/route.ts b/app/api/leantime/status-labels/route.ts index 9986520d..816fb64a 100644 --- a/app/api/leantime/status-labels/route.ts +++ b/app/api/leantime/status-labels/route.ts @@ -8,8 +8,14 @@ interface Task { projectName: string; status: string; dueDate: string | null; - details?: string; - milestone?: string; + details?: string | null; + milestone?: string | null; + class: string; +} + +interface Project { + id: number; + name: string; } // Cache for user IDs @@ -132,68 +138,53 @@ export async function GET() { console.log('Projects response:', JSON.stringify(projectsData, null, 2)); const projectsMap = new Map( - projectsData.result.map((project: any) => [project.id, project.name]) + projectsData.result.map((project: Project) => [project.id, project.name]) ); - // Define status code mapping - const statusMapping: Record = { - '-1': 'archived', - '0': 'new', - '1': 'in progress', - '2': 'waiting', - '3': 'in review', - '4': 'done' - }; - // Transform the nested structure into a flat array of tasks const tasks: Task[] = []; Object.entries(data.result).forEach(([projectId, statusGroups]) => { - const projectName = projectsMap.get(Number(projectId)) || `Project ${projectId}`; + const project = projectsData.result.find((p: Project) => p.id === Number(projectId)); + const projectName = project ? project.name : `Project ${projectId}`; if (typeof statusGroups === 'object' && statusGroups !== null) { // Iterate through each status group - Object.entries(statusGroups).forEach(([statusType, statusLabels]) => { - if (typeof statusLabels === 'object' && statusLabels !== null) { - // Each status label in the group - Object.values(statusLabels).forEach((label: any) => { - const statusName = statusMapping[statusType] || `status-${statusType}`; - const headline = String(label.title || label.name || statusName); - - tasks.push({ - id: label.id?.toString() || `${projectId}-${statusType}`, - headline, - projectName, - status: statusName, - dueDate: null, - details: label.description || null, - milestone: label.milestone || null - }); + Object.entries(statusGroups).forEach(([_, label]) => { + if (typeof label === 'object' && label !== null && 'name' in label) { + const statusLabel = label as { + name: string; + class: string; + statusType: string; + kanbanCol: string; + sortKey: string; + }; + + tasks.push({ + id: `${projectId}-${statusLabel.sortKey}`, + headline: statusLabel.name, + projectName, + status: statusLabel.statusType.toLowerCase(), + dueDate: null, + details: undefined, + milestone: undefined, + class: statusLabel.class }); } }); } }); - // Sort tasks by status type - const statusOrder: Record = { - 'new': 1, - 'in progress': 2, - 'waiting': 3, - 'in review': 4, - 'done': 5, - 'archived': 6 - }; - + // Sort tasks by their sortKey tasks.sort((a, b) => { - const statusA = statusOrder[a.status.toLowerCase()] || 99; - const statusB = statusOrder[b.status.toLowerCase()] || 99; - return statusA - statusB; + const sortKeyA = Number(a.id.split('-')[1]) || 99; + const sortKeyB = Number(b.id.split('-')[1]) || 99; + return sortKeyA - sortKeyB; }); - // Deduplicate tasks based on project and status + // Deduplicate tasks based on headline and status const uniqueTasks = tasks.reduce((acc: Task[], task) => { const existingTask = acc.find(t => - t.projectName === task.projectName && + t.headline === task.headline && t.status === task.status ); diff --git a/components/flow.tsx b/components/flow.tsx index df1b848e..989d7016 100644 --- a/components/flow.tsx +++ b/components/flow.tsx @@ -4,7 +4,6 @@ import { useEffect, useState } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { RefreshCw } from "lucide-react"; -import { formatDate } from "@/lib/utils"; interface Task { id: string; @@ -12,8 +11,9 @@ interface Task { projectName: string; status: string; dueDate: string | null; - details?: string; - milestone?: string; + details?: string | null; + milestone?: string | null; + class: string; } export function Flow() { @@ -63,25 +63,6 @@ export function Flow() { }; }, []); - const getStatusColor = (status: string) => { - switch (status.toLowerCase()) { - case 'new': - return 'text-blue-600'; - case 'blocked': - return 'text-red-600'; - case 'in progress': - case 'inprogress': - return 'text-orange-600'; - case 'done': - case 'archived': - return 'text-green-600'; - case 'waiting for approval': - return 'text-yellow-600'; - default: - return 'text-gray-600'; - } - }; - // Group tasks by project const groupedTasks = tasks.reduce((acc, task) => { if (!acc[task.projectName]) { @@ -124,18 +105,8 @@ export function Flow() {
{task.headline}
- {task.milestone && ( -
- {task.milestone} -
- )} - {task.dueDate && ( -
- {formatDate(task.dueDate)} -
- )}
-
+
{task.status.toUpperCase()}
@@ -148,4 +119,18 @@ export function Flow() { ); +} + +function getLabelClass(className: string): string { + const classMap: Record = { + 'label-default': 'bg-gray-100 text-gray-800', + 'label-success': 'bg-green-100 text-green-800', + 'label-warning': 'bg-yellow-100 text-yellow-800', + 'label-info': 'bg-blue-100 text-blue-800', + 'label-blue': 'bg-blue-100 text-blue-800', + 'label-darker-blue': 'bg-indigo-100 text-indigo-800', + 'label-dark-green': 'bg-emerald-100 text-emerald-800', + }; + + return classMap[className] || 'bg-gray-100 text-gray-800'; } \ No newline at end of file