refactor: 系统设置拆分顶部 Tab 分页
- 4 个 Tab:通用(外观主题+通知+语言区域)/ AI 助手 / 消息通知 / 用户目录(LDAP),复用编辑器 TopBar 下划线样式 - AI/消息通知/用户目录 Tab 标题带启用状态小圆点(绿=已启用) - 原「保存设置/恢复默认」按钮移入通用 Tab(只作用于外观与通知) - 内容区只渲染当前 Tab 卡片,纯布局重构,表单逻辑不变
This commit is contained in:
1 parent
97193eb090
commit
8bd323cc73
1 file changed
+65
-13
@@ -261,6 +261,21 @@ export default function SystemSettings() {
|
||||
toast.info('已恢复默认设置', { description: '仅本地重置,点击「保存设置」后生效' });
|
||||
};
|
||||
|
||||
// 顶部 Tab 分页:通用 / AI 助手 / 消息通知 / 用户目录
|
||||
type SettingsTab = 'general' | 'ai' | 'notify' | 'directory';
|
||||
const [activeTab, setActiveTab] = useState<SettingsTab>('general');
|
||||
|
||||
const aiOn = !!settings?.llmEnabled && !!settings?.llmApiKeySet;
|
||||
const larkOn = !!settings?.larkEnabled && !!settings?.larkWebhook;
|
||||
const ldapOn = !!settings?.ldapEnabled && !!settings?.ldapHost && !!settings?.ldapBindDN && !!settings?.ldapBaseDN;
|
||||
|
||||
const tabs: { id: SettingsTab; label: string; dot?: boolean | null }[] = [
|
||||
{ id: 'general', label: '通用' },
|
||||
{ id: 'ai', label: 'AI 助手', dot: aiOn },
|
||||
{ id: 'notify', label: '消息通知', dot: larkOn },
|
||||
{ id: 'directory', label: '用户目录', dot: ldapOn },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col" style={{ background: 'var(--canvas-bg)' }}>
|
||||
{/* Header */}
|
||||
@@ -273,21 +288,44 @@ export default function SystemSettings() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={handleReset} className="flex items-center gap-1 px-3 py-[5px] text-[12px] font-medium rounded-md border" style={{ borderColor: 'var(--border-color-light)', color: 'var(--text-secondary)' }}>
|
||||
<RotateCcw className="w-3.5 h-3.5" />恢复默认
|
||||
</div>
|
||||
|
||||
{/* Tab 栏(与流水线编辑器 TopBar 同款下划线样式) */}
|
||||
<div className="px-5 border-b flex items-center gap-0 flex-shrink-0" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
{tabs.map((t) => (
|
||||
<button
|
||||
key={t.id}
|
||||
onClick={() => setActiveTab(t.id)}
|
||||
className="relative px-3 py-2 text-[12px] font-medium flex items-center gap-1.5"
|
||||
style={{ color: activeTab === t.id ? 'var(--accent-blue)' : 'var(--text-secondary)' }}
|
||||
>
|
||||
{t.label}
|
||||
{t.dot != null && (
|
||||
<span className="w-1.5 h-1.5 rounded-full" style={{ background: t.dot ? '#1a7f37' : 'var(--text-tertiary)', opacity: t.dot ? 1 : 0.5 }} title={t.dot ? '已启用' : '未启用'} />
|
||||
)}
|
||||
{activeTab === t.id && (
|
||||
<span className="absolute bottom-0 left-1 right-1 h-0.5 rounded-full" style={{ background: 'var(--accent-blue)' }} />
|
||||
)}
|
||||
</button>
|
||||
<button onClick={() => saveMutation.mutate()} disabled={saveMutation.isPending}
|
||||
className="flex items-center gap-1 px-3 py-[5px] text-[12px] font-medium rounded-md text-white disabled:opacity-60" style={{ background: 'var(--accent-blue)' }}>
|
||||
{saveMutation.isPending ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Save className="w-3.5 h-3.5" />}
|
||||
{saveMutation.isPending ? '保存中...' : '保存设置'}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar p-5">
|
||||
<div className="max-w-3xl mx-auto space-y-4">
|
||||
{activeTab === 'general' && (
|
||||
<>
|
||||
{/* 外观主题保存/恢复操作 */}
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<button onClick={handleReset} className="flex items-center gap-1 px-3 py-[5px] text-[12px] font-medium rounded-md border" style={{ borderColor: 'var(--border-color-light)', color: 'var(--text-secondary)' }}>
|
||||
<RotateCcw className="w-3.5 h-3.5" />恢复默认
|
||||
</button>
|
||||
<button onClick={() => saveMutation.mutate()} disabled={saveMutation.isPending}
|
||||
className="flex items-center gap-1 px-3 py-[5px] text-[12px] font-medium rounded-md text-white disabled:opacity-60" style={{ background: 'var(--accent-blue)' }}>
|
||||
{saveMutation.isPending ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Save className="w-3.5 h-3.5" />}
|
||||
{saveMutation.isPending ? '保存中...' : '保存设置'}
|
||||
</button>
|
||||
</div>
|
||||
{/* Appearance */}
|
||||
<div className="rounded-lg border overflow-hidden" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="px-4 py-2.5 border-b flex items-center gap-2" style={{ borderColor: 'var(--border-color)', background: 'var(--panel-bg-secondary)' }}>
|
||||
@@ -478,10 +516,13 @@ export default function SystemSettings() {
|
||||
<p className="text-[11px]" style={{ color: 'var(--text-tertiary)' }}>语言与时区暂未生效,仅作展示</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{activeTab === 'ai' && (
|
||||
<>
|
||||
{/* AI 助手配置 */}
|
||||
<div className="rounded-lg border overflow-hidden mt-4" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="rounded-lg border overflow-hidden" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="px-5 py-3 border-b flex items-center justify-between" style={{ borderColor: 'var(--border-color)' }}>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[13px] font-semibold" style={{ color: 'var(--text-primary)' }}>AI 助手(智能发布)</span>
|
||||
@@ -555,9 +596,13 @@ export default function SystemSettings() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{activeTab === 'notify' && (
|
||||
<>
|
||||
{/* 飞书 / Lark 通知 */}
|
||||
<div className="rounded-lg border overflow-hidden mt-4" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="rounded-lg border overflow-hidden" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="px-5 py-3 border-b flex items-center justify-between" style={{ borderColor: 'var(--border-color)' }}>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[13px] font-semibold" style={{ color: 'var(--text-primary)' }}>飞书 / Lark 群通知</span>
|
||||
@@ -593,9 +638,13 @@ export default function SystemSettings() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{activeTab === 'directory' && (
|
||||
<>
|
||||
{/* LDAP 目录服务 */}
|
||||
<div className="rounded-lg border overflow-hidden mt-4" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="rounded-lg border overflow-hidden" style={{ background: 'var(--panel-bg)', borderColor: 'var(--border-color)' }}>
|
||||
<div className="px-5 py-3 border-b flex items-center justify-between" style={{ borderColor: 'var(--border-color)' }}>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[13px] font-semibold" style={{ color: 'var(--text-primary)' }}>LDAP 目录服务</span>
|
||||
@@ -693,6 +742,9 @@ export default function SystemSettings() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user