feat: 设置语言精简中英+补全时区;构建节点磁盘显示;浏览器 favicon

- 系统设置:界面语言仅保留 简体中文/English;时区按 亚/欧/美/大洋洲
  分组补全 22 个常用时区
- 构建节点:BuildNode 新增 diskInfo 字段(模型/CRUD/seed),卡片显示
  磁盘用量(未上报显示 —),添加/编辑弹窗可维护
- 新增 favicon.svg(主题渐变火箭图标),index.html 注入 icon 链接
This commit is contained in:
Logan.Li committed 2026-10-27 09:16:42 +08:00
1 parent 581d0a8351
commit a3b4637e19
7 files changed
+71 -10

No files matched your search

+1
View File
@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>FlowStack · 发布系统</title>
</head>
<body>
+15
View File
@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#0969da"/>
<stop offset="1" stop-color="#8250df"/>
</linearGradient>
</defs>
<rect x="4" y="4" width="56" height="56" rx="14" fill="url(#g)"/>
<g transform="translate(32 33) rotate(45) translate(-11 -13)">
<path d="M11 0 C17 4 20 10 20 17 L20 22 L14 22 C8 22 3 19 0 13 L0 0 Z" fill="#fff" opacity="0.95"/>
<circle cx="13" cy="9" r="3" fill="#0969da"/>
<path d="M0 13 L-6 20 L1 18 Z" fill="#ffd23e"/>
<path d="M20 22 L26 28 L19 27 Z" fill="#ffd23e" opacity="0.9"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 671 B

