refactor(CommandPaletteView): extract PaletteResultSection, closeAndReset (P1-23, P3-49, P3-50)

Five near-identical 25-line entity result blocks collapse into one
PaletteResultSection. Extract closeAndReset() callback used in 5 places.
Drop dead fallback: runs.find(...)?.id.slice(0,8) === run.id.slice(0,8).
This commit is contained in:
ZacharyZhang-NY committed 2026-04-16 22:54:53 -04:00
1 parent 3c8a593be7
commit b6e1756f1c
1 file changed
+131 -150
+131 -150
View File
@@ -40,6 +40,54 @@ interface CommandPaletteViewProps {
t: (key: string) => string;
}
interface PaletteResultSectionProps<T extends { id: string }> {
label: string;
items: T[];
keyPrefix: string;
icon: typeof MagnifyingGlass;
selectedPaletteIndex: number;
paletteActionIndex: Map<string, number>;
onSelect: (item: T) => void;
renderPrimary: (item: T) => React.ReactNode;
renderRight: (item: T) => React.ReactNode;
}
function PaletteResultSection<T extends { id: string }>({
label,
items,
keyPrefix,
icon: Icon,
selectedPaletteIndex,
paletteActionIndex,
onSelect,
renderPrimary,
renderRight,
}: PaletteResultSectionProps<T>) {
if (items.length === 0) return null;
return (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{label}</div>
<ListFrame>
{items.map((item) => (
<ListRow
key={item.id}
className={`py-3 ${paletteActionIndex.get(`${keyPrefix}:${item.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => onSelect(item)}
>
<div className="flex items-center justify-between gap-3">
<div className="min-w-0 flex items-center gap-3 text-foreground">
<Icon size={16} />
{renderPrimary(item)}
</div>
{renderRight(item)}
</div>
</ListRow>
))}
</ListFrame>
</>
);
}
export function CommandPaletteView({
commandPaletteOpen,
setCommandPaletteOpen,
@@ -56,13 +104,23 @@ export function CommandPaletteView({
matchedProjects,
hasEntityResults,
paletteActionIndex,
runs,
navigateTo,
panelTransition,
t,
}: CommandPaletteViewProps) {
const paletteQuery = commandPaletteSearch.trim().toLowerCase();
const closeAndReset = () => {
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
};
const selectAndClose = (section: SectionId, entityId?: string) => {
navigateTo(section, entityId);
closeAndReset();
};
return (
<AnimatePresence>
{commandPaletteOpen ? (
@@ -71,7 +129,7 @@ export function CommandPaletteView({
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-50 flex items-start justify-center bg-background/72 px-4 pt-24 backdrop-blur-sm"
onClick={() => { setCommandPaletteOpen(false); setCommandPaletteSearch(""); }}
onClick={closeAndReset}
>
<motion.div
ref={paletteTrapRef}
@@ -114,12 +172,7 @@ export function CommandPaletteView({
<ListRow
key={item.id}
className={`py-3 ${paletteActionIndex.get(`section:${item.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo(item.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
onClick={() => selectAndClose(item.id)}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3 text-foreground">
@@ -136,148 +189,76 @@ export function CommandPaletteView({
{hasEntityResults ? (
<div className="mt-3 space-y-3">
{matchedAgents.length > 0 ? (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("entity.agents")}</div>
<ListFrame>
{matchedAgents.map((agent) => (
<ListRow
key={agent.id}
className={`py-3 ${paletteActionIndex.get(`agent:${agent.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo("agents", agent.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3 text-foreground">
<UsersThree size={16} />
<span className="text-[13px] tracking-[0.005em]">{agent.name}</span>
<span className="text-[11px] text-muted-foreground">{agent.role}</span>
</div>
<StatusPill status={agent.status} />
</div>
</ListRow>
))}
</ListFrame>
</>
) : null}
{matchedTasks.length > 0 ? (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("entity.tasks")}</div>
<ListFrame>
{matchedTasks.map((task) => (
<ListRow
key={task.id}
className={`py-3 ${paletteActionIndex.get(`task:${task.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo("tasks", task.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3 text-foreground">
<ListChecks size={16} />
<span className="text-[13px] tracking-[0.005em]">{task.title}</span>
</div>
<StatusPill status={task.status} />
</div>
</ListRow>
))}
</ListFrame>
</>
) : null}
{matchedRuns.length > 0 ? (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("entity.runs")}</div>
<ListFrame>
{matchedRuns.map((run) => (
<ListRow
key={run.id}
className={`py-3 ${paletteActionIndex.get(`run:${run.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo("runs", run.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
>
<div className="flex items-center justify-between gap-3">
<div className="min-w-0 flex items-center gap-3 text-foreground">
<TerminalWindow size={16} />
<span className="truncate text-[13px] tracking-[0.005em]">
{run.summary || runs.find((entry) => entry.id === run.id)?.id.slice(0, 8) || run.id.slice(0, 8)}
</span>
</div>
<StatusPill status={run.status} />
</div>
</ListRow>
))}
</ListFrame>
</>
) : null}
{matchedGoals.length > 0 ? (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("entity.goals")}</div>
<ListFrame>
{matchedGoals.map((goal) => (
<ListRow
key={goal.id}
className={`py-3 ${paletteActionIndex.get(`goal:${goal.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo("goals", goal.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3 text-foreground">
<Target size={16} />
<span className="text-[13px] tracking-[0.005em]">{goal.title}</span>
</div>
<StatusPill status={goal.status} />
</div>
</ListRow>
))}
</ListFrame>
</>
) : null}
{matchedProjects.length > 0 ? (
<>
<div className="text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{t("entity.projects")}</div>
<ListFrame>
{matchedProjects.map((project) => (
<ListRow
key={project.id}
className={`py-3 ${paletteActionIndex.get(`project:${project.id}`) === selectedPaletteIndex ? "bg-muted" : ""}`}
onClick={() => {
navigateTo("projects", project.id);
setCommandPaletteOpen(false);
setCommandPaletteSearch("");
setSelectedPaletteIndex(0);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3 text-foreground">
<Kanban size={16} />
<span className="text-[13px] tracking-[0.005em]">{project.name}</span>
</div>
<StatusPill status={project.status} />
</div>
</ListRow>
))}
</ListFrame>
</>
) : null}
<PaletteResultSection
label={t("entity.agents")}
items={matchedAgents}
keyPrefix="agent"
icon={UsersThree}
selectedPaletteIndex={selectedPaletteIndex}
paletteActionIndex={paletteActionIndex}
onSelect={(agent) => selectAndClose("agents", agent.id)}
renderPrimary={(agent) => (
<>
<span className="text-[13px] tracking-[0.005em]">{agent.name}</span>
<span className="text-[11px] text-muted-foreground">{agent.role}</span>
</>
)}
renderRight={(agent) => <StatusPill status={agent.status} />}
/>
<PaletteResultSection
label={t("entity.tasks")}
items={matchedTasks}
keyPrefix="task"
icon={ListChecks}
selectedPaletteIndex={selectedPaletteIndex}
paletteActionIndex={paletteActionIndex}
onSelect={(task) => selectAndClose("tasks", task.id)}
renderPrimary={(task) => (
<span className="text-[13px] tracking-[0.005em]">{task.title}</span>
)}
renderRight={(task) => <StatusPill status={task.status} />}
/>
<PaletteResultSection
label={t("entity.runs")}
items={matchedRuns}
keyPrefix="run"
icon={TerminalWindow}
selectedPaletteIndex={selectedPaletteIndex}
paletteActionIndex={paletteActionIndex}
onSelect={(run) => selectAndClose("runs", run.id)}
renderPrimary={(run) => (
<span className="truncate text-[13px] tracking-[0.005em]">
{run.summary || run.id.slice(0, 8)}
</span>
)}
renderRight={(run) => <StatusPill status={run.status} />}
/>
<PaletteResultSection
label={t("entity.goals")}
items={matchedGoals}
keyPrefix="goal"
icon={Target}
selectedPaletteIndex={selectedPaletteIndex}
paletteActionIndex={paletteActionIndex}
onSelect={(goal) => selectAndClose("goals", goal.id)}
renderPrimary={(goal) => (
<span className="text-[13px] tracking-[0.005em]">{goal.title}</span>
)}
renderRight={(goal) => <StatusPill status={goal.status} />}
/>
<PaletteResultSection
label={t("entity.projects")}
items={matchedProjects}
keyPrefix="project"
icon={Kanban}
selectedPaletteIndex={selectedPaletteIndex}
paletteActionIndex={paletteActionIndex}
onSelect={(project) => selectAndClose("projects", project.id)}
renderPrimary={(project) => (
<span className="text-[13px] tracking-[0.005em]">{project.name}</span>
)}
renderRight={(project) => <StatusPill status={project.status} />}
/>
</div>
) : null}