fix: null-safe formulas, constrain assign row to card, fix TopBar dialog mounting

Co-Authored-By: Oz <oz-agent@warp.dev>
This commit is contained in:
zenchantlive 2026-03-01 17:30:01 -08:00
parent 300d5b13aa
commit b82c176e12
3 changed files with 6 additions and 20 deletions

View file

@ -91,7 +91,6 @@ export function TopBar({
}: TopBarProps) { }: TopBarProps) {
const { leftPanel, toggleLeftPanel, rightPanel, toggleRightPanel, blockedOnly, toggleBlockedOnly } = useUrlState(); const { leftPanel, toggleLeftPanel, rightPanel, toggleRightPanel, blockedOnly, toggleBlockedOnly } = useUrlState();
const { isDesktop } = useResponsive(); const { isDesktop } = useResponsive();
const [showLaunchSwarm, setShowLaunchSwarm] = useState(false);
return ( return (
<header className="flex h-[var(--topbar-height)] items-center justify-between border-b border-[var(--border-strong)] bg-[var(--surface-elevated)]" data-testid="top-bar"> <header className="flex h-[var(--topbar-height)] items-center justify-between border-b border-[var(--border-strong)] bg-[var(--surface-elevated)]" data-testid="top-bar">
@ -152,14 +151,7 @@ export function TopBar({
</button> </button>
{projectRoot && ( {projectRoot && (
<button <LaunchSwarmDialog projectRoot={projectRoot} />
type="button"
onClick={() => setShowLaunchSwarm(true)}
className="inline-flex items-center gap-2 rounded-xl border border-emerald-500/20 bg-emerald-500/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.11em] text-emerald-400 transition-colors hover:bg-emerald-500/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent-info)]"
>
<Rocket className="h-3.5 w-3.5" aria-hidden="true" />
Launch Swarm
</button>
)} )}
<button <button
@ -199,12 +191,6 @@ export function TopBar({
</span> </span>
</div> </div>
{showLaunchSwarm && projectRoot && (
<LaunchSwarmDialog
projectRoot={projectRoot}
onSuccess={() => setShowLaunchSwarm(false)}
/>
)}
</header> </header>
); );
} }

View file

@ -187,11 +187,11 @@ export function SocialCard({
</div> </div>
{showAssign && ( {showAssign && (
<div className="mt-2 flex gap-2 items-center" onClick={(e) => e.stopPropagation()}> <div className="mt-2 flex gap-2 items-center overflow-hidden" onClick={(e) => e.stopPropagation()}>
<select <select
value={selectedArchetype ?? ''} value={selectedArchetype ?? ''}
onChange={(e) => setSelectedArchetype(e.target.value || null)} onChange={(e) => setSelectedArchetype(e.target.value || null)}
className="flex-1 text-xs border border-[var(--border-subtle)] rounded-md px-2 py-1.5 bg-[var(--surface-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--accent-info)]" className="min-w-0 flex-1 text-xs border border-[var(--border-subtle)] rounded-md px-2 py-1.5 bg-[var(--surface-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--accent-info)]"
> >
<option value="" disabled>Select agent role...</option> <option value="" disabled>Select agent role...</option>
{archetypes.map((a) => ( {archetypes.map((a) => (
@ -204,10 +204,10 @@ export function SocialCard({
await handleAssign(data.id); await handleAssign(data.id);
}} }}
disabled={!selectedArchetype || isAssigning || assignSuccess} disabled={!selectedArchetype || isAssigning || assignSuccess}
className={`px-3 py-1.5 text-xs font-semibold rounded-md transition-colors disabled:opacity-50 flex items-center gap-1 ${assignSuccess ? 'bg-[var(--accent-success)] text-white' : 'bg-[var(--accent-info)] text-white hover:bg-[var(--accent-info)]/90'}`} className={`flex-shrink-0 px-2.5 py-1.5 text-xs font-semibold rounded-md transition-colors disabled:opacity-50 flex items-center gap-1 ${assignSuccess ? 'bg-[var(--accent-success)] text-white' : 'bg-[var(--accent-info)] text-white hover:bg-[var(--accent-info)]/90'}`}
> >
<UserPlus className="w-3 h-3" /> <UserPlus className="w-3 h-3" />
{isAssigning ? 'Assigning...' : assignSuccess ? 'Assigned!' : 'Assign'} {isAssigning ? '...' : assignSuccess ? '' : 'Assign'}
</button> </button>
</div> </div>
)} )}

View file

@ -47,7 +47,7 @@ export function LaunchSwarmDialog({ projectRoot, onSuccess }: LaunchSwarmDialogP
const res = await fetch(`/api/swarm/formulas?projectRoot=${encodeURIComponent(projectRoot)}`); const res = await fetch(`/api/swarm/formulas?projectRoot=${encodeURIComponent(projectRoot)}`);
const json = await res.json(); const json = await res.json();
if (json.ok) { if (json.ok) {
setFormulas(json.data); setFormulas(json.data ?? []);
} else { } else {
setError(json.error); setError(json.error);
} }