fix: labels import colors
This commit is contained in:
parent
017ab4951a
commit
533f5079e1
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue