Build & Release / Lint & Typecheck (push) Successful in 38s
Build & Release / Unit Tests (push) Successful in 31s
Build & Release / Windows (arm64) (push) Failing after 11s
Build & Release / Windows (x64) (push) Failing after 27s
Build & Release / Linux (arm64) (push) Canceled after 0s
Build & Release / Linux (x64) (push) Canceled after 0s
Build & Release / Publish Release (push) Canceled after 0s
Build & Release / macOS (arm64) (push) Canceled after 0s
Build & Release / macOS (x64) (push) Canceled after 0s
- Align Electron CSS with website design schema (Inter font, #FBFAF5/#191919 palette, #213448/#94B4C1 accent) - Generate proper app icons from logo.svg via cairosvg (no more Pillow ladder) - Square bg icons for Electron/tray (Apple HIG — OS applies squircle mask) - Circle bg icons for website favicon only - Add scrolling ASCII agent-activity animation to onboarding hero left panel - Remove dock.setIcon() — let macOS use bundle .icns with system mask - Fix goal title overflow with min-w-0 for flex truncation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { CheckCircle } from "@phosphor-icons/react";
|
|
import type { AgentRecord, GoalRecord } from "@shared/types";
|
|
import { EmptyState, ListFrame, ListRow, StatusPill } from "../ui";
|
|
import { useT } from "../../i18n";
|
|
|
|
export function GoalList({
|
|
goals,
|
|
agents,
|
|
selectedGoalId,
|
|
onSelect,
|
|
}: {
|
|
goals: GoalRecord[];
|
|
agents: AgentRecord[];
|
|
selectedGoalId: string | null;
|
|
onSelect: (goalId: string) => void;
|
|
}) {
|
|
const t = useT();
|
|
if (goals.length === 0) {
|
|
return <EmptyState title={t("org.noGoalsYet")} detail={t("org.noGoalsDetail")} />;
|
|
}
|
|
return (
|
|
<ListFrame>
|
|
{goals.map((goal) => {
|
|
const isSelected = goal.id === selectedGoalId;
|
|
const parentGoal = goal.parentId ? goals.find((g) => g.id === goal.parentId) : null;
|
|
const ownerAgent = goal.ownerAgentId
|
|
? agents.find((a) => a.id === goal.ownerAgentId)
|
|
: null;
|
|
return (
|
|
<ListRow
|
|
key={goal.id}
|
|
onClick={() => onSelect(goal.id)}
|
|
className={`cursor-pointer transition-colors duration-100 ${isSelected ? "bg-[color:var(--accent-soft)]" : "hover:bg-[color:var(--panel-soft)]"}`}
|
|
>
|
|
<div className="mb-2 flex items-center justify-between gap-3">
|
|
<div className="flex min-w-0 items-center gap-2">
|
|
{isSelected && (
|
|
<CheckCircle size={16} weight="fill" className="shrink-0 text-[color:var(--accent)]" />
|
|
)}
|
|
<div className="truncate text-[14px] font-semibold text-[color:var(--text)]">{goal.title}</div>
|
|
</div>
|
|
<StatusPill status={goal.status} />
|
|
</div>
|
|
<div className="line-clamp-2 text-[13px] text-[color:var(--muted)]">{goal.description}</div>
|
|
<div className="mt-1 flex gap-4 text-[11px] text-[color:var(--muted)]">
|
|
{parentGoal && <span>Parent: {parentGoal.title}</span>}
|
|
{ownerAgent && <span>Owner: {ownerAgent.name}</span>}
|
|
</div>
|
|
</ListRow>
|
|
);
|
|
})}
|
|
</ListFrame>
|
|
);
|
|
}
|