Board & Views

Last updated on 2026-03-26

The board and views module provides five different ways to visualize and manage project tasks. Each view shares the same underlying task data but presents it optimized for different workflows. All views include a ViewSwitcher component for quick navigation between them, along with a shared FilterBar for filtering by status, priority, assignee, and labels. All screens are nested under projects/[id]/ in the (dashboard) route group.

Kanban Board

Route: /projects/[id]/board

The Kanban board is the hero feature of the Kanban PM Kit. It provides a visual, drag-and-drop interface for managing tasks across status columns.

  • Drag-and-drop -- powered by @hello-pangea/dnd, task cards can be dragged between columns to update their status
  • Status columns -- Backlog, Todo, In Progress, In Review, Done, and Cancelled, each with a distinct color indicator
  • Task cards -- each card shows task ID badge (e.g. KAN-42), title, assignee avatar, priority icon, due date, and label badges
  • Column headers -- each column header displays the status name, task count, and a "+" button for quick task creation via QuickAddCard
  • Quick add -- inline card creation at the bottom of any column; type a title and press Enter to create a task with that column's status
  • Filter bar -- multi-select filters for priority, assignee, and labels; filters persist across view switches
  • Group by -- toggle between grouping by Status (default), Priority, Assignee, or Label
  • Card actions -- click a card to navigate to the task detail page; hover to reveal a quick actions menu (Edit, Change Priority, Assign, Delete)
import { KanbanBoard } from "@/components/kanban/kanban-board"
import { KanbanColumn } from "@/components/kanban/kanban-column"
import { KanbanCard } from "@/components/kanban/kanban-card"
import { ColumnHeader } from "@/components/kanban/column-header"
import { QuickAddCard } from "@/components/kanban/quick-add-card"
import { FilterBar } from "@/components/project/filter-bar"
import { ViewSwitcher } from "@/components/project/view-switcher"

Kanban Board Layout

+----------+----------+----------+----------+----------+----------+
| Backlog  | Todo     | In Prog  | In Rev   | Done     | Cancel   |
| 8        | 5        | 4        | 2        | 12       | 1        |
+----------+----------+----------+----------+----------+----------+
| +------+ | +------+ | +------+ | +------+ | +------+ | +------+ |
| |KAN-01| | |KAN-05| | |KAN-12| | |KAN-18| | |KAN-03| | |KAN-22| |
| |Task  | | |Task  | | |Task  | | |Task  | | |Task  | | |Task  | |
| |title | | |title | | |title | | |title | | |title | | |title | |
| +------+ | +------+ | +------+ | +------+ | +------+ | +------+ |
| +------+ | +------+ | +------+ | +------+ | +------+ |          |
| |KAN-02| | |KAN-06| | |KAN-13| | |KAN-19| | |KAN-04| |          |
| +------+ | +------+ | +------+ | +------+ | +------+ |          |
| [+ Add]  | [+ Add]  | [+ Add]  | [+ Add]  | [+ Add]  | [+ Add]  |
+----------+----------+----------+----------+----------+----------+

Kanban Board Architecture

The Kanban board uses a three-tier component hierarchy built on @hello-pangea/dnd:

KanbanBoard (DragDropContext)
+-- KanbanColumn (Droppable) x 6 statuses
|   +-- ColumnHeader (status name, count, add button)
|   +-- KanbanCard (Draggable) x N tasks
|   |   +-- TaskIdBadge (e.g. KAN-42)
|   |   +-- Task title
|   |   +-- MemberAvatar (assignee)
|   |   +-- TaskPriority (icon)
|   |   +-- DateBadge (due date)
|   |   +-- TaskLabels (label badges)
|   +-- QuickAddCard (inline create)
+-- onDragEnd handler (updates task status in state)

How it works:

  1. KanbanBoard wraps the entire board in a DragDropContext and manages the onDragEnd callback. When a card is dropped, it reads the source and destination from the result, removes the task from the source column, inserts it into the destination column at the correct index, and updates the task's status field.

  2. Each KanbanColumn is a Droppable container identified by its statusId. It receives the filtered list of tasks for that status and renders them as an ordered list. The ColumnHeader displays the status name, task count, and add button.

  3. Each KanbanCard is a Draggable identified by the taskId. It renders a card with task summary information. The provided.draggableProps and provided.dragHandleProps are spread onto the card element, and provided.innerRef is used as the ref callback.

// kanban-board.tsx (simplified)
import { DragDropContext, type DropResult } from "@hello-pangea/dnd"

