@prmichaelsen/acp-visualizer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/agent/commands/acp.clarification-address.md +417 -0
- package/agent/commands/acp.clarification-capture.md +386 -0
- package/agent/commands/acp.clarification-create.md +437 -0
- package/agent/commands/acp.clarifications-research.md +326 -0
- package/agent/commands/acp.command-create.md +432 -0
- package/agent/commands/acp.design-create.md +286 -0
- package/agent/commands/acp.design-reference.md +355 -0
- package/agent/commands/acp.handoff.md +270 -0
- package/agent/commands/acp.index.md +423 -0
- package/agent/commands/acp.init.md +546 -0
- package/agent/commands/acp.package-create.md +895 -0
- package/agent/commands/acp.package-info.md +212 -0
- package/agent/commands/acp.package-install.md +539 -0
- package/agent/commands/acp.package-list.md +280 -0
- package/agent/commands/acp.package-publish.md +541 -0
- package/agent/commands/acp.package-remove.md +293 -0
- package/agent/commands/acp.package-search.md +307 -0
- package/agent/commands/acp.package-update.md +361 -0
- package/agent/commands/acp.package-validate.md +540 -0
- package/agent/commands/acp.pattern-create.md +386 -0
- package/agent/commands/acp.plan.md +587 -0
- package/agent/commands/acp.proceed.md +882 -0
- package/agent/commands/acp.project-create.md +675 -0
- package/agent/commands/acp.project-info.md +312 -0
- package/agent/commands/acp.project-list.md +226 -0
- package/agent/commands/acp.project-remove.md +379 -0
- package/agent/commands/acp.project-set.md +227 -0
- package/agent/commands/acp.project-update.md +307 -0
- package/agent/commands/acp.projects-restore.md +228 -0
- package/agent/commands/acp.projects-sync.md +347 -0
- package/agent/commands/acp.report.md +407 -0
- package/agent/commands/acp.resume.md +239 -0
- package/agent/commands/acp.sessions.md +301 -0
- package/agent/commands/acp.status.md +293 -0
- package/agent/commands/acp.sync.md +364 -0
- package/agent/commands/acp.task-create.md +500 -0
- package/agent/commands/acp.update.md +302 -0
- package/agent/commands/acp.validate.md +466 -0
- package/agent/commands/acp.version-check-for-updates.md +276 -0
- package/agent/commands/acp.version-check.md +191 -0
- package/agent/commands/acp.version-update.md +289 -0
- package/agent/commands/command.template.md +339 -0
- package/agent/commands/git.commit.md +526 -0
- package/agent/commands/git.init.md +514 -0
- package/agent/commands/tanstack-cloudflare.deploy.md +272 -0
- package/agent/commands/tanstack-cloudflare.tail.md +275 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/design.template.md +154 -0
- package/agent/design/local.dashboard-layout-routing.md +288 -0
- package/agent/design/local.data-model-yaml-parsing.md +310 -0
- package/agent/design/local.search-filtering.md +331 -0
- package/agent/design/local.server-api-auto-refresh.md +235 -0
- package/agent/design/local.table-tree-views.md +299 -0
- package/agent/design/local.visualizer-requirements.md +349 -0
- package/agent/design/requirements.template.md +387 -0
- package/agent/index/.gitkeep +0 -0
- package/agent/index/acp.core.yaml +137 -0
- package/agent/index/local.main.template.yaml +37 -0
- package/agent/manifest.template.yaml +13 -0
- package/agent/manifest.yaml +302 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-project-scaffold-data-pipeline.md +67 -0
- package/agent/milestones/milestone-1-{title}.template.md +206 -0
- package/agent/milestones/milestone-2-dashboard-views-interaction.md +79 -0
- package/agent/package.template.yaml +86 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.template.md +1237 -0
- package/agent/patterns/pattern.template.md +382 -0
- package/agent/patterns/tanstack-cloudflare.acl-permissions.md +332 -0
- package/agent/patterns/tanstack-cloudflare.action-bar-item.md +416 -0
- package/agent/patterns/tanstack-cloudflare.api-route-handlers.md +401 -0
- package/agent/patterns/tanstack-cloudflare.auth-session-management.md +387 -0
- package/agent/patterns/tanstack-cloudflare.card-and-list.md +271 -0
- package/agent/patterns/tanstack-cloudflare.chat-engine.md +353 -0
- package/agent/patterns/tanstack-cloudflare.confirmation-tokens.md +346 -0
- package/agent/patterns/tanstack-cloudflare.durable-objects-websocket.md +516 -0
- package/agent/patterns/tanstack-cloudflare.email-service.md +431 -0
- package/agent/patterns/tanstack-cloudflare.expander.md +98 -0
- package/agent/patterns/tanstack-cloudflare.fcm-push.md +115 -0
- package/agent/patterns/tanstack-cloudflare.firebase-anonymous-sessions.md +441 -0
- package/agent/patterns/tanstack-cloudflare.firebase-auth.md +348 -0
- package/agent/patterns/tanstack-cloudflare.firebase-firestore.md +550 -0
- package/agent/patterns/tanstack-cloudflare.firebase-storage.md +369 -0
- package/agent/patterns/tanstack-cloudflare.form-controls.md +145 -0
- package/agent/patterns/tanstack-cloudflare.global-search-context.md +93 -0
- package/agent/patterns/tanstack-cloudflare.image-carousel.md +126 -0
- package/agent/patterns/tanstack-cloudflare.library-services.md +553 -0
- package/agent/patterns/tanstack-cloudflare.lightbox.md +169 -0
- package/agent/patterns/tanstack-cloudflare.markdown-content.md +115 -0
- package/agent/patterns/tanstack-cloudflare.mention-suggestions.md +98 -0
- package/agent/patterns/tanstack-cloudflare.modal.md +156 -0
- package/agent/patterns/tanstack-cloudflare.nextjs-to-tanstack-routing.md +461 -0
- package/agent/patterns/tanstack-cloudflare.notifications-engine.md +151 -0
- package/agent/patterns/tanstack-cloudflare.oauth-token-refresh.md +90 -0
- package/agent/patterns/tanstack-cloudflare.og-metadata.md +296 -0
- package/agent/patterns/tanstack-cloudflare.pagination.md +442 -0
- package/agent/patterns/tanstack-cloudflare.pill-input.md +220 -0
- package/agent/patterns/tanstack-cloudflare.provider-adapter.md +401 -0
- package/agent/patterns/tanstack-cloudflare.rate-limiting.md +323 -0
- package/agent/patterns/tanstack-cloudflare.scheduled-tasks.md +338 -0
- package/agent/patterns/tanstack-cloudflare.searchable-settings.md +375 -0
- package/agent/patterns/tanstack-cloudflare.slide-over.md +129 -0
- package/agent/patterns/tanstack-cloudflare.ssr-preload.md +571 -0
- package/agent/patterns/tanstack-cloudflare.third-party-api-integration.md +508 -0
- package/agent/patterns/tanstack-cloudflare.toast-system.md +142 -0
- package/agent/patterns/tanstack-cloudflare.unified-header.md +280 -0
- package/agent/patterns/tanstack-cloudflare.user-scoped-collections.md +628 -0
- package/agent/patterns/tanstack-cloudflare.websocket-manager.md +237 -0
- package/agent/patterns/tanstack-cloudflare.wrangler-configuration.md +358 -0
- package/agent/patterns/tanstack-cloudflare.zod-schema-validation.md +336 -0
- package/agent/progress.template.yaml +161 -0
- package/agent/progress.yaml +145 -0
- package/agent/schemas/package.schema.yaml +276 -0
- package/agent/scripts/acp.common.sh +1781 -0
- package/agent/scripts/acp.install.sh +333 -0
- package/agent/scripts/acp.package-create.sh +924 -0
- package/agent/scripts/acp.package-info.sh +288 -0
- package/agent/scripts/acp.package-install.sh +893 -0
- package/agent/scripts/acp.package-list.sh +311 -0
- package/agent/scripts/acp.package-publish.sh +420 -0
- package/agent/scripts/acp.package-remove.sh +348 -0
- package/agent/scripts/acp.package-search.sh +156 -0
- package/agent/scripts/acp.package-update.sh +517 -0
- package/agent/scripts/acp.package-validate.sh +1018 -0
- package/agent/scripts/acp.uninstall.sh +85 -0
- package/agent/scripts/acp.version-check-for-updates.sh +98 -0
- package/agent/scripts/acp.version-check.sh +47 -0
- package/agent/scripts/acp.version-update.sh +176 -0
- package/agent/scripts/acp.yaml-parser.sh +985 -0
- package/agent/scripts/acp.yaml-validate.sh +205 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-1-initialize-tanstack-start-project.md +210 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-2-implement-data-model-yaml-parser.md +294 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-3-build-server-api-data-loading.md +193 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-4-add-auto-refresh-sse.md +262 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-10-polish-integration-testing.md +156 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-5-build-dashboard-layout-routing.md +178 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-6-build-overview-page.md +141 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-7-implement-milestone-table-view.md +153 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-8-implement-milestone-tree-view.md +174 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-9-implement-search-filtering.md +233 -0
- package/agent/tasks/task-1-{title}.template.md +244 -0
- package/bin/visualize.mjs +84 -0
- package/package.json +48 -0
- package/src/components/ExtraFieldsBadge.tsx +15 -0
- package/src/components/FilterBar.tsx +33 -0
- package/src/components/Header.tsx +23 -0
- package/src/components/MilestoneTable.tsx +167 -0
- package/src/components/MilestoneTree.tsx +84 -0
- package/src/components/ProgressBar.tsx +20 -0
- package/src/components/SearchInput.tsx +22 -0
- package/src/components/Sidebar.tsx +54 -0
- package/src/components/StatusBadge.tsx +23 -0
- package/src/components/StatusDot.tsx +12 -0
- package/src/components/TaskList.tsx +36 -0
- package/src/components/ViewToggle.tsx +31 -0
- package/src/lib/config.ts +8 -0
- package/src/lib/file-watcher.ts +43 -0
- package/src/lib/search.ts +48 -0
- package/src/lib/types.ts +73 -0
- package/src/lib/useAutoRefresh.ts +31 -0
- package/src/lib/useCollapse.ts +31 -0
- package/src/lib/useFilteredData.ts +55 -0
- package/src/lib/yaml-loader-real.spec.ts +47 -0
- package/src/lib/yaml-loader.spec.ts +201 -0
- package/src/lib/yaml-loader.ts +265 -0
- package/src/routeTree.gen.ts +140 -0
- package/src/router.tsx +10 -0
- package/src/routes/__root.tsx +75 -0
- package/src/routes/api/watch.ts +29 -0
- package/src/routes/index.tsx +115 -0
- package/src/routes/milestones.tsx +50 -0
- package/src/routes/search.tsx +84 -0
- package/src/routes/tasks.tsx +63 -0
- package/src/services/progress-database.service.ts +46 -0
- package/src/styles.css +25 -0
- package/tsconfig.json +24 -0
- package/vite.config.ts +16 -0
- package/vitest.config.ts +27 -0
package/agent/tasks/milestone-2-dashboard-views-interaction/task-5-build-dashboard-layout-routing.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Task 5: Build Dashboard Layout & Routing
|
|
2
|
+
|
|
3
|
+
**Milestone**: [M2 - Dashboard Views & Interaction](../../milestones/milestone-2-dashboard-views-interaction.md)
|
|
4
|
+
**Design Reference**: [Dashboard Layout & Routing](../../design/local.dashboard-layout-routing.md)
|
|
5
|
+
**Estimated Time**: 3 hours
|
|
6
|
+
**Dependencies**: Task 4
|
|
7
|
+
**Status**: Not Started
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Build the application shell with sidebar navigation, header bar, and file-based routing for all pages. This establishes the persistent layout frame that all dashboard views render within.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
With the data pipeline complete from Milestone 1, the app needs a proper navigation shell before individual views can be built. The layout follows a standard admin dashboard pattern: fixed sidebar on the left for navigation, a header bar showing project metadata, and a main content area where route components render via the TanStack Router Outlet. All subsequent M2 tasks depend on this layout being in place.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Update `app/routes/__root.tsx` with full layout
|
|
26
|
+
|
|
27
|
+
Replace the minimal root layout with a flex container that includes the Sidebar component, and a main content area with Header and Outlet:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// app/routes/__root.tsx
|
|
31
|
+
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
|
32
|
+
import { Sidebar } from "../components/Sidebar";
|
|
33
|
+
import { Header } from "../components/Header";
|
|
34
|
+
|
|
35
|
+
export const Route = createRootRoute({
|
|
36
|
+
component: RootLayout,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
function RootLayout() {
|
|
40
|
+
return (
|
|
41
|
+
<div className="dark min-h-screen bg-gray-950 text-gray-100 flex">
|
|
42
|
+
<Sidebar />
|
|
43
|
+
<div className="flex-1 flex flex-col">
|
|
44
|
+
<Header />
|
|
45
|
+
<main className="flex-1 overflow-auto p-6">
|
|
46
|
+
<Outlet />
|
|
47
|
+
</main>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Create `app/components/Sidebar.tsx`
|
|
55
|
+
|
|
56
|
+
Build the sidebar navigation component:
|
|
57
|
+
|
|
58
|
+
- Fixed width of 14rem (`w-56`)
|
|
59
|
+
- Right border (`border-r border-gray-800`)
|
|
60
|
+
- Dark background (`bg-gray-950`)
|
|
61
|
+
- Nav items: Overview (`/`), Milestones (`/milestones`), Tasks (`/tasks`), Activity (`/activity`)
|
|
62
|
+
- Each nav item uses `<Link>` from TanStack Router with active state styling
|
|
63
|
+
- SearchTrigger button at the bottom of the sidebar
|
|
64
|
+
- Use `lucide-react` icons for each nav item (LayoutDashboard, Flag, CheckSquare, Activity, Search)
|
|
65
|
+
|
|
66
|
+
### 3. Create `app/components/Header.tsx`
|
|
67
|
+
|
|
68
|
+
Build the header bar component:
|
|
69
|
+
|
|
70
|
+
- Displays project name and version from route context or loader data
|
|
71
|
+
- Includes a StatusBadge showing overall project status
|
|
72
|
+
- Includes a ProgressBar showing overall completion percentage
|
|
73
|
+
- Styled with bottom border (`border-b border-gray-800`) and padding
|
|
74
|
+
|
|
75
|
+
### 4. Create `app/components/StatusBadge.tsx`
|
|
76
|
+
|
|
77
|
+
Build the color-coded status pill component:
|
|
78
|
+
|
|
79
|
+
- Accepts a `status` prop: `"completed"` | `"in_progress"` | `"not_started"` | `"blocked"` | `"skipped"`
|
|
80
|
+
- Renders as an inline pill with rounded corners (`rounded-full px-2.5 py-0.5 text-xs font-medium`)
|
|
81
|
+
- Color mapping:
|
|
82
|
+
- `completed` → green (`bg-green-500/20 text-green-400`)
|
|
83
|
+
- `in_progress` → blue (`bg-blue-500/20 text-blue-400`)
|
|
84
|
+
- `not_started` → gray (`bg-gray-500/20 text-gray-400`)
|
|
85
|
+
- `blocked` → red (`bg-red-500/20 text-red-400`)
|
|
86
|
+
- `skipped` → purple (`bg-purple-500/20 text-purple-400`)
|
|
87
|
+
|
|
88
|
+
### 5. Create `app/components/ProgressBar.tsx`
|
|
89
|
+
|
|
90
|
+
Build the horizontal progress bar component:
|
|
91
|
+
|
|
92
|
+
- Accepts `value` (0–100) and optional `size` (`"sm"` | `"md"`) props
|
|
93
|
+
- Horizontal bar with gray-800 background track
|
|
94
|
+
- Filled portion uses green-500 at 100%, blue-500 otherwise
|
|
95
|
+
- Shows percentage text to the right of the bar
|
|
96
|
+
- `sm` size: `h-1.5`, `md` size: `h-2.5`
|
|
97
|
+
- Smooth width transition (`transition-all duration-300`)
|
|
98
|
+
|
|
99
|
+
### 6. Create route placeholder files
|
|
100
|
+
|
|
101
|
+
Create placeholder route components for pages to be built in subsequent tasks:
|
|
102
|
+
|
|
103
|
+
- `app/routes/milestones.tsx` — "Milestones" heading with placeholder text
|
|
104
|
+
- `app/routes/tasks.tsx` — "Tasks" heading with placeholder text
|
|
105
|
+
- `app/routes/search.tsx` — "Search" heading with placeholder text
|
|
106
|
+
|
|
107
|
+
Each route file should use `createFileRoute` and export a basic component.
|
|
108
|
+
|
|
109
|
+
### 7. Apply design token styling
|
|
110
|
+
|
|
111
|
+
Ensure all components follow the design token palette:
|
|
112
|
+
|
|
113
|
+
- Background: `bg-gray-950`
|
|
114
|
+
- Surfaces: `bg-gray-900`
|
|
115
|
+
- Borders: `border-gray-800`
|
|
116
|
+
- Primary text: `text-gray-100`
|
|
117
|
+
- Secondary text: `text-gray-400`
|
|
118
|
+
- Font: Inter for sans, JetBrains Mono for mono
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Verification
|
|
123
|
+
|
|
124
|
+
- [ ] Sidebar renders at 14rem width with all nav items (Overview, Milestones, Tasks, Activity)
|
|
125
|
+
- [ ] Clicking nav links navigates between routes without full page reload
|
|
126
|
+
- [ ] Active nav item is visually highlighted
|
|
127
|
+
- [ ] Header displays project name and version
|
|
128
|
+
- [ ] StatusBadge renders correct colors for each status value
|
|
129
|
+
- [ ] ProgressBar fills proportionally to value and shows percentage
|
|
130
|
+
- [ ] ProgressBar is green at 100%, blue otherwise
|
|
131
|
+
- [ ] All route placeholders render when navigated to
|
|
132
|
+
- [ ] Dark theme styling applied consistently (bg-gray-950, gray-800 borders, gray-100 text)
|
|
133
|
+
- [ ] Layout is responsive — main content area fills remaining space
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Expected Output
|
|
138
|
+
|
|
139
|
+
**File Structure**:
|
|
140
|
+
```
|
|
141
|
+
app/
|
|
142
|
+
├── components/
|
|
143
|
+
│ ├── Header.tsx
|
|
144
|
+
│ ├── ProgressBar.tsx
|
|
145
|
+
│ ├── Sidebar.tsx
|
|
146
|
+
│ └── StatusBadge.tsx
|
|
147
|
+
├── routes/
|
|
148
|
+
│ ├── __root.tsx (updated)
|
|
149
|
+
│ ├── index.tsx (existing)
|
|
150
|
+
│ ├── milestones.tsx (new)
|
|
151
|
+
│ ├── tasks.tsx (new)
|
|
152
|
+
│ └── search.tsx (new)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Key Files Created/Modified**:
|
|
156
|
+
- `app/routes/__root.tsx`: Updated with full layout (Sidebar + Header + Outlet)
|
|
157
|
+
- `app/components/Sidebar.tsx`: Navigation sidebar with route links
|
|
158
|
+
- `app/components/Header.tsx`: Project info header bar
|
|
159
|
+
- `app/components/StatusBadge.tsx`: Reusable color-coded status pill
|
|
160
|
+
- `app/components/ProgressBar.tsx`: Reusable horizontal progress bar
|
|
161
|
+
- `app/routes/milestones.tsx`: Placeholder milestones page
|
|
162
|
+
- `app/routes/tasks.tsx`: Placeholder tasks page
|
|
163
|
+
- `app/routes/search.tsx`: Placeholder search page
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Notes
|
|
168
|
+
|
|
169
|
+
- StatusBadge and ProgressBar are foundational components reused across all views in later tasks
|
|
170
|
+
- The sidebar width of 14rem is fixed; the main content area uses flex-1 to fill remaining space
|
|
171
|
+
- Search trigger in the sidebar will be wired to GlobalSearchContext in Task 9
|
|
172
|
+
- Route context for header data will be populated by loader functions added in Task 6
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
**Next Task**: [Task 6: Build Overview Page](./task-6-build-overview-page.md)
|
|
177
|
+
**Related Design Docs**: [Dashboard Layout & Routing](../../design/local.dashboard-layout-routing.md)
|
|
178
|
+
**Estimated Completion Date**: TBD
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Task 6: Build Overview Page
|
|
2
|
+
|
|
3
|
+
**Milestone**: [M2 - Dashboard Views & Interaction](../../milestones/milestone-2-dashboard-views-interaction.md)
|
|
4
|
+
**Design Reference**: [Dashboard Layout & Routing](../../design/local.dashboard-layout-routing.md)
|
|
5
|
+
**Estimated Time**: 2 hours
|
|
6
|
+
**Dependencies**: Task 5
|
|
7
|
+
**Status**: Not Started
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Build the dashboard home page showing project metadata, milestone summary, next steps, and blockers. This is the first page users see and provides an at-a-glance overview of the entire project's progress.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
The overview page replaces the raw JSON dump from Milestone 1 with a structured, scannable dashboard. It surfaces the most important information — overall status, milestone progress, upcoming work, and blockers — in a card-based layout. This page uses the StatusBadge and ProgressBar components from Task 5 and pulls data from the progress.yaml pipeline established in Milestone 1.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Update `app/routes/index.tsx`
|
|
26
|
+
|
|
27
|
+
Replace the placeholder content with structured overview components. Wire up the route's `beforeLoad` or `loader` to fetch parsed progress data via the server function from Milestone 1.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
export const Route = createFileRoute("/")({
|
|
31
|
+
loader: async () => {
|
|
32
|
+
const data = await getProgressData();
|
|
33
|
+
return { data };
|
|
34
|
+
},
|
|
35
|
+
component: OverviewPage,
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Create project metadata card
|
|
40
|
+
|
|
41
|
+
Display at the top of the overview page:
|
|
42
|
+
|
|
43
|
+
- Project name (large heading)
|
|
44
|
+
- Version number
|
|
45
|
+
- StatusBadge showing overall project status
|
|
46
|
+
- Start date (formatted)
|
|
47
|
+
- Description text
|
|
48
|
+
|
|
49
|
+
Style with the card pattern: `bg-gray-900/50 border border-gray-800 rounded-xl p-4`.
|
|
50
|
+
|
|
51
|
+
### 3. Create overall progress section
|
|
52
|
+
|
|
53
|
+
Below the metadata card, show:
|
|
54
|
+
|
|
55
|
+
- A large ProgressBar (md size) showing overall completion percentage
|
|
56
|
+
- Computed from milestone task completion across all milestones
|
|
57
|
+
- Summary stats: total milestones, completed milestones, total tasks, completed tasks
|
|
58
|
+
|
|
59
|
+
### 4. Create milestone summary list
|
|
60
|
+
|
|
61
|
+
Compact rows showing each milestone at a glance:
|
|
62
|
+
|
|
63
|
+
- Each row: milestone name, StatusBadge, ProgressBar (sm size), task count (e.g., "3/7 tasks")
|
|
64
|
+
- Rows are clickable and navigate to `/milestones` (or anchor to the specific milestone)
|
|
65
|
+
- Styled as a list within a card container
|
|
66
|
+
|
|
67
|
+
### 5. Create `app/components/NextSteps.tsx`
|
|
68
|
+
|
|
69
|
+
Renders the `next_steps` array from progress.yaml as a checklist:
|
|
70
|
+
|
|
71
|
+
- Each item displayed as a list item with a circle/check icon
|
|
72
|
+
- Styled with left border accent (`border-l-2 border-blue-500`)
|
|
73
|
+
- If `next_steps` is empty or undefined, render nothing (no empty state needed)
|
|
74
|
+
|
|
75
|
+
### 6. Create `app/components/BlockersDisplay.tsx`
|
|
76
|
+
|
|
77
|
+
Renders `current_blockers` with warning styling:
|
|
78
|
+
|
|
79
|
+
- Only renders when blockers array is non-empty
|
|
80
|
+
- Each blocker shown with a warning icon (AlertTriangle from lucide-react)
|
|
81
|
+
- Styled with warning colors: `bg-red-500/10 border border-red-500/20 text-red-400`
|
|
82
|
+
- If no blockers, component returns null (renders nothing)
|
|
83
|
+
|
|
84
|
+
### 7. Apply card layout styling
|
|
85
|
+
|
|
86
|
+
Arrange all sections in a responsive grid/stack layout:
|
|
87
|
+
|
|
88
|
+
- Metadata card spans full width at top
|
|
89
|
+
- Progress section below metadata
|
|
90
|
+
- Milestone summary and next steps side by side (or stacked on narrow viewports)
|
|
91
|
+
- Blockers at the bottom (when present)
|
|
92
|
+
- Consistent spacing: `space-y-6` between sections
|
|
93
|
+
- All cards use: `bg-gray-900/50 border border-gray-800 rounded-xl p-4`
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Verification
|
|
98
|
+
|
|
99
|
+
- [ ] Overview page shows project name, version, status badge, start date, and description
|
|
100
|
+
- [ ] Overall progress bar displays correct completion percentage
|
|
101
|
+
- [ ] Milestone summary lists all milestones with name, status, progress, and task count
|
|
102
|
+
- [ ] NextSteps component renders next_steps items as a checklist
|
|
103
|
+
- [ ] BlockersDisplay shows blockers with warning styling when blockers exist
|
|
104
|
+
- [ ] BlockersDisplay renders nothing when there are no blockers
|
|
105
|
+
- [ ] Empty states handled gracefully (no milestones, no next steps)
|
|
106
|
+
- [ ] Card styling is consistent across all sections
|
|
107
|
+
- [ ] Data loads via SSR (page renders with data on first paint, no loading spinner)
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Expected Output
|
|
112
|
+
|
|
113
|
+
**File Structure**:
|
|
114
|
+
```
|
|
115
|
+
app/
|
|
116
|
+
├── components/
|
|
117
|
+
│ ├── BlockersDisplay.tsx (new)
|
|
118
|
+
│ └── NextSteps.tsx (new)
|
|
119
|
+
├── routes/
|
|
120
|
+
│ └── index.tsx (updated)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Key Files Created/Modified**:
|
|
124
|
+
- `app/routes/index.tsx`: Updated with structured overview layout and data loader
|
|
125
|
+
- `app/components/NextSteps.tsx`: Checklist component for next_steps array
|
|
126
|
+
- `app/components/BlockersDisplay.tsx`: Warning display for current_blockers array
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Notes
|
|
131
|
+
|
|
132
|
+
- The overview page is the default route (`/`) and the first thing users see
|
|
133
|
+
- Progress percentage is computed client-side from the milestone/task data, not stored in progress.yaml
|
|
134
|
+
- The milestone summary rows on this page are a compact version; the full milestone view is in Task 7
|
|
135
|
+
- StatusBadge and ProgressBar components come from Task 5
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
**Next Task**: [Task 7: Implement Milestone Table View](./task-7-implement-milestone-table-view.md)
|
|
140
|
+
**Related Design Docs**: [Dashboard Layout & Routing](../../design/local.dashboard-layout-routing.md)
|
|
141
|
+
**Estimated Completion Date**: TBD
|
package/agent/tasks/milestone-2-dashboard-views-interaction/task-7-implement-milestone-table-view.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Task 7: Implement Milestone Table View
|
|
2
|
+
|
|
3
|
+
**Milestone**: [M2 - Dashboard Views & Interaction](../../milestones/milestone-2-dashboard-views-interaction.md)
|
|
4
|
+
**Design Reference**: [Table & Tree Views](../../design/local.table-tree-views.md)
|
|
5
|
+
**Estimated Time**: 3 hours
|
|
6
|
+
**Dependencies**: Task 5
|
|
7
|
+
**Status**: Not Started
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Build a sortable milestone table using @tanstack/react-table with expandable row detail. This provides the primary data-dense view for examining milestone status, progress, and associated tasks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
The milestone table is the core data view of the dashboard, allowing users to see all milestones in a structured, sortable format. It uses @tanstack/react-table for column management, sorting, and row expansion. Each row can be expanded to reveal the tasks within that milestone, displayed via a reusable TaskList component. The table also introduces the ViewToggle component that switches between table and tree views (tree view is built in Task 8).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Create `app/components/MilestoneTable.tsx`
|
|
26
|
+
|
|
27
|
+
Build the table component using TanStack Table:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { createColumnHelper, useReactTable, getCoreRowModel, getSortedRowModel, getExpandedRowModel } from "@tanstack/react-table";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- Use `createColumnHelper` to define typed columns
|
|
34
|
+
- Use `useReactTable` with `getCoreRowModel`, `getSortedRowModel`, and `getExpandedRowModel`
|
|
35
|
+
- Render table with `<table>` elements styled with Tailwind (border-collapse, full width)
|
|
36
|
+
|
|
37
|
+
### 2. Define table columns
|
|
38
|
+
|
|
39
|
+
Configure the following columns:
|
|
40
|
+
|
|
41
|
+
| Column | Width | Content |
|
|
42
|
+
|--------|-------|---------|
|
|
43
|
+
| Expand | 40px | Chevron icon (ChevronRight/ChevronDown from lucide-react) |
|
|
44
|
+
| Name | flex | Milestone name, linked to detail |
|
|
45
|
+
| Status | 120px | StatusBadge component |
|
|
46
|
+
| Progress | 140px | ProgressBar (sm) + percentage text |
|
|
47
|
+
| Tasks | 80px | Completed/total count (e.g., "3/7") |
|
|
48
|
+
| Started | 100px | Start date, formatted |
|
|
49
|
+
| Est. Weeks | 80px | Estimated duration in weeks |
|
|
50
|
+
|
|
51
|
+
### 3. Implement sort headers
|
|
52
|
+
|
|
53
|
+
- Clicking a column header toggles sort direction (asc → desc → none)
|
|
54
|
+
- Show visual sort indicators: ChevronUp for ascending, ChevronDown for descending
|
|
55
|
+
- Sortable columns: Name, Status, Progress, Tasks, Started, Est. Weeks
|
|
56
|
+
- Default sort: by natural order (no initial sort)
|
|
57
|
+
|
|
58
|
+
### 4. Implement row expansion
|
|
59
|
+
|
|
60
|
+
- Clicking the chevron icon in the first column toggles row expansion
|
|
61
|
+
- Expanded row reveals a TaskList component showing all tasks for that milestone
|
|
62
|
+
- Use `getExpandedRowModel` from TanStack Table
|
|
63
|
+
- Expanded content spans all columns with appropriate padding and indentation
|
|
64
|
+
|
|
65
|
+
### 5. Create `app/components/TaskList.tsx`
|
|
66
|
+
|
|
67
|
+
Build the task list component for expanded milestone rows:
|
|
68
|
+
|
|
69
|
+
- Indented list (`pl-8`) showing tasks within a milestone
|
|
70
|
+
- Each task row shows: StatusDot, task name, truncated notes (max 80 chars), ExtraFieldsBadge
|
|
71
|
+
- Styled with subtle row separators (`border-b border-gray-800/50`)
|
|
72
|
+
- Used by both the table view (Task 7) and tree view (Task 8)
|
|
73
|
+
|
|
74
|
+
### 6. Create `app/components/ExtraFieldsBadge.tsx`
|
|
75
|
+
|
|
76
|
+
Build the badge component for tasks with extra/custom fields:
|
|
77
|
+
|
|
78
|
+
- Shows a "+N" count indicating how many extra fields exist beyond standard fields (name, status, notes)
|
|
79
|
+
- Only renders when extra fields are present
|
|
80
|
+
- On hover, shows a tooltip with the extra fields as formatted JSON
|
|
81
|
+
- Styled as a small pill: `bg-gray-700 text-gray-300 text-xs rounded px-1.5`
|
|
82
|
+
|
|
83
|
+
### 7. Update `app/routes/milestones.tsx`
|
|
84
|
+
|
|
85
|
+
Wire up the milestones route:
|
|
86
|
+
|
|
87
|
+
- Add `beforeLoad` or `loader` to fetch progress data via SSR
|
|
88
|
+
- Render a page header with "Milestones" title and ViewToggle
|
|
89
|
+
- Render MilestoneTable as the default view
|
|
90
|
+
- Handle empty state: show "No milestones found" message when data has no milestones
|
|
91
|
+
|
|
92
|
+
### 8. Create `app/components/ViewToggle.tsx`
|
|
93
|
+
|
|
94
|
+
Build the table/tree toggle component:
|
|
95
|
+
|
|
96
|
+
- Two buttons: "Table" and "Tree" (or icons: List and GitBranch from lucide-react)
|
|
97
|
+
- Active view button is visually highlighted (`bg-gray-700` vs `bg-transparent`)
|
|
98
|
+
- Accepts `view` and `onViewChange` props
|
|
99
|
+
- Compact styling: `inline-flex rounded-lg border border-gray-700`
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Verification
|
|
104
|
+
|
|
105
|
+
- [ ] Table renders all milestones from progress data
|
|
106
|
+
- [ ] All columns display correct data (name, status badge, progress bar, task count, dates)
|
|
107
|
+
- [ ] Clicking column headers sorts the table (ascending, descending, none)
|
|
108
|
+
- [ ] Sort direction indicators (chevrons) appear on sorted columns
|
|
109
|
+
- [ ] Clicking expand chevron reveals TaskList for that milestone
|
|
110
|
+
- [ ] TaskList shows all tasks with StatusDot, name, truncated notes
|
|
111
|
+
- [ ] ExtraFieldsBadge appears for tasks with extra fields and shows "+N" count
|
|
112
|
+
- [ ] ExtraFieldsBadge tooltip shows extra field details on hover
|
|
113
|
+
- [ ] ViewToggle renders with Table/Tree options
|
|
114
|
+
- [ ] Empty state handled when no milestones exist
|
|
115
|
+
- [ ] Table scrolls horizontally on narrow viewports if needed
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Expected Output
|
|
120
|
+
|
|
121
|
+
**File Structure**:
|
|
122
|
+
```
|
|
123
|
+
app/
|
|
124
|
+
├── components/
|
|
125
|
+
│ ├── ExtraFieldsBadge.tsx (new)
|
|
126
|
+
│ ├── MilestoneTable.tsx (new)
|
|
127
|
+
│ ├── TaskList.tsx (new)
|
|
128
|
+
│ └── ViewToggle.tsx (new)
|
|
129
|
+
├── routes/
|
|
130
|
+
│ └── milestones.tsx (updated)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Key Files Created/Modified**:
|
|
134
|
+
- `app/components/MilestoneTable.tsx`: Sortable milestone table with row expansion
|
|
135
|
+
- `app/components/TaskList.tsx`: Reusable task list for expanded rows (shared with tree view)
|
|
136
|
+
- `app/components/ExtraFieldsBadge.tsx`: Badge showing extra field count with tooltip
|
|
137
|
+
- `app/components/ViewToggle.tsx`: Table/Tree view toggle buttons
|
|
138
|
+
- `app/routes/milestones.tsx`: Updated with data loader and table rendering
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Notes
|
|
143
|
+
|
|
144
|
+
- TaskList is intentionally extracted as a shared component because Task 8 (tree view) reuses it
|
|
145
|
+
- ExtraFieldsBadge handles the schema-agnostic nature of progress.yaml — tasks can have arbitrary extra fields
|
|
146
|
+
- The table uses native `<table>` elements rather than CSS grid for better accessibility and column alignment
|
|
147
|
+
- @tanstack/react-table should already be installed from Task 1
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
**Next Task**: [Task 8: Implement Milestone Tree View](./task-8-implement-milestone-tree-view.md)
|
|
152
|
+
**Related Design Docs**: [Table & Tree Views](../../design/local.table-tree-views.md)
|
|
153
|
+
**Estimated Completion Date**: TBD
|
package/agent/tasks/milestone-2-dashboard-views-interaction/task-8-implement-milestone-tree-view.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Task 8: Implement Milestone Tree View
|
|
2
|
+
|
|
3
|
+
**Milestone**: [M2 - Dashboard Views & Interaction](../../milestones/milestone-2-dashboard-views-interaction.md)
|
|
4
|
+
**Design Reference**: [Table & Tree Views](../../design/local.table-tree-views.md)
|
|
5
|
+
**Estimated Time**: 2 hours
|
|
6
|
+
**Dependencies**: Task 7 (shares TaskList component)
|
|
7
|
+
**Status**: Not Started
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Build an expandable tree view showing milestone-to-task hierarchy with collapse animation. This provides an alternative to the table view, emphasizing the hierarchical structure of milestones and their tasks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
While the table view (Task 7) is data-dense and sortable, the tree view offers a more visual, hierarchy-focused way to browse milestones and tasks. Users can toggle between views using the ViewToggle component. The tree view reuses the TaskList component from Task 7, and adds smooth expand/collapse animations via a custom useCollapse hook. This view is especially useful for quickly scanning which milestones have incomplete tasks.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Create `app/components/MilestoneTree.tsx`
|
|
26
|
+
|
|
27
|
+
Build the tree view component:
|
|
28
|
+
|
|
29
|
+
- Renders each milestone as an expandable row
|
|
30
|
+
- Each row shows: expand/collapse chevron, milestone name, ProgressBar (sm), task count
|
|
31
|
+
- Rows styled as cards: `bg-gray-900/50 border border-gray-800 rounded-lg` with hover effect
|
|
32
|
+
- Clicking a row toggles expansion to show its tasks
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface MilestoneTreeProps {
|
|
36
|
+
milestones: Milestone[];
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Implement expand/collapse state
|
|
41
|
+
|
|
42
|
+
Manage expansion state with a Set of milestone IDs:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const [expanded, setExpanded] = useState<Set<string>>(new Set());
|
|
46
|
+
|
|
47
|
+
const toggleExpanded = (id: string) => {
|
|
48
|
+
setExpanded((prev) => {
|
|
49
|
+
const next = new Set(prev);
|
|
50
|
+
if (next.has(id)) next.delete(id);
|
|
51
|
+
else next.add(id);
|
|
52
|
+
return next;
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Implement smooth collapse animation with useCollapse hook
|
|
58
|
+
|
|
59
|
+
Use the useCollapse hook for smooth height animation when expanding/collapsing milestone task lists:
|
|
60
|
+
|
|
61
|
+
- Wrap the expandable content (TaskList) in a div that uses the useCollapse ref
|
|
62
|
+
- Animation should feel smooth and natural (300ms cubic-bezier transition)
|
|
63
|
+
- Content should not flash or jump during animation
|
|
64
|
+
|
|
65
|
+
### 4. Create `app/lib/useCollapse.ts`
|
|
66
|
+
|
|
67
|
+
Build the custom collapse hook:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
export function useCollapse(isOpen: boolean) {
|
|
71
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
72
|
+
// ...
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- Uses a ref to measure the natural height of the content
|
|
77
|
+
- When `isOpen` is true: animate height from 0 to measured height, then set to `auto`
|
|
78
|
+
- When `isOpen` is false: animate height from current to 0
|
|
79
|
+
- CSS transition: `height 300ms cubic-bezier(0.4, 0, 0.2, 1)`
|
|
80
|
+
- Set `overflow: hidden` during animation
|
|
81
|
+
- Return `{ ref, style }` for the consumer to apply
|
|
82
|
+
|
|
83
|
+
### 5. Reuse TaskList component from Task 7
|
|
84
|
+
|
|
85
|
+
The expanded content for each milestone tree node renders the TaskList component:
|
|
86
|
+
|
|
87
|
+
- Same TaskList from Task 7 — no duplication
|
|
88
|
+
- Shows StatusDot, task name, truncated notes, ExtraFieldsBadge
|
|
89
|
+
- Indented within the tree node
|
|
90
|
+
|
|
91
|
+
### 6. Create `app/components/StatusDot.tsx`
|
|
92
|
+
|
|
93
|
+
Build the small status indicator dot:
|
|
94
|
+
|
|
95
|
+
- Renders different icons/shapes based on status:
|
|
96
|
+
- `completed` → filled green circle with checkmark (`text-green-500`)
|
|
97
|
+
- `in_progress` → filled blue circle (`text-blue-500`)
|
|
98
|
+
- `not_started` → outlined gray circle (`text-gray-500`)
|
|
99
|
+
- Small size: `w-3 h-3` or equivalent
|
|
100
|
+
- Used in TaskList rows alongside task names
|
|
101
|
+
|
|
102
|
+
### 7. Update `app/routes/milestones.tsx`
|
|
103
|
+
|
|
104
|
+
Wire the ViewToggle to switch between MilestoneTable and MilestoneTree:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const [view, setView] = useState<"table" | "tree">("table");
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div>
|
|
111
|
+
<div className="flex items-center justify-between mb-6">
|
|
112
|
+
<h1 className="text-2xl font-bold">Milestones</h1>
|
|
113
|
+
<ViewToggle view={view} onViewChange={setView} />
|
|
114
|
+
</div>
|
|
115
|
+
{view === "table" ? (
|
|
116
|
+
<MilestoneTable milestones={milestones} />
|
|
117
|
+
) : (
|
|
118
|
+
<MilestoneTree milestones={milestones} />
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Verification
|
|
127
|
+
|
|
128
|
+
- [ ] Tree view renders all milestones as expandable rows
|
|
129
|
+
- [ ] Each milestone row shows chevron, name, progress bar, and task count
|
|
130
|
+
- [ ] Clicking a milestone row expands it to show the task list
|
|
131
|
+
- [ ] Clicking again collapses the task list
|
|
132
|
+
- [ ] Expand/collapse animation is smooth (300ms, no jumping or flashing)
|
|
133
|
+
- [ ] TaskList in tree view matches TaskList in table view (same component)
|
|
134
|
+
- [ ] StatusDot shows correct icon and color for each status (completed=green check, in_progress=blue dot, not_started=gray circle)
|
|
135
|
+
- [ ] ViewToggle switches between table and tree views
|
|
136
|
+
- [ ] View state persists when data updates (expanded milestones stay expanded)
|
|
137
|
+
- [ ] Multiple milestones can be expanded simultaneously
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Expected Output
|
|
142
|
+
|
|
143
|
+
**File Structure**:
|
|
144
|
+
```
|
|
145
|
+
app/
|
|
146
|
+
├── components/
|
|
147
|
+
│ ├── MilestoneTree.tsx (new)
|
|
148
|
+
│ └── StatusDot.tsx (new)
|
|
149
|
+
├── lib/
|
|
150
|
+
│ └── useCollapse.ts (new)
|
|
151
|
+
├── routes/
|
|
152
|
+
│ └── milestones.tsx (updated)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Key Files Created/Modified**:
|
|
156
|
+
- `app/components/MilestoneTree.tsx`: Expandable tree view of milestones and tasks
|
|
157
|
+
- `app/components/StatusDot.tsx`: Small colored status indicator dot
|
|
158
|
+
- `app/lib/useCollapse.ts`: Custom hook for smooth expand/collapse height animation
|
|
159
|
+
- `app/routes/milestones.tsx`: Updated to wire ViewToggle between table and tree views
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Notes
|
|
164
|
+
|
|
165
|
+
- The tree view is intentionally simpler than the table view — it does not support sorting
|
|
166
|
+
- useCollapse measures content height dynamically, so it works with variable-height task lists
|
|
167
|
+
- StatusDot is a smaller, simpler alternative to StatusBadge — used inline in task rows where space is tight
|
|
168
|
+
- Multiple milestones can be expanded at the same time (not accordion behavior)
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
**Next Task**: [Task 9: Implement Search & Filtering](./task-9-implement-search-filtering.md)
|
|
173
|
+
**Related Design Docs**: [Table & Tree Views](../../design/local.table-tree-views.md)
|
|
174
|
+
**Estimated Completion Date**: TBD
|