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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 1x 1x 1x 1x 1x 31x 31x 1x 1x 42x 1x 1x 42x 1x 1x 42x 31x 31x 42x 1x 1x 42x 42x 1x 1x 2x 14x 14x 14x 14x 2x 2x 1x 1x 1x | import type { UserStory } from "./types.js" import { sortStoriesById } from "./sort-by-id.js" /** Board columns โ derived from SQLite `ready` + `status`, not stored separately. */ export type KanbanColumnId = | "backlog" | "todo" | "๐ถ" | "๐งช" | "โ " | "๐ง" | "๐ซ" export type KanbanColumnGroup = { columnId: KanbanColumnId stories: UserStory[] } export const KANBAN_COLUMN_ORDER: KanbanColumnId[] = [ "backlog", "todo", "๐ถ", "๐งช", "โ ", "๐ง", "๐ซ", ] /** Display titles for board column headers (UI only โ not US `status`). */ const COLUMN_HEADER_LABELS: Record<KanbanColumnId, string> = { backlog: "๐ Backlog", todo: "๐ Todo", "๐ถ": "๐ถ Partial", "๐งช": "๐งช Tests", "โ ": "โ Done", "๐ง": "๐ง Frozen", "๐ซ": "๐ซ Deprecated", } export function columnHeaderLabel(columnId: KanbanColumnId): string { return COLUMN_HEADER_LABELS[columnId] } /** @deprecated use columnHeaderLabel */ export function columnLabel(columnId: KanbanColumnId): string { return columnHeaderLabel(columnId) } export function isReadyForTodo(story: UserStory): boolean { return story.ready === true } export function resolveKanbanColumn(story: UserStory): KanbanColumnId { if (story.status === "๐ง") { return "๐ง" } if (story.status === "๐ซ") { return "๐ซ" } if (story.status === "โ") { return isReadyForTodo(story) ? "todo" : "backlog" } if (story.tests === "required" && story.testsStatus === "pending") { return "๐งช" } return story.status } export function groupStoriesForKanban(stories: UserStory[]): KanbanColumnGroup[] { return KANBAN_COLUMN_ORDER.map((columnId) => ({ columnId, stories: sortStoriesById( stories.filter((story) => resolveKanbanColumn(story) === columnId), ), })) } /** Columns visible by default (hide empty Frozen / Deprecated). */ export function visibleBoardColumns(groups: KanbanColumnGroup[]): KanbanColumnGroup[] { return groups.filter(({ columnId, stories }) => { if (columnId === "๐ง" || columnId === "๐ซ") { return stories.length > 0 } return true }) } |