feat: 设置语言精简中英+补全时区;构建节点磁盘显示;浏览器 favicon
- 系统设置:界面语言仅保留 简体中文/English;时区按 亚/欧/美/大洋洲 分组补全 22 个常用时区 - 构建节点:BuildNode 新增 diskInfo 字段(模型/CRUD/seed),卡片显示 磁盘用量(未上报显示 —),添加/编辑弹窗可维护 - 新增 favicon.svg(主题渐变火箭图标),index.html 注入 icon 链接
This commit is contained in:
1 parent
581d0a8351
commit
a3b4637e19
7 files changed
+71
-10
No files matched your search
@@ -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>
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user