feat(KB-048): add collapsible list sections to dashboard

- Add section expansion state management with localStorage persistence
- Update section headers with chevron toggle controls
- Implement conditional task row rendering based on section state
- Add Expand All / Collapse All toolbar controls
- Add CSS styles for chevron rotation animation and section headers
- Add comprehensive tests for collapsible section behavior
This commit is contained in:
gsxdsm
2026-03-29 19:51:41 -07:00
parent 6a00c56217
commit a53e4c1420
111 changed files with 23013 additions and 2936 deletions

View File

@@ -1,6 +1,8 @@
import { resolveDependencyOrder, type TaskStore, type Task } from "@kb/core";
import type { AgentSemaphore } from "./concurrency.js";
import { schedulerLog } from "./logger.js";
import type { PrMonitor } from "./pr-monitor.js";
import { getCurrentGitHubRepo } from "./github.js";
/**
* Check whether two sets of file scope paths overlap.
@@ -53,6 +55,8 @@ export interface SchedulerOptions {
onSchedule?: (task: Task) => void;
/** Called when a task is blocked by deps */
onBlocked?: (task: Task, blockedBy: string[]) => void;
/** Optional PR monitor for tracking in-review PRs */
prMonitor?: PrMonitor;
}
/**
@@ -111,6 +115,48 @@ export class Scheduler {
this.schedule();
}
});
/**
* PR Monitoring: Start monitoring when a task moves to "in-review",
* stop monitoring when it moves out.
*/
this.store.on("task:moved", ({ task, to }) => {
if (!this.options.prMonitor) return;
if (to === "in-review" && task.prInfo) {
// Start monitoring existing PR
const repo = getCurrentGitHubRepo(this.store.getRootDir());
if (repo) {
this.options.prMonitor.startMonitoring(task.id, repo.owner, repo.repo, task.prInfo);
}
} else if (task.column === "in-review" && to !== "in-review") {
// Task moved out of in-review, stop monitoring
this.options.prMonitor.stopMonitoring(task.id);
// If task has a closed/merged PR, check for unaddressed feedback
if (task.prInfo && (task.prInfo.status === "closed" || task.prInfo.status === "merged")) {
// This would need the tracked PR data - handled by PrMonitor/PrCommentHandler
}
}
});
/**
* PR Monitoring: Start monitoring when PR is linked to an in-review task.
*/
this.store.on("task:updated", (task) => {
if (!this.options.prMonitor) return;
if (task.column !== "in-review") return;
if (!task.prInfo) return;
// Check if we're already monitoring this task
const tracked = this.options.prMonitor.getTrackedPrs();
if (!tracked.has(task.id)) {
const repo = getCurrentGitHubRepo(this.store.getRootDir());
if (repo) {
this.options.prMonitor.startMonitoring(task.id, repo.owner, repo.repo, task.prInfo);
}
}
});
}
start(): void {
@@ -131,6 +177,10 @@ export class Scheduler {
this.pollInterval = null;
this.activePollMs = null;
}
// Stop all PR monitoring when scheduler shuts down
if (this.options.prMonitor) {
this.options.prMonitor.stopAll();
}
schedulerLog.log("Stopped");
}