Resolve remaining QA suggestions: shared constants, query tuning, cleanup

- Extract duplicate statusColors/statusLabels to projects/constants.ts
- Add staleTime + select to sidebar tracked projects query to reduce
  refetches and narrow data to only id/name
- Gate TrackedProjectsWidget query on settings being loaded
- Remove unnecessary from_attributes on TrackedTaskResponse schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-02-23 03:10:48 +08:00
parent bb87bd3743
commit c67567e186
6 changed files with 22 additions and 38 deletions

View File

@ -48,5 +48,3 @@ class TrackedTaskResponse(BaseModel):
project_name: str
project_id: int
parent_task_title: Optional[str] = None
model_config = ConfigDict(from_attributes=True)

View File

@ -43,6 +43,7 @@ export default function TrackedProjectsWidget() {
const { data } = await api.get<TrackedTask[]>(`/projects/tracked-tasks?days=${days}`);
return data;
},
enabled: !!settings,
});
if (!tasks || tasks.length === 0) return null;

View File

@ -50,6 +50,8 @@ export default function Sidebar({ collapsed, onToggle, mobileOpen, onMobileClose
const { data } = await api.get<Project[]>('/projects?tracked=true');
return data;
},
staleTime: 60_000,
select: (data) => data.map(({ id, name }) => ({ id, name })),
});
const handleLogout = async () => {

View File

@ -7,30 +7,13 @@ import api from '@/lib/api';
import type { Project } from '@/types';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { statusColors, statusLabels } from './constants';
interface ProjectCardProps {
project: Project;
onEdit: (project: Project) => void;
}
const statusColors: Record<string, string> = {
not_started: 'bg-gray-500/10 text-gray-400 border-gray-500/20',
in_progress: 'bg-purple-500/10 text-purple-400 border-purple-500/20',
completed: 'bg-green-500/10 text-green-400 border-green-500/20',
blocked: 'bg-red-500/10 text-red-400 border-red-500/20',
review: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',
on_hold: 'bg-orange-500/10 text-orange-400 border-orange-500/20',
};
const statusLabels: Record<string, string> = {
not_started: 'Not Started',
in_progress: 'In Progress',
completed: 'Completed',
blocked: 'Blocked',
review: 'Review',
on_hold: 'On Hold',
};
export default function ProjectCard({ project }: ProjectCardProps) {
const navigate = useNavigate();
const queryClient = useQueryClient();

View File

@ -37,24 +37,7 @@ import TaskDetailPanel from './TaskDetailPanel';
import KanbanBoard from './KanbanBoard';
import TaskForm from './TaskForm';
import ProjectForm from './ProjectForm';
const statusColors: Record<string, string> = {
not_started: 'bg-gray-500/10 text-gray-400 border-gray-500/20',
in_progress: 'bg-purple-500/10 text-purple-400 border-purple-500/20',
completed: 'bg-green-500/10 text-green-400 border-green-500/20',
blocked: 'bg-red-500/10 text-red-400 border-red-500/20',
review: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',
on_hold: 'bg-orange-500/10 text-orange-400 border-orange-500/20',
};
const statusLabels: Record<string, string> = {
not_started: 'Not Started',
in_progress: 'In Progress',
completed: 'Completed',
blocked: 'Blocked',
review: 'Review',
on_hold: 'On Hold',
};
import { statusColors, statusLabels } from './constants';
type SortMode = 'manual' | 'priority' | 'due_date';
type ViewMode = 'list' | 'kanban';

View File

@ -0,0 +1,17 @@
export const statusColors: Record<string, string> = {
not_started: 'bg-gray-500/10 text-gray-400 border-gray-500/20',
in_progress: 'bg-purple-500/10 text-purple-400 border-purple-500/20',
completed: 'bg-green-500/10 text-green-400 border-green-500/20',
blocked: 'bg-red-500/10 text-red-400 border-red-500/20',
review: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',
on_hold: 'bg-orange-500/10 text-orange-400 border-orange-500/20',
};
export const statusLabels: Record<string, string> = {
not_started: 'Not Started',
in_progress: 'In Progress',
completed: 'Completed',
blocked: 'Blocked',
review: 'Review',
on_hold: 'On Hold',
};