CONTENT-WP-0002-T03 renders manifest columns through a pure row mapper and replaceable cell renderers. Assistant: grok Assistant-Session: 01a1346c-fdff-7741-b1af-b7283661554b
84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
/*
|
|
* Field set adapted from OnCo BrowserRow (id, name, tldr, route, facets, cols, sortKeys).
|
|
* https://github.com/judegomila/OnCo @ b594d7433bf4e408b44215e25e5304696d6f840e
|
|
* Copyright (c) 2026 OnCo. MIT License. See ui/NOTICE.
|
|
*
|
|
* Domain visuals (molecule, target, schematic, cancer icon, section icon) are not part of this type.
|
|
* The mapper is a pure function from a canonical record plus the manifest facet list.
|
|
*/
|
|
|
|
export type TextCell = { kind: "text"; text: string };
|
|
export type LinkCell = { kind: "link"; label: string; href: string };
|
|
export type ChipsCell = { kind: "chips"; values: string[] };
|
|
export type CellValue = TextCell | LinkCell | ChipsCell;
|
|
|
|
export type BrowserRow = {
|
|
id: string;
|
|
name: string;
|
|
tldr: string;
|
|
route: string;
|
|
facets: Record<string, string[]>;
|
|
cols: Record<string, CellValue>;
|
|
sortKeys: Record<string, string>;
|
|
};
|
|
|
|
export type ColumnDef = { key: string; label: string };
|
|
|
|
export type MapperEntity = {
|
|
id: string;
|
|
title: string;
|
|
tldr: string;
|
|
tags?: string[];
|
|
kindLabel: string;
|
|
route: string;
|
|
kindHref: string;
|
|
};
|
|
|
|
const LABELS: Record<string, string> = {
|
|
name: "Name",
|
|
tldr: "Summary",
|
|
tags: "Tags",
|
|
kind: "Kind",
|
|
};
|
|
|
|
export const HOME_COLUMNS = ["name", "kind", "tldr"];
|
|
|
|
export function columnDefs(keys: readonly string[]): ColumnDef[] {
|
|
return keys.map((key) => ({ key, label: LABELS[key] ?? key }));
|
|
}
|
|
|
|
export function mapBrowserRow(entity: MapperEntity, facetKeys: readonly string[]): BrowserRow {
|
|
const tags = [...(entity.tags ?? [])];
|
|
const cols: Record<string, CellValue> = {
|
|
name: { kind: "link", label: entity.title, href: entity.route },
|
|
tldr: { kind: "text", text: entity.tldr },
|
|
tags: { kind: "chips", values: tags },
|
|
kind: { kind: "link", label: entity.kindLabel, href: entity.kindHref },
|
|
};
|
|
const facets: Record<string, string[]> = {};
|
|
for (const key of facetKeys) facets[key] = key === "tags" ? [...tags] : [];
|
|
return {
|
|
id: entity.id,
|
|
name: entity.title,
|
|
tldr: entity.tldr,
|
|
route: entity.route,
|
|
facets,
|
|
cols,
|
|
sortKeys: {
|
|
name: entity.title,
|
|
tldr: entity.tldr,
|
|
tags: tags.join(", "),
|
|
kind: entity.kindLabel,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function cellSortValue(row: BrowserRow, key: string): string {
|
|
const keyed = row.sortKeys[key];
|
|
if (keyed !== undefined) return keyed;
|
|
const cell = row.cols[key];
|
|
if (!cell) return "";
|
|
if (cell.kind === "text") return cell.text;
|
|
if (cell.kind === "link") return cell.label;
|
|
return cell.values.join(", ");
|
|
}
|