дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
feat(settings): add "Show tool window badges" (#637)
Counts on the tool window stripe icons (changed files on Commit, problems, agent tasks needing input, running processes) can be turned off in Settings › Appearance & Behavior › Appearance › Tool Windows. On by default; the setting is stored in appearance settings and survives restarts. Co-authored-by: a-rookie-of-C-language <[email protected]>
Цей коміт міститься в:
1 джерело
9847fd2c01
коміт
ad80e903e3
8 files changed
+80
-1
No files matched your search
@@ -292,6 +292,7 @@ pub struct AppearanceSettings {
|
||||
pub editor_antialiasing: String,
|
||||
pub show_tool_window_bars: bool,
|
||||
pub show_tool_window_names: bool,
|
||||
pub show_tool_window_badges: bool,
|
||||
pub widescreen_tool_windows: bool,
|
||||
/// Status bar widgets shown (`true`) or hidden (`false`) by the user
|
||||
/// (status bar context menu); widgets not listed use their default.
|
||||
@@ -338,6 +339,7 @@ impl Default for AppearanceSettings {
|
||||
editor_antialiasing: "greyscale".into(),
|
||||
show_tool_window_bars: true,
|
||||
show_tool_window_names: false,
|
||||
show_tool_window_badges: true,
|
||||
widescreen_tool_windows: false,
|
||||
status_bar_widgets: BTreeMap::new(),
|
||||
main_toolbar: None,
|
||||
@@ -719,6 +721,21 @@ impl Settings {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn tool_window_badges_default_on_and_round_trip() {
|
||||
let old: Settings = serde_json::from_str(r#"{"appearance":{"showToolWindowNames":true}}"#).unwrap();
|
||||
assert!(old.appearance.show_tool_window_badges);
|
||||
assert!(Settings::default().appearance.show_tool_window_badges);
|
||||
for enabled in [false, true] {
|
||||
let mut settings = Settings::default();
|
||||
settings.appearance.show_tool_window_badges = enabled;
|
||||
let json = serde_json::to_value(&settings).unwrap();
|
||||
assert_eq!(json["appearance"]["showToolWindowBadges"], enabled);
|
||||
let restored: Settings = serde_json::from_value(json).unwrap();
|
||||
assert_eq!(restored.appearance.show_tool_window_badges, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn main_menu_style_defaults_and_round_trips() {
|
||||
let old: Settings = serde_json::from_str(r#"{"appearance":{"compactMode":true}}"#).unwrap();
|
||||
|
||||
@@ -1434,6 +1434,7 @@ export type AppearanceSettings = {
|
||||
editorAntialiasing?: string,
|
||||
showToolWindowBars?: boolean,
|
||||
showToolWindowNames?: boolean,
|
||||
showToolWindowBadges?: boolean,
|
||||
widescreenToolWindows?: boolean,
|
||||
/**
|
||||
* Status bar widgets shown (`true`) or hidden (`false`) by the user
|
||||
|
||||
@@ -21,6 +21,12 @@ describe("appearance & behavior settings", () => {
|
||||
expect(validateAppearanceExtras({ theme: "system" }).syncWithOs).toBe(true);
|
||||
});
|
||||
|
||||
it("defaults Show tool window badges to on and honours the stored value", () => {
|
||||
expect(validateAppearanceExtras({}).showToolWindowBadges).toBe(true);
|
||||
expect(validateAppearanceExtras({ showToolWindowBadges: false }).showToolWindowBadges).toBe(false);
|
||||
expect(validateAppearanceExtras({ showToolWindowBadges: 1 }).showToolWindowBadges).toBe(true);
|
||||
});
|
||||
|
||||
it("formats dates with an override pattern and pretty dates", () => {
|
||||
const d = new Date(2026, 0, 5, 14, 7);
|
||||
expect(formatPattern(d, "dd.MM.yyyy")).toBe("05.01.2026");
|
||||
|
||||
@@ -33,6 +33,7 @@ export interface AppearanceExtras {
|
||||
editorAntialiasing: Antialiasing;
|
||||
showToolWindowBars: boolean;
|
||||
showToolWindowNames: boolean;
|
||||
showToolWindowBadges: boolean;
|
||||
widescreenToolWindows: boolean;
|
||||
}
|
||||
|
||||
@@ -84,6 +85,7 @@ export const DEFAULT_APPEARANCE_EXTRAS: AppearanceExtras = {
|
||||
editorAntialiasing: "greyscale",
|
||||
showToolWindowBars: true,
|
||||
showToolWindowNames: false,
|
||||
showToolWindowBadges: true,
|
||||
widescreenToolWindows: false,
|
||||
};
|
||||
|
||||
@@ -134,6 +136,7 @@ export function validateAppearanceExtras(raw: unknown): AppearanceExtras {
|
||||
editorAntialiasing: oneOf(a.editorAntialiasing, AA, d.editorAntialiasing),
|
||||
showToolWindowBars: b("showToolWindowBars"),
|
||||
showToolWindowNames: b("showToolWindowNames"),
|
||||
showToolWindowBadges: b("showToolWindowBadges"),
|
||||
widescreenToolWindows: b("widescreenToolWindows"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -284,6 +284,11 @@ function ToolWindowsGrid() {
|
||||
<>
|
||||
<BoundToggle k="appearance.showToolWindowBars" label="Show tool window bars" />
|
||||
<BoundToggle k="appearance.showToolWindowNames" label="Show tool window names" />
|
||||
<BoundToggle
|
||||
k="appearance.showToolWindowBadges"
|
||||
label="Show tool window badges"
|
||||
hint="Counts on the stripe icons, e.g. changed files or agent tasks needing input"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
right={
|
||||
|
||||
@@ -1985,6 +1985,8 @@
|
||||
"Show the parameter info popup in": "在以下时间后显示形参信息弹出窗口",
|
||||
"Show the selected coverage suite in editors and the project view": "在编辑器和项目视图中显示所选覆盖率套件",
|
||||
"Show tool window bars": "显示工具窗口栏",
|
||||
"Show tool window badges": "显示工具窗口角标",
|
||||
"Counts on the stripe icons, e.g. changed files or agent tasks needing input": "侧栏图标上的数字,如变更文件数、等待输入的智能体任务数",
|
||||
"Show tool window names": "显示工具窗口名称",
|
||||
"Show value tooltip on code selection": "选中代码时显示值提示",
|
||||
"Show value tooltip on mouse hover": "鼠标悬停时显示值工具提示",
|
||||
|
||||
@@ -359,8 +359,10 @@ function startStripeDrag(e: PointerEvent<HTMLButtonElement>, id: string) {
|
||||
}
|
||||
|
||||
function StripeBadge({ useBadge }: { useBadge: () => number | string | null }) {
|
||||
// Settings › Appearance › Tool Windows › "Show tool window badges".
|
||||
const showBadges = useProject((s) => s.settings?.appearance?.showToolWindowBadges) !== false;
|
||||
const value = useBadge();
|
||||
if (value === null || value === 0 || value === "") return null;
|
||||
if (!showBadges || value === null || value === 0 || value === "") return null;
|
||||
return <span className={styles.badge}>{typeof value === "number" && value > 99 ? "99+" : value}</span>;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { act, render, screen } from "@testing-library/react";
|
||||
import { afterEach, beforeEach, expect, it } from "vitest";
|
||||
import { create } from "zustand";
|
||||
import { useProject } from "@/platform/project";
|
||||
import { ToolWindowStripe } from "./ToolWindows";
|
||||
import { resetToolWindowLayout, useToolWindowLayout } from "./store";
|
||||
|
||||
beforeEach(() => {
|
||||
resetToolWindowLayout();
|
||||
useProject.setState({ settings: null });
|
||||
});
|
||||
|
||||
afterEach(() => useProject.setState({ settings: null }));
|
||||
|
||||
it("hides stripe counts immediately and restores the current count when enabled", () => {
|
||||
const useCount = create(() => ({ count: 3 }));
|
||||
render(
|
||||
<ToolWindowStripe
|
||||
side="left"
|
||||
visible={useToolWindowLayout.getState().visible}
|
||||
windows={[
|
||||
{
|
||||
id: "git",
|
||||
title: "Git",
|
||||
icon: "folder",
|
||||
anchor: "left",
|
||||
component: () => null,
|
||||
useBadge: () => useCount((s) => s.count),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
const button = screen.getByRole("button", { name: "Git" });
|
||||
expect(button).toHaveTextContent("3");
|
||||
act(() => useProject.setState({ settings: { appearance: { showToolWindowBadges: false } } }));
|
||||
expect(button).not.toHaveTextContent("3");
|
||||
act(() => useCount.setState({ count: 7 }));
|
||||
expect(button).not.toHaveTextContent("7");
|
||||
act(() => useProject.setState({ settings: { appearance: { showToolWindowBadges: true } } }));
|
||||
expect(button).toHaveTextContent("7");
|
||||
act(() => useCount.setState({ count: 0 }));
|
||||
expect(button).not.toHaveTextContent("0");
|
||||
});
|
||||
Reference in new issue
Заблокувати користувача