feat(web): sidebar group polish — even hover geometry, folder open/close icons, group pinning (#35)
Co-authored-by: Alice <alice@prismshadow.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,3 +89,21 @@ export function groupSessionsByWorkspace(sessions: SessionInfo[]): WorkspaceGrou
|
||||
});
|
||||
return groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable pinned-first partition for sidebar groups: items whose key is in `pinned`
|
||||
* come first, each partition preserving the input order (recency for Workspace
|
||||
* groups, the configured order for Agents). Pure and mode-agnostic — callers pass
|
||||
* the key extractor; pinned keys with no matching item are simply ignored.
|
||||
*/
|
||||
export function pinnedFirst<T>(
|
||||
items: readonly T[],
|
||||
keyOf: (item: T) => string,
|
||||
pinned: ReadonlySet<string>,
|
||||
): T[] {
|
||||
if (pinned.size === 0) return [...items];
|
||||
const pin: T[] = [];
|
||||
const rest: T[] = [];
|
||||
for (const item of items) (pinned.has(keyOf(item)) ? pin : rest).push(item);
|
||||
return [...pin, ...rest];
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ export const en: Strings = {
|
||||
expandSidebar: "Expand sidebar",
|
||||
collapseGroup: "Collapse",
|
||||
expandGroup: "Expand",
|
||||
pinGroup: "Pin group",
|
||||
unpinGroup: "Unpin group",
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
||||
@@ -23,6 +23,8 @@ export const zh = {
|
||||
expandSidebar: "展开侧栏",
|
||||
collapseGroup: "折叠",
|
||||
expandGroup: "展开",
|
||||
pinGroup: "置顶分组",
|
||||
unpinGroup: "取消置顶",
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
||||
Reference in New Issue
Block a user