function KanbanBoard({ tasks, statuses }: KanbanBoardProps) {
  const [columns, setColumns] = useState(groupTasksByStatus(tasks, statuses))

  function onDragEnd(result: DropResult) {
    const { source, destination } = result
    if (!destination) return
    if (source.droppableId === destination.droppableId && source.index === destination.index) return

    // Move task between columns
    const sourceColumn = [...columns[source.droppableId]]
    const [movedTask] = sourceColumn.splice(source.index, 1)
    movedTask.status = destination.droppableId as TaskStatusType

    const destColumn = source.droppableId === destination.droppableId
      ? sourceColumn
      : [...columns[destination.droppableId]]
    destColumn.splice(destination.index, 0, movedTask)

    setColumns({
      ...columns,
      [source.droppableId]: sourceColumn,
      [destination.droppableId]: destColumn,
    })
  }

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      {statuses.map((status) => (
        <KanbanColumn key={status.id} status={status} tasks={columns[status.id]} />
      ))}
    </DragDropContext>
  )
}

Data Sources

Data Source Location
Tasks tasks (filtered by projectId) data/seed.ts
Task statuses taskStatuses data/seed.ts
Team members teamMembers data/seed.ts
Labels taskLabels data/seed.ts

List View

Route: /projects/[id]/list

A structured table view of all project tasks with grouping, sorting, and inline editing.

  • Task rows -- tabular rows using TaskRow component showing task ID badge, title, status badge, priority icon, assignee avatar, due date, labels, and estimate
  • Group headers -- collapsible GroupHeader sections that organize tasks by status (default), priority, assignee, or label
  • Inline status toggle -- click the status badge on any row to cycle through statuses
  • Inline priority select -- click the priority icon to open a dropdown and change priority
  • Sorting -- click column headers to sort by title, status, priority, assignee, due date, or created date
  • Bulk actions -- checkbox selection for multi-task operations: change status, change priority, assign, add labels, or delete
  • Filter bar -- shared FilterBar component with status, priority, assignee, and label multi-select filters
import { TaskRow } from "@/components/task/task-row"
import { GroupHeader } from "@/components/project/group-header"
import { FilterBar } from "@/components/project/filter-bar"
import { ViewSwitcher } from "@/components/project/view-switcher"

List View Layout

+------+-------------------+----------+--------+----------+--------+-------+
| [x]  | Task              | Status   | Prior. | Assignee | Due    | Est.  |
+------+-------------------+----------+--------+----------+--------+-------+
| --- In Progress (4) ---------------------------------------------------- |
| [ ]  | KAN-12 Setup auth | In Prog  | High   | [Sarah]  | Mar 20 | 5     |
| [ ]  | KAN-13 API routes | In Prog  | Medium | [Mike]   | Mar 22 | 3     |
+------+-------------------+----------+--------+----------+--------+-------+
| --- Todo (5) ----------------------------------------------------------- |
| [ ]  | KAN-05 Dashboard  | Todo     | High   | [Lisa]   | Mar 25 | 8     |
| [ ]  | KAN-06 Sidebar    | Todo     | Low    | [--]     | --     | 2     |
+------+-------------------+----------+--------+----------+--------+-------+

Data Sources

Data Source Location
Tasks tasks (filtered by projectId) data/seed.ts
Team members teamMembers data/seed.ts
Labels taskLabels data/seed.ts

Backlog

Route: /projects/[id]/backlog

A prioritized backlog view showing tasks not yet assigned to a cycle, designed for sprint planning.

  • Backlog tasks -- list of TaskRow components for tasks with no cycleId, showing task ID badge, title, priority, estimate, labels, and assignee
  • Priority ordering -- tasks are sorted by priority (Urgent first, then High, Medium, Low, None) and within priority by creation date
  • Drag to cycle -- if cycles are enabled, the page shows the active cycle panel on the right; drag tasks from the backlog to add them to the current sprint
  • Estimate totals -- header shows the total estimate points in the backlog and the remaining capacity in the active cycle
  • Bulk assign to cycle -- checkbox selection and "Add to Cycle" action to move multiple tasks at once
  • Filter bar -- filter by priority, assignee, and labels
  • Empty state -- contextual message when the backlog is empty, suggesting task creation
import { TaskRow } from "@/components/task/task-row"
import { FilterBar } from "@/components/project/filter-bar"
import { CycleCard } from "@/components/pm/cycle-card"

Backlog Layout

+----------------------------------+---------------------+
| Backlog (24 tasks, 96 pts)       | Active Cycle        |
+----------------------------------+ Sprint 5            |
| [x] KAN-42 Implement search [H] | Mar 10-24           |
| [ ] KAN-43 Add filters      [M] | 12 tasks, 48 pts    |
| [ ] KAN-44 Export feature    [L] | ████████░░ 72%      |
| [ ] KAN-45 User settings    [L] | Remaining: 13 pts   |
| ...                              |                     |
| [Add to Cycle]                   |                     |
+----------------------------------+---------------------+

Data Sources

Data Source Location
Tasks tasks (filtered by projectId, cycleId = null) data/seed.ts
Active cycle cycles (filtered by projectId, status = Active) data/seed.ts

Calendar View

Route: /projects/[id]/calendar

A month-view calendar displaying tasks plotted by their due date.

  • Month grid -- standard calendar grid showing the current month with day cells; tasks appear as colored chips within their due date cell
  • Task chips -- compact chips showing task title truncated to fit, color-coded by priority (Urgent = red, High = orange, Medium = blue, Low = gray)
  • Click to detail -- clicking a task chip navigates to the task detail page
  • Day click -- clicking an empty day cell opens the quick task creation form pre-filled with that due date
  • Month navigation -- previous/next month arrows and a "Today" button to jump to the current month
  • Filter bar -- filter displayed tasks by status, priority, assignee, and labels
  • Overflow indicator -- when more than 3 tasks fall on a single day, a "+N more" link expands to show all tasks in a popover
import { Calendar } from "@/components/ui/calendar"
import { FilterBar } from "@/components/project/filter-bar"
import { ViewSwitcher } from "@/components/project/view-switcher"

Calendar Layout

+-----+-----+-----+-----+-----+-----+-----+
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |  1  |  2  |  3  |
|     |     |     |     |[T1] |     |     |
+-----+-----+-----+-----+-----+-----+-----+
|  4  |  5  |  6  |  7  |  8  |  9  | 10  |
|     |[T2] |     |[T3] |[T4] |     |     |
|     |[T5] |     |     |[T6] |     |     |
|     |     |     |     |+2   |     |     |
+-----+-----+-----+-----+-----+-----+-----+

Data Sources

Data Source Location
Tasks tasks (filtered by projectId, dueDate != null) data/seed.ts

Timeline / Gantt

Route: /projects/[id]/timeline

A Gantt chart timeline view showing tasks as horizontal bars plotted against a date axis, with milestone markers and dependency visualization.

  • Gantt chart -- horizontal timeline built with the GanttChart component, showing tasks as colored bars spanning from startDate to dueDate
  • Gantt bars -- each GanttBar represents a task, color-coded by status; bar width represents duration; hover shows task details tooltip
  • Today marker -- red vertical line via TodayMarker indicating the current date on the timeline
  • Milestone markers -- diamond-shaped MilestoneMarker components positioned on the date axis for project milestones
  • Task list sidebar -- left-side panel listing tasks with title, assignee, and status for reference alongside the chart
  • Zoom controls -- toggle between Day, Week, and Month zoom levels to adjust the timeline granularity
  • Scroll sync -- the task list sidebar and Gantt chart scroll vertically in sync
  • Filter bar -- shared filter controls for status, priority, assignee, and labels
import { GanttChart } from "@/components/timeline/gantt-chart"
import { GanttBar } from "@/components/timeline/gantt-bar"
import { MilestoneMarker } from "@/components/timeline/milestone-marker"
import { TodayMarker } from "@/components/timeline/today-marker"
import { FilterBar } from "@/components/project/filter-bar"
import { ViewSwitcher } from "@/components/project/view-switcher"

Timeline Layout

+------------------+------------------------------------------+
| Task List        | Mar 2026                                 |
|                  | 10  11  12  13  14  15  16  17  18  19   |
+------------------+-----|-----|-----|-----|-----|-----|-------+
| KAN-01 Auth      |     ███████████████                      |
| KAN-02 API       |              ████████████████            |
| KAN-03 Dashboard |                        ████████████      |
| KAN-04 Settings  |                             ████████     |
| -- Milestone --  |                    [*] v1.0 Beta         |
|                  |                              | (today)   |
+------------------+------------------------------------------+

Gantt Chart Architecture

The timeline is built from four composable components:

GanttChart (container)
+-- Date axis header (days/weeks/months based on zoom)
+-- TodayMarker (red vertical line at current date)
+-- GanttBar x N tasks
|   +-- Colored bar (width = duration, left offset = start date)
|   +-- Tooltip on hover (task title, dates, assignee, status)
+-- MilestoneMarker x N milestones
    +-- Diamond icon positioned on milestone date
    +-- Label text

Data Sources

Data Source Location
Tasks tasks (filtered by projectId, startDate != null) data/seed.ts
Milestones milestones (filtered by projectId) data/seed.ts

View Switcher

The ViewSwitcher component appears at the top of all five view pages, providing one-click navigation:

import { ViewSwitcher } from "@/components/project/view-switcher"

<ViewSwitcher
  projectId={projectId}
  currentView="board"
  views={["board", "list", "backlog", "calendar", "timeline"]}
/>

Each view button shows an icon and label. The active view is highlighted with the primary color. The switcher includes proper aria-current="page" on the active button for screen reader support.

Next Steps