mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 16:08:05 +00:00
feat(settings): Group page description, collapsed page tree and a seamless title bar
- Group pages open with a short description and list their pages as indented links. - The page tree starts collapsed, expanding only the current page's ancestors. - The Settings window title bar sits on the dialog surface without a hairline.
This commit is contained in:
@@ -147,24 +147,37 @@
|
||||
}
|
||||
|
||||
.groupPage {
|
||||
padding-top: 8px;
|
||||
}
|
||||
.groupDescription {
|
||||
margin: 0 0 14px;
|
||||
max-width: 720px;
|
||||
color: var(--fg);
|
||||
line-height: 1.45;
|
||||
}
|
||||
.groupLinks {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 420px;
|
||||
align-items: flex-start;
|
||||
gap: 2px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
.groupLink {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 28px;
|
||||
padding: 0 8px;
|
||||
border-radius: var(--radius-row);
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: none;
|
||||
color: var(--link);
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.groupLink:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
.groupLink:focus-visible {
|
||||
outline: 2px solid var(--focus-ring, var(--accent));
|
||||
}
|
||||
|
||||
.footerStatus {
|
||||
|
||||
@@ -42,20 +42,46 @@ import { PageErrorBoundary } from "./PageErrorBoundary";
|
||||
import styles from "./SettingsDialog.module.css";
|
||||
import { tx } from "@/platform/i18n";
|
||||
|
||||
/** Keys of the nodes above `key`, root first. */
|
||||
function ancestorKeys(nodes: readonly PageNode[], key: string): string[] {
|
||||
for (const n of nodes) {
|
||||
if (n.key === key) return [];
|
||||
const sub = ancestorKeys(n.children, key);
|
||||
if (sub.length || n.children.some((c) => c.key === key)) return [n.key, ...sub];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function firstPage(nodes: readonly PageNode[]): string | null {
|
||||
const list = flatten(nodes).filter((n) => n.page);
|
||||
return (list.find((n) => n.matched) ?? list[0])?.key ?? null;
|
||||
}
|
||||
|
||||
const GROUP_DESCRIPTIONS: Record<string, string> = {
|
||||
"Appearance & Behavior":
|
||||
"Customize IDE appearance and behavior: change themes and font size, configure system settings and notifications.",
|
||||
Editor: "Configure code editing: completion, folding, tabs, fonts, colors, code style and inspections.",
|
||||
"Build, Execution, Deployment": "Configure build tools, run configurations, debugger and deployment.",
|
||||
"Languages & Frameworks": "Configure language servers, interpreters, SDKs and framework support.",
|
||||
Tools: "Configure external tools, terminal, database and other integrations.",
|
||||
};
|
||||
|
||||
function GroupPage({ node }: { node: PageNode }) {
|
||||
const description = GROUP_DESCRIPTIONS[node.title];
|
||||
return (
|
||||
<div className={styles.groupPage}>
|
||||
{node.children.map((c) => (
|
||||
<button key={c.key} type="button" className={styles.groupLink} onClick={() => selectPage(c.key)}>
|
||||
<SearchLabel text={c.title} />
|
||||
<Icon name="chevron-right" size={12} />
|
||||
</button>
|
||||
))}
|
||||
{description && (
|
||||
<p className={styles.groupDescription}>
|
||||
<T>{description}</T>
|
||||
</p>
|
||||
)}
|
||||
<div className={styles.groupLinks}>
|
||||
{node.children.map((c) => (
|
||||
<button key={c.key} type="button" className={styles.groupLink} onClick={() => selectPage(c.key)}>
|
||||
<SearchLabel text={c.title} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -263,7 +289,7 @@ export function SettingsLayout() {
|
||||
getLabel={(n) => tx(n.title)}
|
||||
getChildren={(n) => (n.children.length ? n.children : undefined)}
|
||||
isExpandable={(n) => n.children.length > 0}
|
||||
defaultExpanded={all.filter((n) => n.children.length).map((n) => n.key)}
|
||||
defaultExpanded={current ? ancestorKeys(tree, current.key) : []}
|
||||
expanded={query ? expanded : undefined}
|
||||
selected={current ? new Set([current.key]) : new Set()}
|
||||
onSelectionChange={(_sel, node) => node && selectPage(node.key)}
|
||||
|
||||
@@ -4198,5 +4198,10 @@
|
||||
"0 results": "0 个结果",
|
||||
"Time the agent took to answer": "智能体回答所用的时间",
|
||||
"Edit and Resend": "编辑后重新发送",
|
||||
"Send Again": "再次发送"
|
||||
"Send Again": "再次发送",
|
||||
"Customize IDE appearance and behavior: change themes and font size, configure system settings and notifications.": "自定义 IDE 的外观和行为:更改主题和字号,配置系统设置和通知。",
|
||||
"Configure code editing: completion, folding, tabs, fonts, colors, code style and inspections.": "配置代码编辑:补全、折叠、标签页、字体、配色、代码样式和检查。",
|
||||
"Configure build tools, run configurations, debugger and deployment.": "配置构建工具、运行配置、调试器和部署。",
|
||||
"Configure language servers, interpreters, SDKs and framework support.": "配置语言服务器、解释器、SDK 和框架支持。",
|
||||
"Configure external tools, terminal, database and other integrations.": "配置外部工具、终端、数据库和其他集成。"
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
background: var(--bg-elev);
|
||||
box-shadow: inset 0 -1px 0 var(--border);
|
||||
}
|
||||
/* Dialog window (Settings): the title sits on the dialog surface, no hairline. */
|
||||
.dialogBar {
|
||||
background: var(--bg-dialog, var(--bg-elev));
|
||||
box-shadow: none;
|
||||
}
|
||||
.windowTitle {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -292,7 +292,7 @@ export function TitleBar({
|
||||
const entry = (id: string) => <ToolbarEntry key={id} id={id} items={map} />;
|
||||
return (
|
||||
<header
|
||||
className={clsx(className, minimal && styles.minimal)}
|
||||
className={clsx(className, minimal && styles.minimal, dialog && styles.dialogBar)}
|
||||
data-tauri-drag-region
|
||||
onContextMenu={(e) => {
|
||||
if (minimal || e.defaultPrevented) return;
|
||||
|
||||
Reference in New Issue
Block a user