feat(ui): unified sidebar + project cache + homepage with Issues/Iterations#184
Open
eipasteur wants to merge 12 commits into
Open
feat(ui): unified sidebar + project cache + homepage with Issues/Iterations#184eipasteur wants to merge 12 commits into
eipasteur wants to merge 12 commits into
Conversation
Replace sprint-centric sidebar with a global navigation layout that shows all projects with their current agent status. The sidebar is now always visible, providing quick access to projects, observability, and backlog views. - Add stale-while-revalidate cache for projects and sprint lists - Show running/waiting agent indicators per project in sidebar - Activity panel auto-opens only when inside a sprint - Add Collapsible UI component (radix-ui)
- AppShell: ActivityPanel resolves projectId via useParams, no need to pass it down - useProjectsCache: remove unused useState import
… Backlog link - Dashboard now consumes the shared cache instead of fetching projects directly. This removes a duplicate request at startup (Dashboard + AppSidebar were both fetching) and lets create/delete actions invalidate a single source of truth. - Remove the Backlog navigation entry from AppSidebar: there is no /backlog route in this codebase, the button was dead.
Refactor /project/:projectId to act as a true project landing page, not a sprint-centric view. The page now: - Reads project + sprints from useProjectsCache (shared with sidebar and dashboard) — single fetch path, no more duplicate requests when navigating between Dashboard and Project. - Subscribes to sprint events via useSprintEvents on the latest sprint, so agent status changes appear in real time without manual refresh. - Renders a Live badge while an agent is running or waiting on the latest sprint, plus per-sprint status icons in the iteration list. - Splits sprints into 'Active' and 'Past' (collapsible) so the user always sees what is happening now first. - Embeds Jan's IssueListPanel side-by-side with the iteration list, so GitHub issues drive sprint creation directly from this page.
…on button - Wrap IssueListPanel under an 'Issues' uppercase header that mirrors the existing 'Iterations' header, so both columns line up at the same vertical position. - Add a primary 'Start' button to the right of the Iterations title with a Dialog that asks for the iteration name and calls sprintsService.create. On success, refresh the cached sprint list. - Drop the hard-coded mt-6 from IssueListPanel's outer Card; the parent layout now owns vertical spacing, so the component composes cleanly under any header.
…spacing The two columns were drifting vertically because their headers had different heights (the Issues h3 was its natural height, while the Iterations row was a flex container sized by the Start button). - Wrap both titles in 'flex items-center justify-between h-7' so they share the same fixed height as the Start button. - Reduce the column space-y from 4 to 2 so the title sits closer to the panel underneath.
PR #176 migrated lambda/github from CommonJS (require('./shared/...')) to ESM (import '../shared/response.js'), but the Terraform packaging copied shared/ at the same level as index.js in the zip. At runtime, '../shared/response.js' resolved to /var/shared/response.js (one level above /var/task/), which does not exist, causing ERR_MODULE_NOT_FOUND on every invocation. Apply the same pattern as PR #180 (github-issues): build the lambda with esbuild via the npm workspace and zip the .build output. esbuild inlines the shared/ modules at build time, eliminating runtime path resolution. - terraform/modules/api/lambda/main.tf: - Replace npm_requirements + prefix_in_zip='shared' with the build/:zip pattern, mirroring github_issues_lambda - Bump runtime to nodejs24.x for consistency with the build target (esbuild --target=node24, package.json already targets node24) Tests (153 unit tests across 7 files) continue to pass since they import '../index.js' which resolves to lambda/github/index.js, whose original '../shared/response.js' import resolves correctly inside the source tree at lambda/shared/response.js (the same path esbuild uses to bundle). Closes the runtime regression introduced in #176.
Two layered runtime regressions blocked /api/github/* on staging: 1. PR #176 migrated lambda/github from CommonJS to ESM but the Terraform packaging used npm_requirements + prefix_in_zip='shared'. The ESM resolver dereferenced '../shared/response.js' to /var/shared/... (one level above /var/task/), which doesn't exist, throwing ERR_MODULE_NOT_FOUND on every cold start. 2. shared/git-token.js is CommonJS and does require('@aws-sdk/client-ssm') at the module top level. esbuild bundles a CJS shim around it, but the Node.js ESM runtime rejects the resulting dynamic require: 'Dynamic require of @aws-sdk/client-ssm is not supported'. Fix: - terraform/modules/api/lambda/main.tf: switch github_lambda from npm_requirements to the build/:zip pattern (mirroring github_issues per PR #180), bumping runtime to nodejs24.x to match the esbuild --target=node24 the workspace already uses. - lambda/github/index.js: inline resolveGitToken locally, mirroring the exact pattern adopted by lambda/github-issues. shared/response.js remains imported because esbuild can statically bundle it without hitting a dynamic require (it has no top-level require of an external package). Validated end-to-end on staging: - terraform apply succeeded (no drift) - aws lambda invoke returns statusCode 200 with valid JSON body ({connected: false}) for /api/github/status - 153 unit tests across the repo continue to pass Closes the runtime regression introduced in #176.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refonte de l'expérience utilisateur autour des projets : sidebar globale avec status dots, cache stale-while-revalidate pour projects + sprints, et project homepage qui aligne Issues (via #171) et Iterations en colonnes parallèles.
Components
hooks/useProjectsCache.ts— stale-while-revalidate cacheuseSyncExternalStorepattern, projects cached 120s (TTL) with auto-refresh, sprints cached 60s per-project./api/projectscalls when the user navigates between sidebar entries; hot-tab returns to a stale view immediately while a background refresh validates.Layout (
AppShell+AppSidebar)radix-ui).useProjectSprintsCacheto pre-warm sprint panels and auto-opens the ActivityPanel when a project is selected.pages/Project.tsx— project homepageIssueListPanelfrom Feature/GitHub issue integration #171) and Iterations.h-7height + matchingspace-y-2so columns line up.useProjectSprintsCache— sprint cards reflect agent state in real time without polling the network.pages/Dashboard.tsxuseProjectsCacheinstead of fetching directly. Dashboard project cards now show repo-count badges (forward-compatible with feat(multi-repo): support multiple repositories per project (backend + UI) #183 multi-repo).IssueListPanel(Jan's #171)mt-6margin so the parent (Project page) controls spacing — keeps the layout decision where it belongs.Stacked on
Includes #182 (esbuild fix). Merge #182 first; this branch will rebase cleanly.
Validation
npm run buildcleanrefresh()callOut of scope