"use client"; import { useTranslations } from "next-intl"; import Link from "next/link"; import type { ApiDataInterface } from "../../../../../core"; import { ModuleRegistry } from "../../../../../core/registry/ModuleRegistry"; import { usePageUrlGenerator } from "../../../../../hooks"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../../../../../shadcnui/ui/table"; import type { ChunkInterface, ChunkRelationshipMeta } from "../../../../chunk/data/ChunkInterface"; import { useEntityLabel } from "./useEntityLabel"; interface Props { citations: (ChunkInterface & ChunkRelationshipMeta)[]; /** Resolved source entities keyed by `chunk.nodeId`. */ sources?: Map; } interface ContentRow { source: ApiDataInterface; citationCount: number; maxRelevance: number; } export function ContentsTab({ citations, sources }: Props) { const t = useTranslations(); const entityLabel = useEntityLabel(); const generate = usePageUrlGenerator(); // Group citations by nodeId, then materialise rows from the resolved sources // map. Chunks without a resolved source entity are skipped. const map = new Map(); for (const c of citations) { const id = c.nodeId; if (!id) continue; const source = sources?.get(id); if (!source) continue; const existing = map.get(id); if (existing) { existing.citationCount++; existing.maxRelevance = Math.max(existing.maxRelevance, c.relevance ?? 0); } else { map.set(id, { source, citationCount: 1, maxRelevance: c.relevance ?? 0 }); } } const rows = Array.from(map.values()).sort( (a, b) => b.maxRelevance - a.maxRelevance || ((a.source as any).name ?? "").localeCompare((b.source as any).name ?? ""), ); if (rows.length === 0) return null; return ( {t("features.assistant.message.sources.source")} {t("features.assistant.message.sources.type")} {rows.map(({ source, citationCount }) => { let module; try { module = ModuleRegistry.findByName(source.type); } catch { return null; } // Help HowTos are public articles, not admin records: route to // /help// instead of the module's /administration/howtos page. const howToType = (source as any).howToType as string | undefined; const slug = (source as any).slug as string | undefined; const href = howToType && slug ? `/help/${howToType}/${slug}` : generate({ page: module, id: source.id }); const name = (source as any).name ?? source.identifier; return ( {name}{" "} {t("features.assistant.message.sources.citations_count", { count: citationCount, })} {entityLabel(module.name)} ); })}
); }