feat(KB-502): add dashboard multi-project UX with overview, drill-down, and setup wizard
- Add Project Overview page with responsive grid and health metrics - Add Project selector dropdown for quick context switching - Add Project drill-down with back navigation to overview - Add Setup wizard with auto-detection and manual entry flows - Add Global activity feed with project attribution badges - Add Project health polling (active tasks, agents, completion counts) - Add Empty states and loading skeletons for better UX - Add Keyboard navigation support (arrow keys, enter, escape) - Add LocalStorage persistence for wizard state and view preferences
This commit is contained in:
@@ -43,6 +43,10 @@ function truncatePath(path: string, maxLength: number = 40): string {
|
||||
return `${start}...${end}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two sets of ProjectCardProps for memo equality.
|
||||
* Checks project properties and health metrics to determine if re-render is needed.
|
||||
*/
|
||||
function areProjectCardPropsEqual(previous: ProjectCardProps, next: ProjectCardProps): boolean {
|
||||
if (previous.project.id !== next.project.id) return false;
|
||||
if (previous.project.status !== next.project.status) return false;
|
||||
@@ -66,6 +70,28 @@ function areProjectCardPropsEqual(previous: ProjectCardProps, next: ProjectCardP
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Individual project card component showing project status, health metrics, and actions.
|
||||
*
|
||||
* Displays:
|
||||
* - Project name and truncated path
|
||||
* - Status badge (active, paused, errored, initializing)
|
||||
* - Health metrics: active tasks, running agents, completed tasks
|
||||
* - Last activity timestamp
|
||||
* - Action buttons: Open, Pause/Resume, Remove
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <ProjectCard
|
||||
* project={registeredProject}
|
||||
* health={projectHealth}
|
||||
* onSelect={(p) => setCurrentProject(p)}
|
||||
* onPause={(p) => pauseProject(p.id)}
|
||||
* onResume={(p) => resumeProject(p.id)}
|
||||
* onRemove={(p) => unregisterProject(p.id)}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
function ProjectCardInner({
|
||||
project,
|
||||
health,
|
||||
|
||||
Reference in New Issue
Block a user