+18 -4
View File
@@ -10,6 +10,7 @@ import {
Trash2,
Tag,
Zap,
HardDrive,
} from 'lucide-react';
import { toast } from 'sonner';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
@@ -60,9 +61,10 @@ interface NodeForm {
labels: string;
maxConcurrency: string;
workspacePath: string;
diskInfo: string;
}
const emptyForm: NodeForm = { name: '', ip: '', labels: '', maxConcurrency: '2', workspacePath: '/var/lib/flowstack/workspace' };
const emptyForm: NodeForm = { name: '', ip: '', labels: '', maxConcurrency: '2', workspacePath: '/var/lib/flowstack/workspace', diskInfo: '' };
const inputStyle = {
background: 'var(--panel-bg-secondary)',
@@ -92,6 +94,7 @@ export default function BuildNodeManager() {
labels: parseJsonArray(node.labels).join(','),
maxConcurrency: String(node.maxConcurrency ?? 2),
workspacePath: node.workspacePath ?? '',
diskInfo: node.diskInfo ?? '',
}
: emptyForm,
);
@@ -152,6 +155,7 @@ export default function BuildNodeManager() {
labels: JSON.stringify(splitComma(form.labels)),
maxConcurrency: Number(form.maxConcurrency) || 1,
workspacePath: form.workspacePath.trim(),
diskInfo: form.diskInfo.trim(),
},
});
};
@@ -292,10 +296,16 @@ export default function BuildNodeManager() {
</div>
</div>
{/* Info: 工作空间 / 心跳(后端暂无 CPU/内存/磁盘数据) */}
<div className="grid grid-cols-2 gap-3 text-[11px]">
{/* Info: 磁盘 / 工作空间 / 心跳 */}
<div className="grid grid-cols-3 gap-3 text-[11px]">
<div className="flex items-center gap-1.5 min-w-0">
<span className="flex-shrink-0" style={{ color: 'var(--text-tertiary)' }}>工作空间</span>
<HardDrive className="w-3 h-3 flex-shrink-0" style={{ color: 'var(--text-tertiary)' }} />
<span className="font-mono truncate" style={{ color: 'var(--text-secondary)' }} title={node.diskInfo ? `磁盘 ${node.diskInfo}` : '磁盘未上报'}>
{node.diskInfo || '—'}
</span>
</div>
<div className="flex items-center gap-1.5 min-w-0">
<span className="flex-shrink-0" style={{ color: 'var(--text-tertiary)' }}>空间</span>
<span className="font-mono truncate" style={{ color: 'var(--text-secondary)' }} title={node.workspacePath}>
{node.workspacePath || '—'}
</span>
@@ -366,6 +376,10 @@ export default function BuildNodeManager() {
<Input className="h-8 text-[12px] font-mono" style={inputStyle} value={form.workspacePath} onChange={(e) => setForm({ ...form, workspacePath: e.target.value })} placeholder="/var/lib/flowstack/workspace" />
</div>
</div>
<div className="space-y-1.5">
<Label className="text-[12px]" style={{ color: 'var(--text-secondary)' }}>磁盘用量</Label>
<Input className="h-8 text-[12px] font-mono" style={inputStyle} value={form.diskInfo} onChange={(e) => setForm({ ...form, diskInfo: e.target.value })} placeholder="如 45G/200G(已用/总量)" />
</div>
</div>
<DialogFooter>
<button
+32 -2
View File
@@ -302,11 +302,41 @@ export default function SystemSettings() {
<div className="grid grid-cols-2 gap-3">
<div><label className="block text-[12px] font-medium mb-1" style={{ color: 'var(--text-secondary)' }}>界面语言</label>
<select className="w-full px-3 py-[6px] text-[13px] rounded-md border outline-none" style={{ background: 'var(--panel-bg-secondary)', borderColor: 'var(--border-color-light)', color: 'var(--text-primary)' }}>
<option>简体中文</option><option>English</option><option>日本語</option>
<option>简体中文</option><option>English</option>
</select></div>
<div><label className="block text-[12px] font-medium mb-1" style={{ color: 'var(--text-secondary)' }}>时区</label>
<select className="w-full px-3 py-[6px] text-[13px] rounded-md border outline-none" style={{ background: 'var(--panel-bg-secondary)', borderColor: 'var(--border-color-light)', color: 'var(--text-primary)' }}>
<option>Asia/Shanghai (UTC+8)</option><option>UTC</option><option>America/New_York</option>
<optgroup label="亚洲">
<option>Asia/Shanghai (UTC+8) 中国标准时间</option>
<option>Asia/Hong_Kong (UTC+8) 香港时间</option>
<option>Asia/Taipei (UTC+8) 台北时间</option>
<option>Asia/Singapore (UTC+8) 新加坡时间</option>
<option>Asia/Tokyo (UTC+9) 日本时间</option>
<option>Asia/Seoul (UTC+9) 韩国时间</option>
<option>Asia/Bangkok (UTC+7) 泰国时间</option>
<option>Asia/Dubai (UTC+4) 迪拜时间</option>
</optgroup>
<optgroup label="欧洲">
<option>Europe/London (UTC+0/+1) 英国时间</option>
<option>Europe/Berlin (UTC+1/+2) 中欧时间</option>
<option>Europe/Paris (UTC+1/+2) 法国时间</option>
<option>Europe/Moscow (UTC+3) 莫斯科时间</option>
<option>Europe/Istanbul (UTC+3) 土耳其时间</option>
</optgroup>
<optgroup label="美洲">
<option>America/New_York (UTC-5/-4) 美东时间</option>
<option>America/Chicago (UTC-6/-5) 美中时间</option>
<option>America/Denver (UTC-7/-6) 美山时间</option>
<option>America/Los_Angeles (UTC-8/-7) 美西时间</option>
<option>America/Sao_Paulo (UTC-3) 巴西时间</option>
</optgroup>
<optgroup label="大洋洲 / 非洲 / 标准">
<option>Australia/Sydney (UTC+10/+11) 澳洲东部时间</option>
<option>Australia/Perth (UTC+8) 澳洲西部时间</option>
<option>Africa/Cairo (UTC+2) 埃及时间</option>
<option>Africa/Johannesburg (UTC+2) 南非时间</option>
<option>UTC 协调世界时</option>
</optgroup>
</select></div>
</div>
<p className="text-[11px]" style={{ color: 'var(--text-tertiary)' }}>语言与时区暂未生效,仅作展示</p>