fix: labels import colors

This commit is contained in:
null 2026-05-19 21:40:25 -05:00
parent 017ab4951a
commit 533f5079e1
2 changed files with 56 additions and 21 deletions

View File

@ -13,7 +13,44 @@ import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { DataTable } from "@/components/tables/DataTable";
import { CloseForgejoIssueDialog } from "@/components/git/CloseForgejoIssueDialog";
import type { ForgejoIssue } from "@/lib/api-forgejo";
import type { ForgejoIssue, ForgejoIssueLabel } from "@/lib/api-forgejo";
/** Normalize a Forgejo label color to a valid 6-char hex string or null. */
function normalizeLabelColor(raw: string | null | undefined): string | null {
if (!raw) return null;
const hex = raw.replace(/^#+/, "");
return /^[0-9a-fA-F]{3,6}$/.test(hex) ? `#${hex.padEnd(6, "0")}` : null;
}
/** Return white or dark text based on WCAG relative luminance of a hex background. */
function labelTextColor(hex: string): string {
const h = hex.replace("#", "");
const r = parseInt(h.slice(0, 2), 16) / 255;
const g = parseInt(h.slice(2, 4), 16) / 255;
const b = parseInt(h.slice(4, 6), 16) / 255;
const lin = (c: number) =>
c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
const L = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
return L > 0.179 ? "#1a1a1a" : "#ffffff";
}
function LabelChip({ label }: { label: ForgejoIssueLabel }) {
const bg = normalizeLabelColor(label.color);
return (
<Badge
variant="outline"
className="shrink-0 text-xs"
style={
bg
? { backgroundColor: bg, color: labelTextColor(bg), borderColor: bg }
: undefined
}
title={label.description ?? label.name}
>
{label.name}
</Badge>
);
}
export type ForgejoIssuesTableProps = {
issues: ForgejoIssue[];
@ -108,26 +145,17 @@ export function ForgejoIssuesTable({
cell: ({ row }) => {
const labels = row.original.labels;
if (!labels || labels.length === 0) return null;
const visible = labels.slice(0, 3);
const overflow = labels.length - visible.length;
return (
<div className="flex max-w-[220px] flex-wrap gap-1">
{labels
.slice(0, 3)
.map((label: Record<string, unknown>, i: number) => (
<Badge
key={i}
variant="outline"
className="text-xs"
style={
label.color
? { backgroundColor: `#${label.color}`, color: "#fff" }
: undefined
}
>
{String(label.name || "")}
</Badge>
))}
{labels.length > 3 && (
<span className="text-xs text-muted">+{labels.length - 3}</span>
<div className="flex max-w-[240px] flex-wrap gap-1">
{visible.map((label, i) => (
<LabelChip key={i} label={label} />
))}
{overflow > 0 && (
<span className="self-center text-xs text-muted">
+{overflow}
</span>
)}
</div>
);

View File

@ -251,6 +251,13 @@ export async function validateRepository(
}
// Forgejo Issue types
export interface ForgejoIssueLabel {
id?: number | null;
name: string;
color: string;
description?: string | null;
}
export interface ForgejoIssue {
id: string;
organization_id: string;
@ -260,7 +267,7 @@ export interface ForgejoIssue {
body_preview: string | null;
state: string;
is_pull_request: boolean;
labels: Record<string, unknown>[];
labels: ForgejoIssueLabel[];
assignees: Record<string, unknown>[];
author: string;
html_url: string;