import { useEffect, useState } from 'react'; import { api } from '@renderer/api'; import { buildMembersFromDrafts, createMemberDraftsFromInputs, filterEditableMemberInputs, MembersEditorSection, validateMemberNameInline, } from '@renderer/components/team/members/MembersEditorSection'; import { Button } from '@renderer/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@renderer/components/ui/dialog'; import { getTeamColorSet, getThemedBadge } from '@renderer/constants/teamColors'; import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer'; import { useTheme } from '@renderer/hooks/useTheme'; import { cn } from '@renderer/lib/utils'; import { Loader2 } from 'lucide-react'; import type { ResolvedTeamMember } from '@shared/types'; const TEAM_COLOR_NAMES = [ 'blue', 'green', 'red', 'yellow', 'purple', 'cyan', 'orange', 'pink', ] as const; interface EditTeamDialogProps { open: boolean; teamName: string; currentName: string; currentDescription: string; currentColor: string; currentMembers: ResolvedTeamMember[]; isTeamAlive?: boolean; projectPath?: string | null; onClose: () => void; onSaved: () => void; } function membersToDrafts(members: ResolvedTeamMember[]) { return createMemberDraftsFromInputs(filterEditableMemberInputs(members)); } export const EditTeamDialog = ({ open, teamName, currentName, currentDescription, currentColor, currentMembers, isTeamAlive = false, projectPath, onClose, onSaved, }: EditTeamDialogProps): React.JSX.Element => { const { isLight } = useTheme(); const [name, setName] = useState(currentName); const [description, setDescription] = useState(currentDescription); const [color, setColor] = useState(currentColor); const [members, setMembers] = useState(() => membersToDrafts(currentMembers)); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); useFileListCacheWarmer(projectPath ?? null); useEffect(() => { if (open) { setName(currentName); setDescription(currentDescription); setColor(currentColor); setMembers(membersToDrafts(currentMembers)); setError(null); } }, [open, currentName, currentDescription, currentColor, currentMembers]); const handleSave = (): void => { if (!name.trim()) { setError('Team name cannot be empty'); return; } const builtMembers = buildMembersFromDrafts(members); setSaving(true); setError(null); void (async () => { try { await api.teams.updateConfig(teamName, { name: name.trim(), description: description.trim(), color, }); await api.teams.replaceMembers(teamName, { members: builtMembers }); onSaved(); onClose(); } catch (e) { setError(e instanceof Error ? e.message : 'Failed to save'); } finally { setSaving(false); } })(); }; return ( !nextOpen && onClose()}> Edit Team Change team name, description and color
setName(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && !saving && name.trim()) handleSave(); }} className="w-full rounded-md border border-[var(--color-border)] bg-[var(--color-surface)] px-3 py-1.5 text-sm text-[var(--color-text)] outline-none focus:border-[var(--color-border-emphasis)]" placeholder="Team name" />