Ctrl K
ComunidadGuías…

lib/board-columns.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { StatusMeta } from "@/lib/issue-constants";
import type { Issue } from "@/lib/types";

export interface BoardColumn {
  status: StatusMeta;
  items: Issue[];
}

/** A comparator built per column — the smart sort needs the column's own
 * issue set (the triage rules group objectives over it), the other sorts
 * ignore it. */
export type ColumnComparatorFactory = (
  columnIssues: Issue[]
) => (a: Issue, b: Issue) => number;

/** Group issues in one pass, then sort only the populated board columns. */
export function buildBoardColumns(
  statuses: StatusMeta[],
  issues: Issue[],
  makeComparator: ColumnComparatorFactory
): BoardColumn[] {
  const itemsByStatus = new Map(statuses.map((status) => [status.value, [] as Issue[]]));
  for (const issue of issues) itemsByStatus.get(issue.status)?.push(issue);
  return statuses.map((status) => {
    const items = itemsByStatus.get(status.value) ?? [];
    if (items.length > 1) items.sort(makeComparator(items));
    return { status, items };
  });
}

function sameItems(a: Issue[], b: Issue[]) {
  return a.length === b.length && a.every((issue, index) => issue === b[index]);
}

/**
 * Keep unchanged column objects and item arrays referentially stable so a
 * memoized column does not rerender when an issue in another status changes.
 */
export function createBoardColumnsBuilder() {
  let previous = new Map<string, BoardColumn>();
  return (
    statuses: StatusMeta[],
    issues: Issue[],
    makeComparator: ColumnComparatorFactory
  ) => {
    const next = buildBoardColumns(statuses, issues, makeComparator).map((column) => {
      const before = previous.get(column.status.value);
      return before &&
        before.status === column.status &&
        sameItems(before.items, column.items)
        ? before
        : column;
    });
    previous = new Map(next.map((column) => [column.status.value, column]));
    return next;
  };
}