fix(ui): polish reasoning labels and settings margins

This commit is contained in:
Peter Steinberger
2026-05-18 10:03:41 +01:00
parent 1e5450f23e
commit 4b4f71a2cc
5 changed files with 46 additions and 21 deletions
+1
View File
@@ -52,6 +52,7 @@ Docs: https://docs.openclaw.ai
- Agents/Codex: fail closed when an explicitly requested Codex harness is not registered instead of silently trying configured model fallbacks. Fixes #83349. Thanks @r2-vibes.
- QA-Lab: make runtime tool coverage fail on missing required tool exercise instead of treating pass/pass parity envelope drift as missing coverage.
- Core/plugins: harden clawpatch-reported edge cases across gateway auth cleanup, Claude session id paths, plugin activation policy, apply-patch hunk handling, diagnostic redaction, and plugin metadata validation.
- UI: show reasoning choices as plain labels instead of leaking internal override wording in session and chat pickers.
- Mac app: prefer explicit private/Tailscale/LAN Gateway endpoints over SSH tunnels, preserve legacy loopback tunnel configs, persist transport choices, and show captured SSH stderr when tunneling really fails.
- Gateway/sessions: keep ACP/acpx and runtime child sessions visible in configured-only session lists when their owner or parent session belongs to a configured agent.
- Mac app: keep app-level menu commands and Dashboard failure states reachable when the remote Gateway is disconnected, and keep the Settings sidebar toggle in the leading titlebar area.
@@ -14,7 +14,6 @@ struct ExecApprovalsSettings: View {
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.vertical, 4)
.padding(.trailing, SettingsLayout.scrollbarGutter)
}
}
}
+28 -3
View File
@@ -10,7 +10,7 @@ export function formatInheritedThinkingLabel(effectiveLevel: string | null | und
if (!normalized || normalized === "off") {
return "Off";
}
return `Inherited: ${normalized}`;
return `Inherited: ${formatThinkingLevelDisplayLabel(normalized)}`;
}
export function formatThinkingOverrideLabel(value: string, label?: string | null): string {
@@ -18,6 +18,31 @@ export function formatThinkingOverrideLabel(value: string, label?: string | null
if (!normalized || normalized === "off") {
return "Off";
}
const displayLabel = label?.trim() || normalized;
return `Override: ${displayLabel}`;
return formatThinkingLevelDisplayLabel(label?.trim() || normalized);
}
function formatThinkingLevelDisplayLabel(value: string): string {
const raw = normalizeLowercaseStringOrEmpty(value);
if (["on", "enable", "enabled"].includes(raw)) {
return "On";
}
const normalized = normalizeThinkingOptionValue(value);
switch (normalized) {
case "adaptive":
return "Adaptive";
case "minimal":
return "Minimal";
case "low":
return "Low";
case "medium":
return "Medium";
case "high":
return "High";
case "xhigh":
return "Extra high";
case "max":
return "Maximum";
default:
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
+11 -11
View File
@@ -1339,7 +1339,7 @@ describe("chat session controls", () => {
]);
expect(
[...(thinkingSelect?.options ?? [])].map((option) => option.textContent?.trim()),
).toEqual(["Off", "Off", "Override: adaptive", "Override: xhigh", "Override: maximum"]);
).toEqual(["Off", "Off", "Adaptive", "Extra high", "Maximum"]);
});
it("labels chat thinking default from the active session row", () => {
@@ -1356,8 +1356,8 @@ describe("chat session controls", () => {
);
expect(thinkingSelect?.value).toBe("");
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
expect(thinkingSelect?.title).toBe("Inherited: adaptive");
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
expect(thinkingSelect?.title).toBe("Inherited: Adaptive");
});
it("always renders full thinking labels", () => {
@@ -1387,14 +1387,14 @@ describe("chat session controls", () => {
expect(container.querySelector('select[data-chat-thinking-select-compact="true"]')).toBeNull();
expect(thinkingSelect?.value).toBe("");
expect(thinkingSelect?.title).toBe("Inherited: high");
expect(thinkingSelect?.title).toBe("Inherited: High");
expect([...thinkingSelect!.options].map((option) => option.textContent?.trim())).toEqual([
"Inherited: high",
"Inherited: High",
"Off",
"Override: low",
"Override: medium",
"Override: high",
"Override: xhigh",
"Low",
"Medium",
"High",
"Extra high",
]);
});
@@ -1411,7 +1411,7 @@ describe("chat session controls", () => {
);
expect(thinkingSelect?.value).toBe("");
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
expect(thinkingSelect?.title).toBe("Inherited: adaptive");
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
expect(thinkingSelect?.title).toBe("Inherited: Adaptive");
});
});
+6 -6
View File
@@ -272,7 +272,7 @@ describe("sessions view", () => {
Array.from(thinking?.options ?? [])
.find((option) => option.value === "max")
?.textContent?.trim(),
).toBe("Override: maximum");
).toBe("Maximum");
thinking!.value = "max";
thinking!.dispatchEvent(new Event("change", { bubbles: true }));
@@ -303,12 +303,12 @@ describe("sessions view", () => {
const thinking = container.querySelector("tbody select") as HTMLSelectElement | null;
expect(thinking?.value).toBe("");
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
expect(
Array.from(thinking?.options ?? [])
.find((option) => option.value === "adaptive")
?.textContent?.trim(),
).toBe("Override: adaptive");
).toBe("Adaptive");
});
it("labels inherited thinking from list defaults when lightweight rows omit row defaults", async () => {
@@ -340,9 +340,9 @@ describe("sessions view", () => {
const thinking = container.querySelector("tbody select") as HTMLSelectElement | null;
expect(thinking?.value).toBe("");
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: high");
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: High");
expect(Array.from(thinking?.options ?? []).map((option) => option.textContent?.trim())).toEqual(
["Inherited: high", "Off", "Override: high"],
["Inherited: High", "Off", "High"],
);
});
@@ -372,7 +372,7 @@ describe("sessions view", () => {
Array.from(thinking?.options ?? [])
.find((option) => option.value === "low")
?.textContent?.trim(),
).toBe("Override: on");
).toBe("On");
thinking!.value = "low";
thinking!.dispatchEvent(new Event("change", { bubbles: true }));