Skip to content

Commit 754db7d

Browse files
committed
refactor: extract settings panel entry wrappers
1 parent 16acf57 commit 754db7d

3 files changed

Lines changed: 189 additions & 31 deletions

File tree

lib/codex-manager/settings-hub.ts

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ import {
7575
findSettingsHubInitialCursor,
7676
} from "./settings-hub-menu.js";
7777
import { promptSettingsHubMenu } from "./settings-hub-prompt.js";
78+
import {
79+
promptBehaviorSettingsPanelEntry,
80+
promptDashboardDisplaySettingsPanelEntry,
81+
promptStatuslineSettingsPanelEntry,
82+
promptThemeSettingsPanelEntry,
83+
reorderStatuslineField,
84+
} from "./settings-panels.js";
7885
import {
7986
readFileWithRetry,
8087
resolvePluginConfigSavePathKey,
@@ -448,7 +455,7 @@ const __testOnly = {
448455
buildAccountListPreview,
449456
buildSummaryPreviewText,
450457
normalizeStatuslineFields,
451-
reorderField,
458+
reorderField: reorderStatuslineField,
452459
promptDashboardDisplaySettings,
453460
promptStatuslineSettings,
454461
promptBehaviorSettings,
@@ -460,7 +467,9 @@ const __testOnly = {
460467
async function promptDashboardDisplaySettings(
461468
initial: DashboardDisplaySettings,
462469
): Promise<DashboardDisplaySettings | null> {
463-
return promptDashboardDisplayPanel(initial, {
470+
return promptDashboardDisplaySettingsPanelEntry({
471+
initial,
472+
promptDashboardDisplayPanel,
464473
cloneDashboardSettings,
465474
buildAccountListPreview,
466475
formatDashboardSettingState,
@@ -497,33 +506,16 @@ async function configureDashboardDisplaySettings(
497506
});
498507
}
499508

500-
function reorderField(
501-
fields: DashboardStatuslineField[],
502-
key: DashboardStatuslineField,
503-
direction: -1 | 1,
504-
): DashboardStatuslineField[] {
505-
const index = fields.indexOf(key);
506-
if (index < 0) return fields;
507-
const target = index + direction;
508-
if (target < 0 || target >= fields.length) return fields;
509-
const next = [...fields];
510-
const current = next[index];
511-
const swap = next[target];
512-
if (!current || !swap) return fields;
513-
next[index] = swap;
514-
next[target] = current;
515-
return next;
516-
}
517-
518509
async function promptStatuslineSettings(
519510
initial: DashboardDisplaySettings,
520511
): Promise<DashboardDisplaySettings | null> {
521-
return promptStatuslineSettingsPanel(initial, {
512+
return promptStatuslineSettingsPanelEntry({
513+
initial,
514+
promptStatuslineSettingsPanel,
522515
cloneDashboardSettings,
523516
buildAccountListPreview,
524517
normalizeStatuslineFields,
525518
formatDashboardSettingState,
526-
reorderField,
527519
applyDashboardDefaultsForKeys,
528520
STATUSLINE_FIELD_OPTIONS,
529521
STATUSLINE_PANEL_KEYS,
@@ -553,19 +545,14 @@ async function configureStatuslineSettings(
553545
});
554546
}
555547

556-
function formatDelayLabel(delayMs: number): string {
557-
return delayMs <= 0
558-
? "Instant return"
559-
: `${Math.round(delayMs / 1000)}s auto-return`;
560-
}
561-
562548
async function promptBehaviorSettings(
563549
initial: DashboardDisplaySettings,
564550
): Promise<DashboardDisplaySettings | null> {
565-
return promptBehaviorSettingsPanel(initial, {
551+
return promptBehaviorSettingsPanelEntry({
552+
initial,
553+
promptBehaviorSettingsPanel,
566554
cloneDashboardSettings,
567555
applyDashboardDefaultsForKeys,
568-
formatDelayLabel,
569556
formatMenuQuotaTtl,
570557
AUTO_RETURN_OPTIONS_MS,
571558
MENU_QUOTA_TTL_OPTIONS_MS,
@@ -577,7 +564,9 @@ async function promptBehaviorSettings(
577564
async function promptThemeSettings(
578565
initial: DashboardDisplaySettings,
579566
): Promise<DashboardDisplaySettings | null> {
580-
return promptThemeSettingsPanel(initial, {
567+
return promptThemeSettingsPanelEntry({
568+
initial,
569+
promptThemeSettingsPanel,
581570
cloneDashboardSettings,
582571
applyDashboardDefaultsForKeys,
583572
applyUiThemeFromDashboardSettings,
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import {
2+
type DashboardDisplaySettings,
3+
type DashboardStatuslineField,
4+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS,
5+
} from "../dashboard-settings.js";
6+
import type { BehaviorSettingsPanelDeps } from "./behavior-settings-panel.js";
7+
import type { DashboardDisplayPanelDeps } from "./dashboard-display-panel.js";
8+
import type { StatuslineSettingsPanelDeps } from "./statusline-settings-panel.js";
9+
import type { ThemeSettingsPanelDeps } from "./theme-settings-panel.js";
10+
11+
export async function promptDashboardDisplaySettingsPanelEntry(params: {
12+
initial: DashboardDisplaySettings;
13+
promptDashboardDisplayPanel: (
14+
initial: DashboardDisplaySettings,
15+
deps: DashboardDisplayPanelDeps,
16+
) => Promise<DashboardDisplaySettings | null>;
17+
cloneDashboardSettings: DashboardDisplayPanelDeps["cloneDashboardSettings"];
18+
buildAccountListPreview: DashboardDisplayPanelDeps["buildAccountListPreview"];
19+
formatDashboardSettingState: DashboardDisplayPanelDeps["formatDashboardSettingState"];
20+
formatMenuSortMode: DashboardDisplayPanelDeps["formatMenuSortMode"];
21+
resolveMenuLayoutMode: (
22+
settings?: DashboardDisplaySettings,
23+
) => NonNullable<DashboardDisplaySettings["menuLayoutMode"]>;
24+
formatMenuLayoutMode: DashboardDisplayPanelDeps["formatMenuLayoutMode"];
25+
applyDashboardDefaultsForKeys: DashboardDisplayPanelDeps["applyDashboardDefaultsForKeys"];
26+
DASHBOARD_DISPLAY_OPTIONS: DashboardDisplayPanelDeps["DASHBOARD_DISPLAY_OPTIONS"];
27+
ACCOUNT_LIST_PANEL_KEYS: DashboardDisplayPanelDeps["ACCOUNT_LIST_PANEL_KEYS"];
28+
UI_COPY: DashboardDisplayPanelDeps["UI_COPY"];
29+
}): Promise<DashboardDisplaySettings | null> {
30+
return params.promptDashboardDisplayPanel(params.initial, {
31+
cloneDashboardSettings: params.cloneDashboardSettings,
32+
buildAccountListPreview: params.buildAccountListPreview,
33+
formatDashboardSettingState: params.formatDashboardSettingState,
34+
formatMenuSortMode: params.formatMenuSortMode,
35+
resolveMenuLayoutMode: (settings) =>
36+
params.resolveMenuLayoutMode(
37+
settings ?? DEFAULT_DASHBOARD_DISPLAY_SETTINGS,
38+
) ?? "compact-details",
39+
formatMenuLayoutMode: params.formatMenuLayoutMode,
40+
applyDashboardDefaultsForKeys: params.applyDashboardDefaultsForKeys,
41+
DASHBOARD_DISPLAY_OPTIONS: params.DASHBOARD_DISPLAY_OPTIONS,
42+
ACCOUNT_LIST_PANEL_KEYS: params.ACCOUNT_LIST_PANEL_KEYS,
43+
UI_COPY: params.UI_COPY,
44+
});
45+
}
46+
47+
export function reorderStatuslineField(
48+
fields: DashboardStatuslineField[],
49+
key: DashboardStatuslineField,
50+
direction: -1 | 1,
51+
): DashboardStatuslineField[] {
52+
const index = fields.indexOf(key);
53+
if (index < 0) return fields;
54+
const target = index + direction;
55+
if (target < 0 || target >= fields.length) return fields;
56+
const next = [...fields];
57+
const current = next[index];
58+
const swap = next[target];
59+
if (!current || !swap) return fields;
60+
next[index] = swap;
61+
next[target] = current;
62+
return next;
63+
}
64+
65+
export async function promptStatuslineSettingsPanelEntry(params: {
66+
initial: DashboardDisplaySettings;
67+
promptStatuslineSettingsPanel: (
68+
initial: DashboardDisplaySettings,
69+
deps: StatuslineSettingsPanelDeps,
70+
) => Promise<DashboardDisplaySettings | null>;
71+
cloneDashboardSettings: StatuslineSettingsPanelDeps["cloneDashboardSettings"];
72+
buildAccountListPreview: StatuslineSettingsPanelDeps["buildAccountListPreview"];
73+
normalizeStatuslineFields: StatuslineSettingsPanelDeps["normalizeStatuslineFields"];
74+
formatDashboardSettingState: StatuslineSettingsPanelDeps["formatDashboardSettingState"];
75+
applyDashboardDefaultsForKeys: StatuslineSettingsPanelDeps["applyDashboardDefaultsForKeys"];
76+
STATUSLINE_FIELD_OPTIONS: StatuslineSettingsPanelDeps["STATUSLINE_FIELD_OPTIONS"];
77+
STATUSLINE_PANEL_KEYS: StatuslineSettingsPanelDeps["STATUSLINE_PANEL_KEYS"];
78+
UI_COPY: StatuslineSettingsPanelDeps["UI_COPY"];
79+
}): Promise<DashboardDisplaySettings | null> {
80+
return params.promptStatuslineSettingsPanel(params.initial, {
81+
cloneDashboardSettings: params.cloneDashboardSettings,
82+
buildAccountListPreview: params.buildAccountListPreview,
83+
normalizeStatuslineFields: params.normalizeStatuslineFields,
84+
formatDashboardSettingState: params.formatDashboardSettingState,
85+
reorderField: reorderStatuslineField,
86+
applyDashboardDefaultsForKeys: params.applyDashboardDefaultsForKeys,
87+
STATUSLINE_FIELD_OPTIONS: params.STATUSLINE_FIELD_OPTIONS,
88+
STATUSLINE_PANEL_KEYS: params.STATUSLINE_PANEL_KEYS,
89+
UI_COPY: params.UI_COPY,
90+
});
91+
}
92+
93+
export function formatAutoReturnDelayLabel(delayMs: number): string {
94+
return delayMs <= 0
95+
? "Instant return"
96+
: `${Math.round(delayMs / 1000)}s auto-return`;
97+
}
98+
99+
export async function promptBehaviorSettingsPanelEntry(params: {
100+
initial: DashboardDisplaySettings;
101+
promptBehaviorSettingsPanel: (
102+
initial: DashboardDisplaySettings,
103+
deps: BehaviorSettingsPanelDeps,
104+
) => Promise<DashboardDisplaySettings | null>;
105+
cloneDashboardSettings: BehaviorSettingsPanelDeps["cloneDashboardSettings"];
106+
applyDashboardDefaultsForKeys: BehaviorSettingsPanelDeps["applyDashboardDefaultsForKeys"];
107+
formatMenuQuotaTtl: BehaviorSettingsPanelDeps["formatMenuQuotaTtl"];
108+
AUTO_RETURN_OPTIONS_MS: BehaviorSettingsPanelDeps["AUTO_RETURN_OPTIONS_MS"];
109+
MENU_QUOTA_TTL_OPTIONS_MS: BehaviorSettingsPanelDeps["MENU_QUOTA_TTL_OPTIONS_MS"];
110+
BEHAVIOR_PANEL_KEYS: BehaviorSettingsPanelDeps["BEHAVIOR_PANEL_KEYS"];
111+
UI_COPY: BehaviorSettingsPanelDeps["UI_COPY"];
112+
}): Promise<DashboardDisplaySettings | null> {
113+
return params.promptBehaviorSettingsPanel(params.initial, {
114+
cloneDashboardSettings: params.cloneDashboardSettings,
115+
applyDashboardDefaultsForKeys: params.applyDashboardDefaultsForKeys,
116+
formatDelayLabel: formatAutoReturnDelayLabel,
117+
formatMenuQuotaTtl: params.formatMenuQuotaTtl,
118+
AUTO_RETURN_OPTIONS_MS: params.AUTO_RETURN_OPTIONS_MS,
119+
MENU_QUOTA_TTL_OPTIONS_MS: params.MENU_QUOTA_TTL_OPTIONS_MS,
120+
BEHAVIOR_PANEL_KEYS: params.BEHAVIOR_PANEL_KEYS,
121+
UI_COPY: params.UI_COPY,
122+
});
123+
}
124+
125+
export async function promptThemeSettingsPanelEntry(params: {
126+
initial: DashboardDisplaySettings;
127+
promptThemeSettingsPanel: (
128+
initial: DashboardDisplaySettings,
129+
deps: ThemeSettingsPanelDeps,
130+
) => Promise<DashboardDisplaySettings | null>;
131+
cloneDashboardSettings: ThemeSettingsPanelDeps["cloneDashboardSettings"];
132+
applyDashboardDefaultsForKeys: ThemeSettingsPanelDeps["applyDashboardDefaultsForKeys"];
133+
applyUiThemeFromDashboardSettings: ThemeSettingsPanelDeps["applyUiThemeFromDashboardSettings"];
134+
THEME_PRESET_OPTIONS: ThemeSettingsPanelDeps["THEME_PRESET_OPTIONS"];
135+
ACCENT_COLOR_OPTIONS: ThemeSettingsPanelDeps["ACCENT_COLOR_OPTIONS"];
136+
THEME_PANEL_KEYS: ThemeSettingsPanelDeps["THEME_PANEL_KEYS"];
137+
UI_COPY: ThemeSettingsPanelDeps["UI_COPY"];
138+
}): Promise<DashboardDisplaySettings | null> {
139+
return params.promptThemeSettingsPanel(params.initial, {
140+
cloneDashboardSettings: params.cloneDashboardSettings,
141+
applyDashboardDefaultsForKeys: params.applyDashboardDefaultsForKeys,
142+
applyUiThemeFromDashboardSettings: params.applyUiThemeFromDashboardSettings,
143+
THEME_PRESET_OPTIONS: params.THEME_PRESET_OPTIONS,
144+
ACCENT_COLOR_OPTIONS: params.ACCENT_COLOR_OPTIONS,
145+
THEME_PANEL_KEYS: params.THEME_PANEL_KEYS,
146+
UI_COPY: params.UI_COPY,
147+
});
148+
}

test/settings-panels.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { describe, expect, it } from "vitest";
2+
import {
3+
formatAutoReturnDelayLabel,
4+
reorderStatuslineField,
5+
} from "../lib/codex-manager/settings-panels.js";
6+
7+
describe("settings panel helpers", () => {
8+
it("reorders statusline fields safely", () => {
9+
expect(
10+
reorderStatuslineField(["last-used", "limits", "status"], "limits", -1),
11+
).toEqual(["limits", "last-used", "status"]);
12+
expect(reorderStatuslineField(["last-used"], "last-used", -1)).toEqual([
13+
"last-used",
14+
]);
15+
});
16+
17+
it("formats auto return delay labels", () => {
18+
expect(formatAutoReturnDelayLabel(0)).toBe("Instant return");
19+
expect(formatAutoReturnDelayLabel(4000)).toBe("4s auto-return");
20+
});
21+
});

0 commit comments

Comments
 (0)