All files / src/components/layout breadcrumb-trails.ts

100% Statements 19/19
100% Branches 2/2
100% Functions 14/14
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59                                                80x         12x 59x       21x         12x 20x 1x 28x 2x 1x 3x 2x 7x       13x 10x 21x          
import { itemDisplayName } from "@/lib/items";
 
export interface Crumb {
  label: string;
  href?: string;
}
 
export interface TrailCollection {
  id: string;
  slug?: string | null;
  name: string;
}
 
export interface TrailItem {
  name: string | null;
  // Nullable to match the domain model; only feeds itemDisplayName's "#n" label.
  number: number | null;
}
 
export interface TrailResult {
  number: number;
  name: string;
}
 
const base = (c: TrailCollection) => `/collections/${c.slug ?? c.id}`;
 
// Linked-crumb constructors: every non-leaf level goes through one of these,
// so the back-arrow invariant (non-last crumbs always have an href) holds by
// construction. Each trail below is a parent prefix + an unlinked leaf.
const collectionsCrumb: Crumb = { label: "Collections", href: "/collections" };
const collectionPrefix = (c: TrailCollection): Crumb[] => [
  collectionsCrumb,
  { label: c.name, href: base(c) },
];
const decidePrefix = (c: TrailCollection): Crumb[] => [
  ...collectionPrefix(c),
  { label: "Decide", href: `${base(c)}/results` },
];
 
export const trail = {
  collections: (): Crumb[] => [{ label: "Collections" }],
  collectionNew: (): Crumb[] => [collectionsCrumb, { label: "Create" }],
  collection: (c: TrailCollection): Crumb[] => [collectionsCrumb, { label: c.name }],
  collectionEdit: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "Edit" }],
  members: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "People" }],
  pool: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "Photos" }],
  itemNew: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "Add item" }],
  item: (c: TrailCollection, item: TrailItem): Crumb[] => [
    ...collectionPrefix(c),
    { label: itemDisplayName(item) },
  ],
  sort: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "Sort" }],
  results: (c: TrailCollection): Crumb[] => [...collectionPrefix(c), { label: "Decide" }],
  result: (c: TrailCollection, result: TrailResult): Crumb[] => [
    ...decidePrefix(c),
    { label: result.name },
  ],
};