feat(web): settings form polish — dialog layout, homepage button, no default rows, unified dropdown text (#39)

Co-authored-by: Alice <alice@prismshadow.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Yaowei Zheng
2026-07-23 01:07:45 +08:00
committed by GitHub
parent 6d56ce9ccc
commit d01d0faf7a
10 changed files with 363 additions and 183 deletions
@@ -41,7 +41,7 @@ export function thinkingLevelLabel(
/** One dropdown row of the agent-settings thinking-level menu (shape of OptionMenuChoice<string>). */
export interface ThinkingLevelOptionRow {
value: string;
/** Compact text on the trigger button ("" renders the localized default tag). */
/** Compact text on the trigger button. */
triggerLabel: string;
/** Panel row title. */
label: string;
@@ -51,25 +51,30 @@ export interface ThinkingLevelOptionRow {
/**
* Assembles the agent-settings thinking-level dropdown rows from the dictionary's
* [value, description] pairs (which no longer include `none`). Backward compatibility:
* when the **persisted** config already stores `none` (a legacy value), a display-only
* row for it is appended — the trigger shows the real stored state instead of "—" and
* nothing is silently rewritten. Gating on the persisted value (not the local edit
* state) means a misclick onto another tier keeps the row until the change is actually
* saved, so the user can always click back to the value still stored on disk.
* [value, description] pairs, composing both review decisions:
* - the "" (inherit) row is **filtered** — the menu offers only concrete tiers, the user
* picks explicitly; an unset value shows the OptionMenu's (default) placeholder and the
* reset link next to the menu rewinds a local pick back to it;
* - `none` is no longer offered (many models cannot disable thinking) but stays a valid
* stored value: when the **persisted** config already carries it, a display-only row is
* appended — the trigger shows the real stored state and nothing is silently rewritten.
* Gating on the persisted value (not the local edit state) means a misclick onto another
* tier keeps the row until the change is actually saved, so the user can always click
* back to the value still stored on disk.
*/
export function thinkingLevelOptionsFor(
options: ReadonlyArray<readonly [string, string]>,
defaultTag: string,
noneKeptDescription: string,
storedLevel: string | undefined,
): ThinkingLevelOptionRow[] {
const rows = options.map(([value, description]) => ({
value,
triggerLabel: value || defaultTag,
label: value || defaultTag,
description,
}));
const rows = options
.filter(([value]) => value !== "")
.map(([value, description]) => ({
value,
triggerLabel: value,
label: value,
description,
}));
if (storedLevel === "none") {
rows.push({
value: "none",