import { useEffect } from "react"; import { useParams, Link } from "react-router-dom"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { issuesApi } from "../api/issues"; import { useCompany } from "../context/CompanyContext"; import { usePanel } from "../context/PanelContext"; import { useBreadcrumbs } from "../context/BreadcrumbContext"; import { queryKeys } from "../lib/queryKeys"; import { InlineEditor } from "../components/InlineEditor"; import { CommentThread } from "../components/CommentThread"; import { IssueProperties } from "../components/IssueProperties"; import { StatusIcon } from "../components/StatusIcon"; import { PriorityIcon } from "../components/PriorityIcon"; import { Separator } from "@/components/ui/separator"; import { ChevronRight } from "lucide-react"; export function IssueDetail() { const { issueId } = useParams<{ issueId: string }>(); const { selectedCompanyId } = useCompany(); const { openPanel, closePanel } = usePanel(); const { setBreadcrumbs } = useBreadcrumbs(); const queryClient = useQueryClient(); const { data: issue, isLoading, error } = useQuery({ queryKey: queryKeys.issues.detail(issueId!), queryFn: () => issuesApi.get(issueId!), enabled: !!issueId, }); const { data: comments } = useQuery({ queryKey: queryKeys.issues.comments(issueId!), queryFn: () => issuesApi.listComments(issueId!), enabled: !!issueId, }); const updateIssue = useMutation({ mutationFn: (data: Record) => issuesApi.update(issueId!, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: queryKeys.issues.detail(issueId!) }); if (selectedCompanyId) { queryClient.invalidateQueries({ queryKey: queryKeys.issues.list(selectedCompanyId) }); } }, }); const addComment = useMutation({ mutationFn: (body: string) => issuesApi.addComment(issueId!, body), onSuccess: () => { queryClient.invalidateQueries({ queryKey: queryKeys.issues.comments(issueId!) }); }, }); useEffect(() => { setBreadcrumbs([ { label: "Issues", href: "/issues" }, { label: issue?.title ?? issueId ?? "Issue" }, ]); }, [setBreadcrumbs, issue, issueId]); useEffect(() => { if (issue) { openPanel( updateIssue.mutate(data)} /> ); } return () => closePanel(); }, [issue]); // eslint-disable-line react-hooks/exhaustive-deps if (isLoading) return

Loading...

; if (error) return

{error.message}

; if (!issue) return null; // Ancestors are returned oldest-first from the server (root at end, immediate parent at start) const ancestors = issue.ancestors ?? []; return (
{/* Parent chain breadcrumb */} {ancestors.length > 0 && ( )}
updateIssue.mutate({ status })} /> updateIssue.mutate({ priority })} /> {issue.id.slice(0, 8)}
updateIssue.mutate({ title })} as="h2" className="text-xl font-bold" /> updateIssue.mutate({ description })} as="p" className="text-sm text-muted-foreground" placeholder="Add a description..." multiline />
{ await addComment.mutateAsync(body); }} />
); }