"use client"; import Link from "@/components/routing/app-link"; import { IconCircle, IconCircleCheck, IconPlus, IconChevronDown } from "@tabler/icons-react"; import { Badge } from "@kandev/ui/badge"; import { Button } from "@kandev/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@kandev/ui/dropdown-menu"; import { Spinner } from "@kandev/ui/spinner"; import { cn } from "@/lib/utils"; import { formatRelativeTime } from "@/lib/utils"; import type { GitHubIssue, TaskIssueLink } from "@/lib/types/github"; import type { LaunchPayload, TaskPreset } from "./quick-task-launcher"; import { TaskRowIndicator } from "./task-row-indicator"; import { useTranslation } from "react-i18next"; type IssueListProps = { items: GitHubIssue[]; loading: boolean; error: string | null; presets: TaskPreset[]; onStartTask: (payload: LaunchPayload) => void; issueKeyToTasks?: Map; }; function StartTaskMenu({ issue, presets, onStartTask, }: { issue: GitHubIssue; presets: TaskPreset[]; onStartTask: IssueListProps["onStartTask"]; }) { const { t } = useTranslation(); const launch = (preset: TaskPreset) => onStartTask({ kind: "issue", issue, preset }); return ( {presets.map((p) => { const ItemIcon = p.icon; return ( launch(p)} >
{p.label} {p.hint}
); })}
); } function IssueLabels({ labels }: { labels: string[] }) { if (!labels?.length) return null; return ( <> {labels.slice(0, 4).map((l) => ( {l} ))} {labels.length > 4 && ( +{labels.length - 4} )} ); } function IssueRow({ issue, presets, onStartTask, tasks, }: { issue: GitHubIssue; presets: TaskPreset[]; onStartTask: IssueListProps["onStartTask"]; tasks: TaskIssueLink[] | undefined; }) { const { t } = useTranslation(); const StateIcon = issue.state === "open" ? IconCircle : IconCircleCheck; const stateClass = issue.state === "open" ? "text-emerald-600 dark:text-emerald-400" : "text-purple-600 dark:text-purple-400"; return (
{issue.title}
{issue.repo_owner}/{issue.repo_name}#{issue.number} ยท {t("github:byAuthorOpenedAgo", { author: issue.author_login, time: formatRelativeTime(issue.created_at), })} ({ id: task.task_id, taskId: task.task_id, fallbackTitle: task.task_title, }))} testIdPrefix="issue-row-task-indicator" />
); } function IssueListBody({ loading, error, items, presets, onStartTask, issueKeyToTasks, }: IssueListProps) { const { t } = useTranslation(); if (loading) { return (
); } if (error) { return
{error}
; } if (items.length === 0) { return (
{t("github:noIssuesMatchThisFilter")}
); } return (
{items.map((issue) => { const key = `${issue.repo_owner}/${issue.repo_name}#${issue.number}`; return ( ); })}
); } export function IssueList(props: IssueListProps) { return (
); }