Skip to content

Commit dc71f12

Browse files
improve(ui): propose settings route cleanup
1 parent 2ba622c commit dc71f12

8 files changed

Lines changed: 63 additions & 24 deletions

File tree

ui/src/app-navigation-groups.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ describe("sidebar pinned routes", () => {
5555
});
5656

5757
it("routes every published settings slice", () => {
58+
expect(routeIdFromPath("/settings/communications")).toBe("communications");
59+
expect(routeIdFromPath("/settings/appearance")).toBe("appearance");
60+
expect(routeIdFromPath("/settings/automation")).toBe("automation");
61+
expect(routeIdFromPath("/settings/infrastructure")).toBe("infrastructure");
62+
expect(routeIdFromPath("/settings/ai-agents")).toBe("ai-agents");
63+
expect(routeIdFromPath("/settings/general")).toBe("config");
64+
expect(routeIdFromPath("/settings/channels")).toBe("channels");
65+
expect(routeIdFromPath("/settings/worktrees")).toBe("worktrees");
66+
});
67+
68+
it("keeps old settings paths as aliases", () => {
5869
expect(routeIdFromPath("/communications")).toBe("communications");
5970
expect(routeIdFromPath("/appearance")).toBe("appearance");
6071
expect(routeIdFromPath("/automation")).toBe("automation");

ui/src/app-navigation.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,16 @@ describe("pathForRoute", () => {
177177
it("returns correct path without base", () => {
178178
expect(pathForRoute("chat")).toBe("/chat");
179179
expect(pathForRoute("overview")).toBe("/overview");
180-
expect(pathForRoute("worktrees")).toBe("/worktrees");
180+
expect(pathForRoute("worktrees")).toBe("/settings/worktrees");
181+
expect(pathForRoute("config")).toBe("/settings/general");
182+
expect(pathForRoute("appearance")).toBe("/settings/appearance");
183+
expect(pathForRoute("logs")).toBe("/settings/logs");
181184
});
182185

183186
it("prepends base path", () => {
184187
expect(pathForRoute("chat", "/ui")).toBe("/ui/chat");
185188
expect(pathForRoute("sessions", "/apps/openclaw")).toBe("/apps/openclaw/sessions");
189+
expect(pathForRoute("config", "/ui")).toBe("/ui/settings/general");
186190
});
187191
});
188192

@@ -192,9 +196,20 @@ describe("routeIdFromPath", () => {
192196
expect(routeIdFromPath("/overview")).toBe("overview");
193197
expect(routeIdFromPath("/activity")).toBe("activity");
194198
expect(routeIdFromPath("/worktrees")).toBe("worktrees");
199+
expect(routeIdFromPath("/settings/worktrees")).toBe("worktrees");
195200
expect(routeIdFromPath("/sessions")).toBe("sessions");
196201
expect(routeIdFromPath("/dreaming")).toBe("dreams");
197202
expect(routeIdFromPath("/dreams")).toBe("dreams");
203+
expect(routeIdFromPath("/settings/general")).toBe("config");
204+
expect(routeIdFromPath("/settings/appearance")).toBe("appearance");
205+
expect(routeIdFromPath("/settings/logs")).toBe("logs");
206+
});
207+
208+
it("keeps legacy top-level settings paths routed", () => {
209+
expect(routeIdFromPath("/config")).toBe("config");
210+
expect(routeIdFromPath("/appearance")).toBe("appearance");
211+
expect(routeIdFromPath("/worktrees")).toBe("worktrees");
212+
expect(routeIdFromPath("/logs")).toBe("logs");
198213
});
199214

200215
it("leaves root fallback to application startup", () => {
@@ -204,11 +219,14 @@ describe("routeIdFromPath", () => {
204219
it("handles base paths", () => {
205220
expect(routeIdFromPath("/ui/chat", "/ui")).toBe("chat");
206221
expect(routeIdFromPath("/apps/openclaw/sessions", "/apps/openclaw")).toBe("sessions");
222+
expect(routeIdFromPath("/ui/settings/general", "/ui")).toBe("config");
223+
expect(routeIdFromPath("/ui/appearance", "/ui")).toBe("appearance");
207224
});
208225

209226
it("rejects route-shaped paths outside the configured base path", () => {
210227
expect(routeIdFromPath("/xx/chat", "/ui")).toBeNull();
211228
expect(routeIdFromPath("/other/sessions", "/apps/openclaw")).toBeNull();
229+
expect(routeIdFromPath("/xx/settings/general", "/ui")).toBeNull();
212230
});
213231

214232
it("returns null for unknown path", () => {
@@ -229,13 +247,18 @@ describe("inferBasePathFromPathname", () => {
229247
it("returns empty string for direct tab path", () => {
230248
expect(inferBasePathFromPathname("/chat")).toBe("");
231249
expect(inferBasePathFromPathname("/overview")).toBe("");
250+
expect(inferBasePathFromPathname("/settings/general")).toBe("");
251+
expect(inferBasePathFromPathname("/settings/appearance")).toBe("");
252+
expect(inferBasePathFromPathname("/appearance")).toBe("");
232253
expect(inferBasePathFromPathname("/dreaming")).toBe("");
233254
expect(inferBasePathFromPathname("/dreams")).toBe("");
234255
});
235256

236257
it("infers base path from nested paths", () => {
237258
expect(inferBasePathFromPathname("/ui/chat")).toBe("/ui");
238259
expect(inferBasePathFromPathname("/apps/openclaw/sessions")).toBe("/apps/openclaw");
260+
expect(inferBasePathFromPathname("/ui/settings/general")).toBe("/ui");
261+
expect(inferBasePathFromPathname("/ui/appearance")).toBe("/ui");
239262
});
240263

241264
it("preserves mount roots without a route suffix", () => {

ui/src/app-route-paths.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ export const APP_ROUTE_DEFINITIONS = {
66
overview: { path: "/overview" },
77
activity: { path: "/activity" },
88
agents: { path: "/agents" },
9-
channels: { path: "/channels" },
10-
config: { path: "/config" },
11-
communications: { path: "/communications" },
12-
appearance: { path: "/appearance" },
13-
automation: { path: "/automation" },
14-
mcp: { path: "/mcp" },
15-
infrastructure: { path: "/infrastructure" },
16-
"ai-agents": { path: "/ai-agents" },
9+
channels: { path: "/settings/channels", aliases: ["/channels"] },
10+
config: { path: "/settings/general", aliases: ["/config"] },
11+
communications: { path: "/settings/communications", aliases: ["/communications"] },
12+
appearance: { path: "/settings/appearance", aliases: ["/appearance"] },
13+
automation: { path: "/settings/automation", aliases: ["/automation"] },
14+
mcp: { path: "/settings/mcp", aliases: ["/mcp"] },
15+
infrastructure: { path: "/settings/infrastructure", aliases: ["/infrastructure"] },
16+
"ai-agents": { path: "/settings/ai-agents", aliases: ["/ai-agents"] },
1717
workboard: { path: "/workboard" },
18-
worktrees: { path: "/worktrees" },
18+
worktrees: { path: "/settings/worktrees", aliases: ["/worktrees"] },
1919
instances: { path: "/instances" },
2020
sessions: { path: "/sessions" },
2121
usage: { path: "/usage" },
22-
debug: { path: "/debug" },
23-
logs: { path: "/logs" },
22+
debug: { path: "/settings/debug", aliases: ["/debug"] },
23+
logs: { path: "/settings/logs", aliases: ["/logs"] },
2424
"skill-workshop": { path: "/skills/workshop" },
2525
skills: { path: "/skills" },
2626
cron: { path: "/cron" },

ui/src/pages/channels/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ function loadChannelsRoute(context: ApplicationContext) {
1717

1818
export const page = definePage({
1919
id: "channels",
20-
path: "/channels",
20+
path: "/settings/channels",
21+
aliases: ["/channels"],
2122
loader: (context: ApplicationContext) => loadChannelsRoute(context),
2223
component: () =>
2324
import("./channels-page.ts").then(() => ({

ui/src/pages/config/route.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ function loadConfigRoute(context: ApplicationContext) {
1313
);
1414
}
1515

16-
function configPage(id: ConfigPageId, path: string) {
16+
function configPage(id: ConfigPageId, path: string, aliases: readonly string[]) {
1717
return definePage({
1818
id,
1919
path,
20+
aliases,
2021
loader: (context: ApplicationContext) => loadConfigRoute(context),
2122
component: () =>
2223
import("./config-page.ts").then(() => ({
@@ -27,11 +28,11 @@ function configPage(id: ConfigPageId, path: string) {
2728
}
2829

2930
export const pages = [
30-
configPage("config", "/config"),
31-
configPage("communications", "/communications"),
32-
configPage("appearance", "/appearance"),
33-
configPage("automation", "/automation"),
34-
configPage("mcp", "/mcp"),
35-
configPage("infrastructure", "/infrastructure"),
36-
configPage("ai-agents", "/ai-agents"),
31+
configPage("config", "/settings/general", ["/config"]),
32+
configPage("communications", "/settings/communications", ["/communications"]),
33+
configPage("appearance", "/settings/appearance", ["/appearance"]),
34+
configPage("automation", "/settings/automation", ["/automation"]),
35+
configPage("mcp", "/settings/mcp", ["/mcp"]),
36+
configPage("infrastructure", "/settings/infrastructure", ["/infrastructure"]),
37+
configPage("ai-agents", "/settings/ai-agents", ["/ai-agents"]),
3738
] as const;

ui/src/pages/debug/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { html } from "lit";
33

44
export const page = definePage({
55
id: "debug",
6-
path: "/debug",
6+
path: "/settings/debug",
7+
aliases: ["/debug"],
78
component: () =>
89
import("./debug-page.ts").then(() => ({
910
header: true,

ui/src/pages/logs/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { html } from "lit";
33

44
export const page = definePage({
55
id: "logs",
6-
path: "/logs",
6+
path: "/settings/logs",
7+
aliases: ["/logs"],
78
component: () =>
89
import("./logs-page.ts").then(() => ({
910
header: true,

ui/src/pages/worktrees/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { html } from "lit";
33

44
export const page = definePage({
55
id: "worktrees",
6-
path: "/worktrees",
6+
path: "/settings/worktrees",
7+
aliases: ["/worktrees"],
78
component: () =>
89
import("./worktrees-page.ts").then(() => ({
910
header: true,

0 commit comments

Comments
 (0)