feat(phase0+1): wire URL context to ContextualRightPanel
Phase 0: - UnifiedShell: pass blockedOnly to SocialPage; wire TopBar with live counts - thread-drawer: show real issue.status instead of hardcoded "In Progress" - social-page: fix onJumpToActivity to open right panel (not dead ?view=activity) Phase 1: - contextual-right-panel: add taskId branch (ThreadDrawer embedded) and swarmId branch (MissionInspector via SwarmIdBranch inner component); ActivityPanel remains the no-selection fallback All 207 tests pass; no new typecheck errors. Closes beadboard-r1i (Phase 1: Contextual Right Panel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fccb2dede7
commit
7d37d02af1
6 changed files with 731 additions and 237 deletions
|
|
@ -4,14 +4,19 @@ import React from 'react';
|
|||
import type { BeadIssue } from '../../lib/types';
|
||||
import { ActivityPanel } from './activity-panel';
|
||||
import { SwarmCommandFeed } from './swarm-command-feed';
|
||||
import { ThreadDrawer } from '../shared/thread-drawer';
|
||||
import { MissionInspector } from '../mission/mission-inspector';
|
||||
import { useSwarmList } from '../../hooks/use-swarm-list';
|
||||
|
||||
export interface ContextualRightPanelProps {
|
||||
epicId?: string | null;
|
||||
taskId?: string | null;
|
||||
swarmId?: string | null;
|
||||
issues: BeadIssue[];
|
||||
projectRoot: string;
|
||||
}
|
||||
|
||||
export function ContextualRightPanel({ epicId, issues, projectRoot }: ContextualRightPanelProps) {
|
||||
export function ContextualRightPanel({ epicId, taskId, swarmId, issues, projectRoot }: ContextualRightPanelProps) {
|
||||
if (epicId) {
|
||||
return (
|
||||
<SwarmCommandFeed
|
||||
|
|
@ -22,6 +27,31 @@ export function ContextualRightPanel({ epicId, issues, projectRoot }: Contextual
|
|||
);
|
||||
}
|
||||
|
||||
if (taskId) {
|
||||
const selectedIssue = issues.find(i => i.id === taskId) ?? null;
|
||||
return (
|
||||
<ThreadDrawer
|
||||
isOpen={true}
|
||||
embedded={true}
|
||||
onClose={() => {}}
|
||||
title={selectedIssue?.title ?? taskId}
|
||||
id={taskId}
|
||||
issue={selectedIssue}
|
||||
projectRoot={projectRoot}
|
||||
onIssueUpdated={async () => {}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (swarmId) {
|
||||
return (
|
||||
<SwarmIdBranch
|
||||
swarmId={swarmId}
|
||||
projectRoot={projectRoot}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Fallback to Global feed
|
||||
return (
|
||||
<ActivityPanel
|
||||
|
|
@ -30,3 +60,24 @@ export function ContextualRightPanel({ epicId, issues, projectRoot }: Contextual
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Inner component so hooks can be called conditionally via component boundary
|
||||
function SwarmIdBranch({ swarmId, projectRoot }: { swarmId: string; projectRoot: string }) {
|
||||
const { swarms } = useSwarmList(projectRoot);
|
||||
const swarm = swarms.find(s => s.swarmId === swarmId);
|
||||
// Fall back to swarmId as title while swarm list loads
|
||||
const missionTitle = swarm?.title ?? swarmId;
|
||||
// TODO (follow-up): populate assignedAgents from swarm.agents once agent-registry is wired
|
||||
const assignedAgents = swarm?.agents ?? [];
|
||||
|
||||
return (
|
||||
<MissionInspector
|
||||
missionId={swarmId}
|
||||
missionTitle={missionTitle}
|
||||
projectRoot={projectRoot}
|
||||
assignedAgents={assignedAgents}
|
||||
onClose={() => {}}
|
||||
onAssign={async () => {}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue