mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-06-13 22:34:06 +00:00
fix(webui): sort Chats group among projects by recency
In project-based sidebar grouping, the "Chats" section (non-project conversations) was always appended at the end regardless of its most recent updated_at. This meant the newest conversation could appear below older project groups. Move Chats group insertion before the global sort, compute its updatedAt from its most recently updated session, and sort all groups together by updatedAt descending.
This commit is contained in:
parent
edf34d857a
commit
a70871679c
@ -281,19 +281,18 @@ function groupSessionsByProject(
|
||||
),
|
||||
}));
|
||||
|
||||
groups.sort((a, b) => {
|
||||
const timeOrder = dateToTime(b.updatedAt) - dateToTime(a.updatedAt);
|
||||
if (timeOrder !== 0) return timeOrder;
|
||||
return a.label.localeCompare(b.label, "en", {
|
||||
numeric: true,
|
||||
sensitivity: "base",
|
||||
});
|
||||
});
|
||||
|
||||
if (conversations.length) {
|
||||
const chatsUpdatedAt = conversations.reduce<string | null>(
|
||||
(best, s) => {
|
||||
const candidate = s.updatedAt ?? s.createdAt ?? null;
|
||||
return isNewerDate(candidate, best) ? candidate : best;
|
||||
},
|
||||
null,
|
||||
);
|
||||
groups.push({
|
||||
id: "workspace:chats",
|
||||
label: labels.all,
|
||||
updatedAt: chatsUpdatedAt,
|
||||
sessions: sortProjectSessions(
|
||||
conversations,
|
||||
options.sort,
|
||||
@ -304,6 +303,15 @@ function groupSessionsByProject(
|
||||
});
|
||||
}
|
||||
|
||||
groups.sort((a, b) => {
|
||||
const timeOrder = dateToTime(b.updatedAt) - dateToTime(a.updatedAt);
|
||||
if (timeOrder !== 0) return timeOrder;
|
||||
return a.label.localeCompare(b.label, "en", {
|
||||
numeric: true,
|
||||
sensitivity: "base",
|
||||
});
|
||||
});
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
|
||||
@ -256,4 +256,60 @@ describe("ChatList", () => {
|
||||
expect(within(chatsSection).getByText("Chat 0")).toBeInTheDocument();
|
||||
expect(within(chatsSection).getByRole("button", { name: "Show less" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("sorts Chats section among project groups by recency, not always last", () => {
|
||||
const sessions = [
|
||||
session({
|
||||
chatId: "recent-chat",
|
||||
title: "Recent chat",
|
||||
updatedAt: "2026-05-21T12:00:00Z",
|
||||
}),
|
||||
session({
|
||||
chatId: "project-a",
|
||||
title: "Project A task",
|
||||
updatedAt: "2026-05-21T10:00:00Z",
|
||||
workspaceScope: {
|
||||
project_path: "/Users/me/project-a",
|
||||
project_name: "project-a",
|
||||
access_mode: "restricted",
|
||||
},
|
||||
}),
|
||||
session({
|
||||
chatId: "project-b",
|
||||
title: "Project B task",
|
||||
updatedAt: "2026-05-21T11:00:00Z",
|
||||
workspaceScope: {
|
||||
project_path: "/Users/me/project-b",
|
||||
project_name: "project-b",
|
||||
access_mode: "restricted",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
render(
|
||||
<ChatList
|
||||
sessions={sessions}
|
||||
activeKey="websocket:recent-chat"
|
||||
onSelect={vi.fn()}
|
||||
onRequestDelete={vi.fn()}
|
||||
onTogglePin={vi.fn()}
|
||||
onRequestRename={vi.fn()}
|
||||
onToggleArchive={vi.fn()}
|
||||
showTimestamps
|
||||
/>,
|
||||
);
|
||||
|
||||
const allRegions = screen.getAllByRole("region");
|
||||
const regionNames = allRegions.map((r) => r.getAttribute("aria-label") ?? r.textContent);
|
||||
|
||||
// The most recently updated conversation ("Recent chat" at 12:00) must be
|
||||
// in the first group — Chats should come before both projects.
|
||||
const chatsIdx = regionNames.findIndex((n) => n?.includes("Chats"));
|
||||
const projAIdx = regionNames.findIndex((n) => n?.includes("project-a"));
|
||||
const projBIdx = regionNames.findIndex((n) => n?.includes("project-b"));
|
||||
|
||||
expect(chatsIdx).toBeLessThan(projAIdx);
|
||||
expect(chatsIdx).toBeLessThan(projBIdx);
|
||||
expect(within(allRegions[chatsIdx]).getByText("Recent chat")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user