Skip to content

Commit 28afb14

Browse files
Sort sidebar projects and threads by recency (#1372)
1 parent 8f35155 commit 28afb14

File tree

10 files changed

+1082
-392
lines changed

10 files changed

+1082
-392
lines changed

apps/web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@dnd-kit/modifiers": "^9.0.0",
2020
"@dnd-kit/sortable": "^10.0.0",
2121
"@dnd-kit/utilities": "^3.2.2",
22+
"@formkit/auto-animate": "^0.9.0",
2223
"@lexical/react": "^0.41.0",
2324
"@pierre/diffs": "^1.1.0-beta.16",
2425
"@t3tools/contracts": "workspace:*",

apps/web/src/appSettings.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { describe, expect, it } from "vitest";
33

44
import {
55
AppSettingsSchema,
6+
DEFAULT_SIDEBAR_PROJECT_SORT_ORDER,
7+
DEFAULT_SIDEBAR_THREAD_SORT_ORDER,
68
DEFAULT_TIMESTAMP_FORMAT,
79
getAppModelOptions,
810
getCustomModelOptionsByProvider,
@@ -111,6 +113,16 @@ describe("timestamp format defaults", () => {
111113
});
112114
});
113115

116+
describe("sidebar sort defaults", () => {
117+
it("defaults project sorting to updated_at", () => {
118+
expect(DEFAULT_SIDEBAR_PROJECT_SORT_ORDER).toBe("updated_at");
119+
});
120+
121+
it("defaults thread sorting to updated_at", () => {
122+
expect(DEFAULT_SIDEBAR_THREAD_SORT_ORDER).toBe("updated_at");
123+
});
124+
});
125+
114126
describe("provider-specific custom models", () => {
115127
it("includes provider-specific custom slugs in non-codex model lists", () => {
116128
const claudeOptions = getAppModelOptions("claudeAgent", ["claude/custom-opus"]);
@@ -245,6 +257,8 @@ describe("AppSettingsSchema", () => {
245257
defaultThreadEnvMode: "local",
246258
confirmThreadDelete: false,
247259
enableAssistantStreaming: false,
260+
sidebarProjectSortOrder: DEFAULT_SIDEBAR_PROJECT_SORT_ORDER,
261+
sidebarThreadSortOrder: DEFAULT_SIDEBAR_THREAD_SORT_ORDER,
248262
timestampFormat: DEFAULT_TIMESTAMP_FORMAT,
249263
customCodexModels: [],
250264
customClaudeModels: [],

apps/web/src/appSettings.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ export const MAX_CUSTOM_MODEL_LENGTH = 256;
2121
export const TimestampFormat = Schema.Literals(["locale", "12-hour", "24-hour"]);
2222
export type TimestampFormat = typeof TimestampFormat.Type;
2323
export const DEFAULT_TIMESTAMP_FORMAT: TimestampFormat = "locale";
24+
export const SidebarProjectSortOrder = Schema.Literals(["updated_at", "created_at", "manual"]);
25+
export type SidebarProjectSortOrder = typeof SidebarProjectSortOrder.Type;
26+
export const DEFAULT_SIDEBAR_PROJECT_SORT_ORDER: SidebarProjectSortOrder = "updated_at";
27+
export const SidebarThreadSortOrder = Schema.Literals(["updated_at", "created_at"]);
28+
export type SidebarThreadSortOrder = typeof SidebarThreadSortOrder.Type;
29+
export const DEFAULT_SIDEBAR_THREAD_SORT_ORDER: SidebarThreadSortOrder = "updated_at";
2430
type CustomModelSettingsKey = "customCodexModels" | "customClaudeModels";
2531
export type ProviderCustomModelConfig = {
2632
provider: ProviderKind;
@@ -58,6 +64,12 @@ export const AppSettingsSchema = Schema.Struct({
5864
confirmThreadDelete: Schema.Boolean.pipe(withDefaults(() => true)),
5965
diffWordWrap: Schema.Boolean.pipe(withDefaults(() => false)),
6066
enableAssistantStreaming: Schema.Boolean.pipe(withDefaults(() => false)),
67+
sidebarProjectSortOrder: SidebarProjectSortOrder.pipe(
68+
withDefaults(() => DEFAULT_SIDEBAR_PROJECT_SORT_ORDER),
69+
),
70+
sidebarThreadSortOrder: SidebarThreadSortOrder.pipe(
71+
withDefaults(() => DEFAULT_SIDEBAR_THREAD_SORT_ORDER),
72+
),
6173
timestampFormat: TimestampFormat.pipe(withDefaults(() => DEFAULT_TIMESTAMP_FORMAT)),
6274
customCodexModels: Schema.Array(Schema.String).pipe(withDefaults(() => [])),
6375
customClaudeModels: Schema.Array(Schema.String).pipe(withDefaults(() => [])),

0 commit comments

Comments
 (0)