"use client"; import { IconBug, IconClipboardList, IconGitPullRequest, IconLink } from "@tabler/icons-react"; import type { EntityReferenceSearchError } from "@/hooks/use-entity-reference-search"; import type { EntityReference, EntityReferenceGroupStatus, EntityReferenceSearchGroup, } from "@/lib/types/entity-reference"; import { selectableEntityReferences, visibleEntityReferenceGroups, } from "./entity-reference-groups"; import { PopupMenu, PopupMenuItem, useMenuItemRefs } from "./popup-menu"; export { selectableEntityReferences, visibleEntityReferenceGroups, } from "./entity-reference-groups"; type EntityReferenceMenuProps = { isOpen: boolean; clientRect?: (() => DOMRect | null) | null; groups: EntityReferenceSearchGroup[]; query: string; selectedIndex: number; isSearching: boolean; error: EntityReferenceSearchError | null; onRetry: () => void; onSelect: (reference: EntityReference) => void; onClose: () => void; setSelectedIndex: (index: number) => void; }; const GROUP_STATUS_LABELS: Partial> = { unauthorized: "Sign-in required", rate_limited: "Temporarily rate limited", timeout: "Search timed out", upstream_error: "Provider unavailable", unsupported_scope: "Unavailable for this workspace", }; function entityReferenceIcon(kind: string) { if (kind === "task") return ; if (kind === "issue" || kind === "work_item") return ; if (kind === "pull_request" || kind === "merge_request") { return ; } return ; } function entityReferenceEmptyState( query: string, isSearching: boolean, error: EntityReferenceSearchError | null, onRetry: () => void, ) { if (!query.trim()) return "Type to search work items"; if (isSearching) return "Searching work items…"; if (error) { return (
{error.message}
); } return "No work items found"; } export function EntityReferenceMenu({ isOpen, clientRect, groups, query, selectedIndex, isSearching, error, onRetry, onSelect, onClose, setSelectedIndex, }: EntityReferenceMenuProps) { const { setItemRef } = useMenuItemRefs(selectedIndex); const selectable = selectableEntityReferences(groups); let itemIndex = 0; const visibleGroups = visibleEntityReferenceGroups(groups); const hasContent = visibleGroups.length > 0; return ( {entityReferenceEmptyState(query, isSearching, error, onRetry)} } > {visibleGroups.map((group) => (
{group.display_name} {group.kind_label}
{group.status === "ok" ? ( group.results.map((reference) => { const index = itemIndex++; return ( onSelect(reference)} onMouseEnter={() => setSelectedIndex(index)} itemRef={setItemRef(index)} /> ); }) ) : (
{GROUP_STATUS_LABELS[group.status] ?? "Provider unavailable"}
)}
))} {isSearching && selectable.length > 0 && (
Updating…
)}
); }