feat(visual-config): enhance overview layout and improve visual section translations

This commit is contained in:
Supra4E8C
2026-03-22 17:35:06 +08:00
Unverified
parent 868ac6b61b
commit 8758a75b39
6 changed files with 74 additions and 82 deletions
@@ -75,6 +75,9 @@
.overview {
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
gap: 18px;
border-radius: 30px;
border: 1px solid color-mix(in srgb, var(--border-color) 78%, transparent);
background:
@@ -106,22 +109,12 @@
}
}
.overviewGrid {
.overviewHeader {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1.05fr) minmax(260px, 0.95fr);
gap: 28px;
@include mobile {
grid-template-columns: minmax(0, 1fr);
gap: 20px;
}
}
.overviewLead {
display: flex;
flex-direction: column;
gap: 16px;
align-items: center;
justify-content: space-between;
gap: 12px;
min-width: 0;
}
@@ -152,28 +145,19 @@
background: var(--warning-bg);
}
.overviewTitle {
margin: 0;
max-width: 18ch;
color: var(--text-primary);
font-size: clamp(28px, 4vw, 44px);
line-height: 0.98;
letter-spacing: -0.03em;
}
.overviewNotice {
margin: 0;
max-width: 52ch;
color: var(--text-secondary);
font-size: 15px;
line-height: 1.7;
}
.overviewFocusList {
display: flex;
flex-direction: column;
justify-content: center;
gap: 10px;
position: relative;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
@media (max-width: 1200px) {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@include mobile {
grid-template-columns: minmax(0, 1fr);
}
}
.overviewFocusLink {
+38 -42
View File
@@ -351,51 +351,47 @@ export function VisualConfigEditor({
return (
<div className={styles.visualEditor}>
<div className={styles.overview}>
<div className={styles.overviewGrid}>
<div className={styles.overviewLead}>
<div className={styles.overviewMeta}>
<span className={styles.overviewPill}>
{t('config_management.tabs.visual', { defaultValue: '可视化编辑' })}
<div className={styles.overviewHeader}>
<div className={styles.overviewMeta}>
<span className={styles.overviewPill}>
{t('config_management.visual.quick_jump', { defaultValue: '快速跳转' })}
</span>
{hasValidationIssues ? (
<span className={`${styles.overviewPill} ${styles.overviewPillWarning}`}>
{t('config_management.visual.validation.validation_blocked')}
</span>
{hasValidationIssues ? (
<span className={`${styles.overviewPill} ${styles.overviewPillWarning}`}>
{t('config_management.visual.validation.validation_blocked')}
) : null}
</div>
</div>
<div className={styles.overviewFocusList}>
{focusSections.map((section) => {
const Icon = section.icon;
return (
<button
key={section.id}
type="button"
className={`${styles.overviewFocusLink} ${
activeSectionId === section.id ? styles.overviewFocusLinkActive : ''
}`}
onClick={() => handleSectionJump(section.id)}
>
<span className={styles.focusIcon}>
<Icon size={16} />
</span>
) : null}
</div>
<h2 className={styles.overviewTitle}>{t('config_management.editor_title')}</h2>
<p className={styles.overviewNotice}>{t('config_management.visual.notice')}</p>
</div>
<div className={styles.overviewFocusList}>
{focusSections.map((section) => {
const Icon = section.icon;
return (
<button
key={section.id}
type="button"
className={`${styles.overviewFocusLink} ${
activeSectionId === section.id ? styles.overviewFocusLinkActive : ''
}`}
onClick={() => handleSectionJump(section.id)}
>
<span className={styles.focusIcon}>
<Icon size={16} />
<span className={styles.focusCopy}>
<span className={styles.focusTitle}>{section.title}</span>
<span className={styles.focusDescription}>{section.description}</span>
</span>
{section.errorCount > 0 ? (
<span className={styles.navBadge} aria-hidden="true">
{section.errorCount}
</span>
<span className={styles.focusCopy}>
<span className={styles.focusTitle}>{section.title}</span>
<span className={styles.focusDescription}>{section.description}</span>
</span>
{section.errorCount > 0 ? (
<span className={styles.navBadge} aria-hidden="true">
{section.errorCount}
</span>
) : null}
</button>
);
})}
</div>
) : null}
</button>
);
})}
</div>
</div>
+2 -1
View File
@@ -1161,7 +1161,8 @@
"source": "Source File Editor"
},
"visual": {
"notice": "Visual mode only covers common supported fields. Other config.yaml fields still need to be reviewed and edited in source mode.",
"notice": "Visual mode covers common fields. Review or edit unsupported config.yaml entries in source mode.",
"quick_jump": "Quick Jump",
"sections": {
"server": {
"title": "Server Configuration",
+2 -1
View File
@@ -1164,7 +1164,8 @@
"source": "Редактор файла"
},
"visual": {
"notice": "Визуальный режим покрывает только часто используемые и уже поддерживаемые поля. Остальные поля `config.yaml` по-прежнему нужно проверять или редактировать в режиме исходника.",
"notice": "Визуальный режим охватывает основные поля. Остальные параметры config.yaml по-прежнему нужно проверять или редактировать в режиме исходника.",
"quick_jump": "Быстрый переход",
"sections": {
"server": {
"title": "Настройки сервера",
+2 -1
View File
@@ -1161,7 +1161,8 @@
"source": "源文件编辑"
},
"visual": {
"notice": "可视化模式目前只覆盖常用且已支持的字段,不代表已经覆盖 `config.yaml` 的全部配置项;其他字段仍需在源模式查看或编辑。",
"notice": "可视化模式覆盖常用字段,未覆盖的配置仍需在源文件模式查看或编辑。",
"quick_jump": "快速跳转",
"sections": {
"server": {
"title": "服务器配置",
+11 -2
View File
@@ -462,13 +462,22 @@ export function ConfigPage() {
</div>
);
const pageEyebrow =
activeTab === 'visual'
? t('config_management.tabs.visual', { defaultValue: '可视化编辑' })
: t('config_management.tabs.source', { defaultValue: '源文件编辑' });
const pageDescription =
activeTab === 'visual'
? t('config_management.visual.notice')
: t('config_management.description');
return (
<div className={styles.container}>
<div className={styles.pageHeader}>
<div className={styles.pageHeaderCopy}>
<span className={styles.pageEyebrow}>{t('config_management.editor_title')}</span>
<span className={styles.pageEyebrow}>{pageEyebrow}</span>
<h1 className={styles.pageTitle}>{t('config_management.title')}</h1>
<p className={styles.description}>{t('config_management.description')}</p>
<p className={styles.description}>{pageDescription}</p>
</div>
<div className={styles.pageMeta}>