feat(webui): persist manual session ordering

This commit is contained in:
Xubin Ren
2026-08-06 19:11:05 +08:00
parent 2c8e63446f
commit 9cf6cf0639
12 changed files with 204 additions and 19 deletions
+21 -3
View File
@@ -30,6 +30,7 @@ export interface ChatGroupingOptions {
archivedKeys: string[];
titleOverrides: Record<string, string>;
projectNameOverrides: Record<string, string>;
sessionOrder: string[];
showArchived: boolean;
sort: SidebarSortMode;
defaultWorkspacePath?: string | null;
@@ -64,7 +65,7 @@ export function groupSessions(
pinnedSessions.push(session);
continue;
}
if (options.sort === "title_asc") {
if (options.sort === "title_asc" || options.sort === "manual") {
normalSessions.push(session);
continue;
}
@@ -87,11 +88,12 @@ export function groupSessions(
buckets.get(label) ?? [],
options.sort,
options.titleOverrides,
options.sessionOrder,
),
}))
.filter((group) => group.sessions.length > 0);
if (options.sort === "title_asc" && normalSessions.length) {
if ((options.sort === "title_asc" || options.sort === "manual") && normalSessions.length) {
groups.push({
id: "date:all",
label: labels.all,
@@ -99,6 +101,7 @@ export function groupSessions(
normalSessions,
options.sort,
options.titleOverrides,
options.sessionOrder,
),
});
}
@@ -110,6 +113,7 @@ export function groupSessions(
pinnedSessions,
options.sort,
options.titleOverrides,
options.sessionOrder,
),
});
}
@@ -121,6 +125,7 @@ export function groupSessions(
archivedSessions,
options.sort,
options.titleOverrides,
options.sessionOrder,
),
});
}
@@ -276,6 +281,7 @@ function groupSessionsByProject(
bucket.sessions,
options.sort,
options.titleOverrides,
options.sessionOrder,
pinned,
archived,
),
@@ -297,6 +303,7 @@ function groupSessionsByProject(
conversations,
options.sort,
options.titleOverrides,
options.sessionOrder,
pinned,
archived,
),
@@ -319,10 +326,11 @@ function sortProjectSessions(
sessions: ChatSummary[],
sort: SidebarSortMode,
titleOverrides: Record<string, string>,
sessionOrder: string[],
pinned: Set<string>,
archived: Set<string>,
): ChatSummary[] {
return sortSessions(sessions, sort, titleOverrides).sort((a, b) => {
return sortSessions(sessions, sort, titleOverrides, sessionOrder).sort((a, b) => {
const pinOrder = Number(pinned.has(b.key)) - Number(pinned.has(a.key));
if (pinOrder !== 0) return pinOrder;
const archiveOrder = Number(archived.has(a.key)) - Number(archived.has(b.key));
@@ -335,9 +343,19 @@ function sortSessions(
sessions: ChatSummary[],
sort: SidebarSortMode,
titleOverrides: Record<string, string>,
sessionOrder: string[],
): ChatSummary[] {
const copy = [...sessions];
const order = new Map(sessionOrder.map((key, index) => [key, index]));
copy.sort((a, b) => {
if (sort === "manual") {
const aIndex = order.get(a.key);
const bIndex = order.get(b.key);
if (aIndex !== undefined && bIndex !== undefined) return aIndex - bIndex;
if (aIndex === undefined && bIndex !== undefined) return -1;
if (aIndex !== undefined && bIndex === undefined) return 1;
return sessionTime(b, "updatedAt") - sessionTime(a, "updatedAt");
}
if (sort === "title_asc") {
const titleOrder = titleForSort(a, titleOverrides).localeCompare(
titleForSort(b, titleOverrides),
+1 -1
View File
@@ -13,6 +13,6 @@ export function writeDraggedSession(
dataTransfer: DataTransfer,
sessionKey: string,
): void {
dataTransfer.effectAllowed = "copy";
dataTransfer.effectAllowed = "copyMove";
dataTransfer.setData(SESSION_DRAG_TYPE, sessionKey);
}
+2 -1
View File
@@ -367,7 +367,7 @@ export interface WorkspacesPayload {
}
export type SidebarDensity = "comfortable" | "compact";
export type SidebarSortMode = "updated_desc" | "created_desc" | "title_asc";
export type SidebarSortMode = "updated_desc" | "created_desc" | "title_asc" | "manual";
export interface SidebarViewState {
density: SidebarDensity;
@@ -381,6 +381,7 @@ export interface SidebarStatePayload {
schema_version: number;
pinned_keys: string[];
archived_keys: string[];
session_order: string[];
title_overrides: Record<string, string>;
project_name_overrides: Record<string, string>;
tags_by_key: Record<string, string[]>;