fix: always enable SSE auto-refresh on kanban page

Previously SSE was only enabled in single project mode (allowMutations).
Now auto-refresh works in all modes including aggregate.
This commit is contained in:
zenchantlive 2026-02-13 14:51:31 -08:00
parent ad7a7b9b00
commit 4f8f3006e9
7 changed files with 209 additions and 28 deletions

View file

@ -553,14 +553,14 @@ export function DependencyGraphPage({
if (dep.type !== 'blocks') continue;
// Avoid self-loops
if (issue.id === dep.target) continue;
const edgeId = `${issue.id}:blocks:${dep.target}`;
const edgeId = `${dep.target}:blocks:${issue.id}`;
const linkedToSelection = selectedId ? issue.id === selectedId || dep.target === selectedId : false;
graphEdges.push({
id: edgeId,
source: issue.id,
target: dep.target,
source: dep.target,
target: issue.id,
className: linkedToSelection ? 'workflow-edge-selected' : 'workflow-edge-muted',
animated: linkedToSelection,
label: 'BLOCKS',

View file

@ -188,10 +188,8 @@ export function KanbanPage({
}
}, [projectRoot]);
// Auto-refresh when issues change on disk (SSE)
useEffect(() => {
if (!allowMutations) {
return;
}
const source = new EventSource(`/api/events?projectRoot=${encodeURIComponent(projectRoot)}`);
const onIssues = () => {
void refreshIssues({ silent: true });
@ -203,7 +201,7 @@ export function KanbanPage({
source.removeEventListener('issues', onIssues as EventListener);
source.close();
};
}, [allowMutations, projectRoot, refreshIssues]);
}, [projectRoot, refreshIssues]);
const mutateStatus = async (issue: BeadIssue, targetStatus: KanbanStatus) => {
if (!allowMutations) {

View file

@ -100,7 +100,12 @@ export function buildGraphModel(issues: BeadIssue[], options: BuildGraphModelOpt
continue;
}
const edgeKey = `${issue.id}::${dependency.type}::${dependency.target}`;
// Beads "blocks" dependency means: issue depends on target, so target blocks issue.
// Normalize graph direction to blocker -> blocked for all blocker analytics and UI signals.
const source = dependency.type === 'blocks' ? dependency.target : issue.id;
const target = dependency.type === 'blocks' ? issue.id : dependency.target;
const edgeKey = `${source}::${dependency.type}::${target}`;
if (edgeKeys.has(edgeKey)) {
diagnostics.droppedDuplicates += 1;
continue;
@ -108,8 +113,8 @@ export function buildGraphModel(issues: BeadIssue[], options: BuildGraphModelOpt
edgeKeys.add(edgeKey);
edges.push({
source: issue.id,
target: dependency.target,
source,
target,
type: dependency.type,
});
}