# Feature: Task Management UI ## Problem Statement Users of the Foundary Studio currently have no visual interface for managing tasks. The backend (studio-api) is being built with full Task CRUD endpoints (via the `data-models` feature), but there is no frontend to interact with them. Project teams need a way to visualize task status at a glance, move tasks through workflow stages, create and edit tasks with metadata (labels, assignees), and filter their view to focus on relevant work items. Without a UI, users would need to interact with raw API endpoints — impractical for day-to-day project management workflows. ## User Stories - As a **team member**, I want to see all tasks organized by status in a Kanban board so that I can understand the state of work at a glance. - As a **team member**, I want to drag tasks between columns (To Do, In Progress, Done) so that I can quickly update task status without opening a form. - As a **team member**, I want to create a new task with title, description, labels, and assignee so that I can capture work items as they arise. - As a **team member**, I want to edit an existing task's details so that I can keep task information up to date. - As a **team member**, I want to filter the board by label so that I can focus on a specific category of work (e.g., bugs only). - As a **team member**, I want to filter the board by assignee so that I can see work assigned to a specific person. - As a **team member**, I want to delete a task from the edit modal so that I can remove work items that are no longer needed. ## Acceptance Criteria ### Kanban Board View - [ ] Board displays three columns: **To Do** (status=`open`), **In Progress** (status=`in_progress`), **Done** (status=`done`) - [ ] Each column shows a count of tasks it contains - [ ] Tasks are rendered as cards within their respective status column - [ ] Task cards display: title, priority badge, label badges, and assignee avatar/name - [ ] Board fetches tasks from `GET /api/studio-api/projects/{projectId}/tasks` on mount - [ ] Empty columns display a placeholder message (e.g., "No tasks") ### Drag and Drop - [ ] Tasks can be dragged from one column and dropped into another - [ ] Dropping a task into a new column fires `PUT /api/studio-api/tasks/{id}` with the new status - [ ] The board updates optimistically (moves the card immediately, reverts on API error) - [ ] Visual feedback during drag: dragged card has elevated shadow, drop target column is highlighted - [ ] Cancelled tasks (status=`cancelled`) are excluded from the board view ### Task Creation - [ ] A "New Task" button is visible above/beside the board - [ ] Clicking "New Task" opens a modal/dialog with fields: title (required), description (optional), label (multi-select from existing labels), assignee (select from known users/IDs) - [ ] Submitting the form calls `POST /api/studio-api/projects/{projectId}/tasks` to create the task - [ ] After successful creation, the new task appears in the "To Do" column without a full page refresh - [ ] Validation: title is required (1-200 chars); shows inline error if empty ### Task Editing - [ ] Clicking a task card opens an edit modal/dialog pre-populated with the task's current data - [ ] Edit modal includes fields: title, description, status (dropdown), priority (dropdown), labels (multi-select), assignee - [ ] Saving calls `PUT /api/studio-api/tasks/{id}` with updated fields - [ ] After successful update, the board reflects changes (card moves columns if status changed) - [ ] A "Delete" action in the edit modal calls `DELETE /api/studio-api/tasks/{id}` after confirmation - [ ] Deleting a task removes it from the board without a full page refresh ### Filtering - [ ] A filter bar is visible above the board - [ ] Filter by label: dropdown/multi-select populated from `GET /api/studio-api/labels` - [ ] Filter by assignee: dropdown/input populated from task data or a known user list - [ ] Filters apply client-side to the fetched task list (no additional API calls) - [ ] Active filters are visually indicated (e.g., badge count, highlighted filter chip) - [ ] A "Clear filters" action resets all filters ### Label and Assignee Integration - [ ] Labels are fetched from `GET /api/studio-api/labels` for the filter and task form dropdowns - [ ] Labels display with their name and color (color swatch or colored badge) - [ ] Assignees are attached/detached via `POST/DELETE /api/studio-api/tasks/{taskId}/assignments` - [ ] Labels are attached/detached via `POST/DELETE /api/studio-api/tasks/{taskId}/labels/{labelId}` ### UI/UX Quality - [ ] Board is responsive: on small screens, columns stack vertically or become horizontally scrollable - [ ] All UI uses the existing design system (`@foundary-test-1770784989/ui` components, CSS variables) - [ ] Loading states shown while data is being fetched (skeleton or spinner) - [ ] Error states shown when API calls fail (toast or inline alert) - [ ] Board integrates into the existing `DashboardShell` layout with sidebar navigation ### Routing - [ ] Board is accessible at a dedicated route (e.g., `/projects/{projectId}/board`) - [ ] Route is added to the sidebar navigation - [ ] Uses `react-router-dom` for client-side routing (already installed) ## Technical Constraints - **Frontend stack**: React 18 + TypeScript + Vite, using `@foundary-test-1770784989/ui` component library (Radix UI primitives + Tailwind CSS) - **Drag-and-drop**: Requires installing a DnD library (e.g., `@dnd-kit/core` + `@dnd-kit/sortable`) — no DnD library currently installed - **API client**: Use `@foundary-test-1770784989/api-client` (`createClient`) for all API calls - **CSS**: Must use CSS custom properties (`var(--*)`) from the design token system — no hardcoded colors - **Layout**: Must render inside `DashboardShell` with `Sidebar` and `Header` components from `@foundary-test-1770784989/layout` - **Components**: Use existing `Dialog`, `Button`, `Input`, `Textarea`, `Select`, `Badge`, `Card`, `Alert` from `@foundary-test-1770784989/ui` - **No state management library**: Use React state + context or hooks for local state; no Redux/Zustand currently in the project - **Backend dependency**: Requires `data-models` feature to be implemented first (provides the Task, Label, Assignment CRUD endpoints) - **Task statuses**: Board maps `open` → To Do, `in_progress` → In Progress, `done` → Done. The `cancelled` status exists in the API but is not shown on the board. - **No pagination**: Backend list endpoints return all records (per data-models spec); client renders all tasks ## Dependencies - **`data-models` feature** (must be built first): Provides all backend REST endpoints: - `GET/POST /api/studio-api/projects/{projectId}/tasks` — list/create tasks - `GET/PUT/DELETE /api/studio-api/tasks/{id}` — read/update/delete task - `GET /api/studio-api/labels` — list labels - `POST/DELETE /api/studio-api/tasks/{taskId}/labels/{labelId}` — manage task-label associations - `POST/DELETE /api/studio-api/tasks/{taskId}/assignments` — manage assignments - **Project selection**: The board is scoped to a single project. Requires a project to exist and be selected/navigated to. - **`react-router-dom`** (already installed v6.23.1): For client-side routing - **DnD library** (to be installed): `@dnd-kit/core` and `@dnd-kit/sortable` recommended for accessible, modern drag-and-drop - **Existing shared packages**: `@foundary-test-1770784989/ui`, `@foundary-test-1770784989/layout`, `@foundary-test-1770784989/api-client` ## Out of Scope - **Project CRUD UI** — This feature assumes a project already exists; creating/managing projects is a separate feature - **User management / user picker** — Assignee field will accept a user ID string; no user directory or avatar service - **Real-time updates** — No WebSocket/SSE for live board sync across clients - **Task comments or activity log** — No comment thread or history view on tasks - **Subtasks or task dependencies** — Flat task list only - **Task reordering within a column** — Cards within a column are ordered by `created_at`; manual sort order is out of scope - **Board customization** — Column names and statuses are fixed (To Do / In Progress / Done); no custom columns - **Bulk operations** — No multi-select, bulk status change, or bulk delete - **Offline support** — Requires network connectivity - **Priority filtering** — Only label and assignee filters are in scope; priority filter can be added later - **Label CRUD UI** — Labels are managed via API; no UI for creating/editing labels in this feature ## Open Questions 1. **Project context**: How does the user select which project's board to view? Is there a project list page, or should the board default to the first/only project? This affects routing and navigation design. 2. **Assignee data source**: Since there is no user directory, where does the assignee dropdown get its options? Options: (a) free-text input for user ID, (b) derive from existing assignments on tasks, (c) hardcoded list for MVP. 3. **DnD library choice**: `@dnd-kit` is recommended for its accessibility and modern API, but `react-beautiful-dnd` is another option. Should we standardize on one? 4. **Optimistic updates vs. refetch**: Should the board use optimistic UI updates (move card immediately, revert on error) or refetch the full task list after each mutation? 5. **State management**: Should task data be managed via React Context (shared across board + modals) or local component state with prop drilling? Adding React Query / TanStack Query for server state caching is another option. 6. **Board URL structure**: Should the route be `/projects/:projectId/board` or `/board?project=:projectId` or something else?