working leantime widget 9
This commit is contained in:
parent
d9208b489d
commit
af09f37458
@ -107,38 +107,31 @@ export async function GET() {
|
|||||||
|
|
||||||
if (!data.result) {
|
if (!data.result) {
|
||||||
console.log('No result in Leantime response');
|
console.log('No result in Leantime response');
|
||||||
return NextResponse.json({ statusLabels: [] });
|
return NextResponse.json({ projects: [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a map to store unique status labels
|
// Transform the response into a more structured format while maintaining project grouping
|
||||||
const uniqueLabels = new Map();
|
const transformedProjects = Object.entries(data.result as Record<string, Record<string, any>>).map(([projectId, labels]) => {
|
||||||
|
// Convert the labels object to an array and sort by sortKey
|
||||||
|
const sortedLabels = Object.entries(labels).map(([id, label]) => ({
|
||||||
|
id,
|
||||||
|
name: label.name,
|
||||||
|
statusType: label.statusType,
|
||||||
|
class: label.class,
|
||||||
|
sortKey: Number(label.sortKey) || 0,
|
||||||
|
kanbanCol: label.kanbanCol
|
||||||
|
})).sort((a, b) => a.sortKey - b.sortKey);
|
||||||
|
|
||||||
// Transform and deduplicate status labels
|
return {
|
||||||
Object.entries(data.result as Record<string, Record<string, any>>).forEach(([projectId, labels]) => {
|
projectId,
|
||||||
Object.entries(labels).forEach(([id, label]) => {
|
labels: sortedLabels
|
||||||
const key = label.name;
|
};
|
||||||
if (!uniqueLabels.has(key)) {
|
|
||||||
uniqueLabels.set(key, {
|
|
||||||
id,
|
|
||||||
name: label.name,
|
|
||||||
statusType: label.statusType,
|
|
||||||
class: label.class,
|
|
||||||
sortKey: Number(label.sortKey) || 0, // Convert to number, default to 0 if invalid
|
|
||||||
projects: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
uniqueLabels.get(key).projects.push({
|
|
||||||
id: projectId,
|
|
||||||
name: projectId // You might want to fetch project names separately
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert the map to an array and sort by sortKey numerically
|
// Sort projects by ID for consistency
|
||||||
const transformedLabels = Array.from(uniqueLabels.values())
|
transformedProjects.sort((a, b) => a.projectId.localeCompare(b.projectId));
|
||||||
.sort((a, b) => a.sortKey - b.sortKey);
|
|
||||||
|
|
||||||
return NextResponse.json({ statusLabels: transformedLabels });
|
return NextResponse.json({ projects: transformedProjects });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Detailed error in status labels fetch:', error);
|
console.error('Detailed error in status labels fetch:', error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@ -7,22 +7,22 @@ import { RefreshCw } from "lucide-react";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
|
|
||||||
interface Project {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StatusLabel {
|
interface StatusLabel {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
statusType: string;
|
statusType: string;
|
||||||
class: string;
|
class: string;
|
||||||
sortKey: string;
|
sortKey: number;
|
||||||
projects: Project[];
|
kanbanCol: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Project {
|
||||||
|
projectId: string;
|
||||||
|
labels: StatusLabel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Flow() {
|
export function Flow() {
|
||||||
const [statusLabels, setStatusLabels] = useState<StatusLabel[]>([]);
|
const [projects, setProjects] = useState<Project[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
@ -50,7 +50,7 @@ export function Flow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
setStatusLabels(data.statusLabels);
|
setProjects(data.projects);
|
||||||
setError(null);
|
setError(null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching status labels:', err);
|
console.error('Error fetching status labels:', err);
|
||||||
@ -110,38 +110,31 @@ export function Flow() {
|
|||||||
)}
|
)}
|
||||||
{!loading && !error && (
|
{!loading && !error && (
|
||||||
<div className="space-y-4 max-h-[300px] overflow-y-auto">
|
<div className="space-y-4 max-h-[300px] overflow-y-auto">
|
||||||
{statusLabels.length === 0 ? (
|
{projects.length === 0 ? (
|
||||||
<p className="text-center text-muted-foreground">No status labels found</p>
|
<p className="text-center text-muted-foreground">No status labels found</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
projects.map((project) => (
|
||||||
{statusLabels.map((label) => (
|
<div key={project.projectId} className="space-y-2">
|
||||||
<div
|
<h3 className="text-sm font-medium text-gray-500">Project {project.projectId}</h3>
|
||||||
key={label.id}
|
<div className="space-y-1">
|
||||||
className="flex items-start space-x-2 hover:bg-gray-50 p-2 rounded-lg transition-colors"
|
{project.labels.map((label) => (
|
||||||
>
|
<div
|
||||||
<div className="flex-1 min-w-0">
|
key={`${project.projectId}-${label.id}`}
|
||||||
<div className="flex items-baseline justify-between">
|
className="flex items-start space-x-2 hover:bg-gray-50 p-2 rounded-lg transition-colors"
|
||||||
<p className="text-sm font-medium truncate">{label.name}</p>
|
>
|
||||||
<span className={`text-xs px-2 py-1 rounded ${label.class}`}>
|
<div className="flex-1 min-w-0">
|
||||||
{label.statusType}
|
<div className="flex items-baseline justify-between">
|
||||||
</span>
|
<p className="text-sm font-medium truncate">{label.name}</p>
|
||||||
</div>
|
<span className={`text-xs px-2 py-1 rounded ${label.class}`}>
|
||||||
{label.projects.length > 0 && (
|
{label.statusType}
|
||||||
<div className="mt-1 flex flex-wrap gap-1">
|
|
||||||
{label.projects.map((project) => (
|
|
||||||
<span
|
|
||||||
key={project.id}
|
|
||||||
className="text-xs bg-gray-100 text-gray-600 px-1.5 py-0.5 rounded"
|
|
||||||
>
|
|
||||||
{project.name}
|
|
||||||
</span>
|
</span>
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</div>
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
</div>
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user