feat(KB-129): dashboard performance optimizations
- Fix SSE hook cleanup to prevent memory leaks and stale connections - Cap agent log memory and optimize batch log processing - Memoize Board, Column, and TaskCard with custom comparator to reduce re-renders - Stabilize column task arrays and preserve pagination across live updates - Add TaskCardBadge component for PR/issue state display - Remove deprecated GitHub polling code and archive functionality from core store
This commit is contained in:
@@ -562,6 +562,17 @@ describe("TaskStore", () => {
|
||||
expect(tasks).toHaveLength(2);
|
||||
expect(tasks.map((t) => t.id).sort()).toEqual(["KB-001", "PROJ-002"]);
|
||||
});
|
||||
|
||||
it("supports pagination with limit and offset", async () => {
|
||||
await store.createTask({ description: "Task 1" });
|
||||
await store.createTask({ description: "Task 2" });
|
||||
await store.createTask({ description: "Task 3" });
|
||||
|
||||
const paged = await store.listTasks({ limit: 1, offset: 1 });
|
||||
|
||||
expect(paged).toHaveLength(1);
|
||||
expect(paged[0].id).toBe("KB-002");
|
||||
});
|
||||
});
|
||||
|
||||
describe("pauseTask", () => {
|
||||
|
||||
@@ -367,7 +367,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
return { ...task, prompt };
|
||||
}
|
||||
|
||||
async listTasks(): Promise<Task[]> {
|
||||
async listTasks(options?: { limit?: number; offset?: number }): Promise<Task[]> {
|
||||
if (!existsSync(this.tasksDir)) return [];
|
||||
|
||||
const entries = await readdir(this.tasksDir, { withFileTypes: true });
|
||||
@@ -383,13 +383,22 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
}
|
||||
}
|
||||
|
||||
return tasks.sort((a, b) => {
|
||||
const sorted = tasks.sort((a, b) => {
|
||||
const cmp = a.createdAt.localeCompare(b.createdAt);
|
||||
if (cmp !== 0) return cmp;
|
||||
const aNum = parseInt(a.id.slice(a.id.lastIndexOf("-") + 1), 10) || 0;
|
||||
const bNum = parseInt(b.id.slice(b.id.lastIndexOf("-") + 1), 10) || 0;
|
||||
return aNum - bNum;
|
||||
});
|
||||
|
||||
const offset = Math.max(0, options?.offset ?? 0);
|
||||
const limit = options?.limit;
|
||||
|
||||
if (limit === undefined) {
|
||||
return sorted.slice(offset);
|
||||
}
|
||||
|
||||
return sorted.slice(offset, offset + Math.max(0, limit));
|
||||
}
|
||||
|
||||
async moveTask(id: string, toColumn: Column): Promise<Task> {
|
||||
|
||||
Reference in New Issue
Block a user