Skip to content

Commit ee9135e

Browse files
committed
Merge PR #270: refactor: extract settings panel entry wrappers
2 parents 63cd1e9 + ba89e48 commit ee9135e

3 files changed

Lines changed: 189 additions & 13 deletions

File tree

lib/codex-manager/settings-hub.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ import {
8080
findSettingsHubInitialCursor,
8181
} from "./settings-hub-menu.js";
8282
import { promptSettingsHubMenu } from "./settings-hub-prompt.js";
83+
import {
84+
promptBehaviorSettingsPanelEntry,
85+
promptDashboardDisplaySettingsPanelEntry,
86+
promptStatuslineSettingsPanelEntry,
87+
promptThemeSettingsPanelEntry,
88+
reorderStatuslineField,
89+
} from "./settings-panels.js";
8390
import {
8491
readFileWithRetry,
8592
resolvePluginConfigSavePathKey,
@@ -438,7 +445,7 @@ const __testOnly = {
438445
buildAccountListPreview,
439446
buildSummaryPreviewText,
440447
normalizeStatuslineFields,
441-
reorderField,
448+
reorderField: reorderStatuslineField,
442449
promptDashboardDisplaySettings,
443450
promptStatuslineSettings,
444451
promptBehaviorSettings,
@@ -450,7 +457,9 @@ const __testOnly = {
450457
async function promptDashboardDisplaySettings(
451458
initial: DashboardDisplaySettings,
452459
): Promise<DashboardDisplaySettings | null> {
453-
return promptDashboardDisplayPanel(initial, {
460+
return promptDashboardDisplaySettingsPanelEntry({
461+
initial,
462+
promptDashboardDisplayPanel,
454463
cloneDashboardSettings,
455464
buildAccountListPreview,
456465
formatDashboardSettingState,
@@ -490,12 +499,13 @@ async function configureDashboardDisplaySettings(
490499
async function promptStatuslineSettings(
491500
initial: DashboardDisplaySettings,
492501
): Promise<DashboardDisplaySettings | null> {
493-
return promptStatuslineSettingsPanel(initial, {
502+
return promptStatuslineSettingsPanelEntry({
503+
initial,
504+
promptStatuslineSettingsPanel,
494505
cloneDashboardSettings,
495506
buildAccountListPreview,
496507
normalizeStatuslineFields,
497508
formatDashboardSettingState,
498-
reorderField,
499509
applyDashboardDefaultsForKeys,
500510
STATUSLINE_FIELD_OPTIONS,
501511
STATUSLINE_PANEL_KEYS,
@@ -526,19 +536,14 @@ async function configureStatuslineSettings(
526536
});
527537
}
528538

529-
function formatDelayLabel(delayMs: number): string {
530-
return delayMs <= 0
531-
? "Instant return"
532-
: `${Math.round(delayMs / 1000)}s auto-return`;
533-
}
534-
535539
async function promptBehaviorSettings(
536540
initial: DashboardDisplaySettings,
537541
): Promise<DashboardDisplaySettings | null> {
538-
return promptBehaviorSettingsPanel(initial, {
542+
return promptBehaviorSettingsPanelEntry({
543+
initial,
544+
promptBehaviorSettingsPanel,
539545
cloneDashboardSettings,
540546
applyDashboardDefaultsForKeys,
541-
formatDelayLabel,
542547
formatMenuQuotaTtl,
543548
AUTO_RETURN_OPTIONS_MS,
544549
MENU_QUOTA_TTL_OPTIONS_MS,
@@ -550,7 +555,9 @@ async function promptBehaviorSettings(
550555
async function promptThemeSettings(
551556
initial: DashboardDisplaySettings,
552557
): Promise<DashboardDisplaySettings | null> {
553-
return promptThemeSettingsPanel(initial, {
558+
return promptThemeSettingsPanelEntry({
559+
initial,
560+
promptThemeSettingsPanel,
554561
cloneDashboardSettings,
555562
applyDashboardDefaultsForKeys,
556563
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)