mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
feat: add command palette and dashboard view components
- Introduced a command palette for enhanced navigation and command execution. - Added a new dashboard view with project management features, including project cards and an empty state for new users. - Updated routing to include the new dashboard view and integrated it with the existing layout. - Enhanced the app store to manage pinned projects and GitHub cache for issues and pull requests. These changes improve user experience by streamlining project management and navigation within the application.
This commit is contained in:
128
apps/ui/src/components/layout/top-bar/pinned-projects.tsx
Normal file
128
apps/ui/src/components/layout/top-bar/pinned-projects.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useAppStore } from '@/store/app-store';
|
||||
import type { Project } from '@/lib/electron';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuSeparator,
|
||||
ContextMenuTrigger,
|
||||
} from '@/components/ui/context-menu';
|
||||
import { Star, Settings, Trash2 } from 'lucide-react';
|
||||
|
||||
interface PinnedProjectsProps {
|
||||
pinnedProjects: Project[];
|
||||
currentProject: Project | null;
|
||||
}
|
||||
|
||||
export function PinnedProjects({ pinnedProjects, currentProject }: PinnedProjectsProps) {
|
||||
const navigate = useNavigate();
|
||||
const { setCurrentProject, unpinProject, moveProjectToTrash } = useAppStore();
|
||||
|
||||
const handleProjectClick = useCallback(
|
||||
(project: Project) => {
|
||||
setCurrentProject(project);
|
||||
navigate({ to: '/board' });
|
||||
},
|
||||
[setCurrentProject, navigate]
|
||||
);
|
||||
|
||||
const handleUnpin = useCallback(
|
||||
(projectId: string) => {
|
||||
unpinProject(projectId);
|
||||
},
|
||||
[unpinProject]
|
||||
);
|
||||
|
||||
const handleProjectSettings = useCallback(
|
||||
(project: Project) => {
|
||||
setCurrentProject(project);
|
||||
navigate({ to: '/settings' });
|
||||
},
|
||||
[setCurrentProject, navigate]
|
||||
);
|
||||
|
||||
const handleRemoveProject = useCallback(
|
||||
(projectId: string) => {
|
||||
moveProjectToTrash(projectId);
|
||||
},
|
||||
[moveProjectToTrash]
|
||||
);
|
||||
|
||||
if (pinnedProjects.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<div className="flex items-center gap-1">
|
||||
{pinnedProjects.map((project) => {
|
||||
const isActive = currentProject?.id === project.id;
|
||||
// TODO: Get running agent count from store
|
||||
const runningCount = 0;
|
||||
|
||||
return (
|
||||
<ContextMenu key={project.id}>
|
||||
<ContextMenuTrigger>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={() => handleProjectClick(project)}
|
||||
className={cn(
|
||||
'flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium',
|
||||
'transition-all duration-200',
|
||||
'hover:bg-accent/50',
|
||||
isActive && 'bg-accent text-accent-foreground',
|
||||
!isActive && 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
<span className="truncate max-w-[120px]">{project.name}</span>
|
||||
{runningCount > 0 && (
|
||||
<span className="flex h-2 w-2 rounded-full bg-green-500 animate-pulse" />
|
||||
)}
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" className="text-xs">
|
||||
<div className="font-medium">{project.name}</div>
|
||||
<div className="text-muted-foreground">{project.path}</div>
|
||||
{runningCount > 0 && (
|
||||
<div className="text-green-500 mt-1">
|
||||
{runningCount} agent{runningCount > 1 ? 's' : ''} running
|
||||
</div>
|
||||
)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem onClick={() => handleProjectClick(project)}>Open</ContextMenuItem>
|
||||
<ContextMenuSeparator />
|
||||
<ContextMenuItem onClick={() => handleUnpin(project.id)}>
|
||||
<Star className="h-4 w-4 mr-2" />
|
||||
Unpin from bar
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleProjectSettings(project)}>
|
||||
<Settings className="h-4 w-4 mr-2" />
|
||||
Project Settings
|
||||
</ContextMenuItem>
|
||||
<ContextMenuSeparator />
|
||||
<ContextMenuItem
|
||||
onClick={() => handleRemoveProject(project.id)}
|
||||
className="text-destructive focus:text-destructive"
|
||||
>
|
||||
<Trash2 className="h-4 w-4 mr-2" />
|
||||
Remove Project
|
||||
</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Separator after pinned projects */}
|
||||
<div className="h-6 w-px bg-border/60 mx-2" />
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user