feat: 全站 PageShell 设计系统与专业 UI 统一
- 新增 PageShell/PageTabs/ContentPanel/PageLoading/PageEmpty 页面骨架 - index.css 设计令牌文档化,布局令牌与纯色主按钮(去除渐变粉彩) - 全站路由页接入 PageShell,云账单三 Tab 为标杆 - 主题体系:跟随系统 + 主流/开发者分组,新增 Dracula/Tokyo Night,One Dark 暖灰差异化 - 登录页/侧栏/顶栏去渐变光球,企业克制风 - 修复 AIAlertAnalyzer JSX 与构建依赖导入问题
This commit is contained in:
1 parent
1acb0c49af
commit
e363ded445
213 files changed
+7148
-6818
No files matched your search
@@ -320,10 +320,10 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardContent className="p-12 text-center">
|
||||
<Loader2 className="h-6 w-6 animate-spin mx-auto text-slate-500" />
|
||||
<p className="text-slate-500 mt-3 text-sm">加载中...</p>
|
||||
<Loader2 className="h-6 w-6 animate-spin mx-auto dg-text-muted" />
|
||||
<p className="dg-text-muted mt-3 text-sm">加载中...</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
@@ -331,8 +331,8 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
|
||||
if (!manifest) {
|
||||
return (
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<CardContent className="p-8 text-center text-slate-500">
|
||||
<Card className="dg-card">
|
||||
<CardContent className="p-8 text-center dg-text-muted">
|
||||
未获取到 manifest 数据,请使用 YAML 编辑模式直接修改。
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -342,20 +342,20 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* 更新策略 */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-slate-200 flex items-center gap-2">
|
||||
<RefreshCw className="h-4 w-4 text-blue-400" />更新策略 (Strategy)
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<RefreshCw className="h-4 w-4 dg-text-blue" />更新策略 (Strategy)
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 space-y-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<label className="flex items-center gap-1.5 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="radio" checked={strategyType === 'RollingUpdate'} onChange={() => setStrategyType('RollingUpdate')}
|
||||
className="accent-blue-500" />
|
||||
RollingUpdate(滚动更新)
|
||||
</label>
|
||||
<label className="flex items-center gap-1.5 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="radio" checked={strategyType === 'Recreate'} onChange={() => setStrategyType('Recreate')}
|
||||
className="accent-blue-500" />
|
||||
Recreate(重建)
|
||||
@@ -364,14 +364,14 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
{strategyType === 'RollingUpdate' && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">maxSurge(整数或百分比,超出期望副本数)</Label>
|
||||
<Label className="dg-text-muted text-xs">maxSurge(整数或百分比,超出期望副本数)</Label>
|
||||
<Input value={maxSurge} onChange={e => setMaxSurge(e.target.value)}
|
||||
placeholder="25%" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">maxUnavailable(整数或百分比,不可用上限)</Label>
|
||||
<Label className="dg-text-muted text-xs">maxUnavailable(整数或百分比,不可用上限)</Label>
|
||||
<Input value={maxUnavailable} onChange={e => setMaxUnavailable(e.target.value)}
|
||||
placeholder="25%" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -379,53 +379,53 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
</Card>
|
||||
|
||||
{/* 历史版本 / 进度 */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-slate-200 flex items-center gap-2">
|
||||
<Clock className="h-4 w-4 text-amber-400" />历史版本 & 进度
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<Clock className="h-4 w-4 dg-text-yellow" />历史版本 & 进度
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">revisionHistoryLimit(保留 RS 历史)</Label>
|
||||
<Label className="dg-text-muted text-xs">revisionHistoryLimit(保留 RS 历史)</Label>
|
||||
<Input type="number" value={revisionHistoryLimit} onChange={e => setRevisionHistoryLimit(e.target.value)}
|
||||
className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">progressDeadlineSeconds(升级超时秒数)</Label>
|
||||
<Label className="dg-text-muted text-xs">progressDeadlineSeconds(升级超时秒数)</Label>
|
||||
<Input type="number" value={progressDeadlineSeconds} onChange={e => setProgressDeadlineSeconds(e.target.value)}
|
||||
className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 容忍 (Tolerations) — 此前仅有状态无 UI // Logan.Li */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle className="text-sm text-slate-200">容忍 (Tolerations)</CardTitle>
|
||||
<Button size="sm" variant="outline" className="h-7 border-slate-700 text-slate-300 text-xs"
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)]">容忍 (Tolerations)</CardTitle>
|
||||
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
||||
onClick={() => setTolerations(prev => [...prev, { key: '', operator: 'Equal', value: '', effect: 'NoSchedule', tolerationSeconds: '' }])}>
|
||||
<Plus className="h-3 w-3 mr-1" />添加
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 space-y-2">
|
||||
{tolerations.length === 0 && <p className="text-xs text-slate-600">未配置容忍</p>}
|
||||
{tolerations.length === 0 && <p className="text-xs dg-text-muted">未配置容忍</p>}
|
||||
{tolerations.map((t, i) => (
|
||||
<div key={i} className="grid grid-cols-[1fr_80px_1fr_100px_80px_auto] gap-2 items-center">
|
||||
<Input value={t.key} placeholder="key" onChange={e => setTolerations(prev => prev.map((x, idx) => idx === i ? { ...x, key: e.target.value } : x))}
|
||||
className="h-7 bg-slate-800 border-slate-700 text-xs font-mono" />
|
||||
className="h-7 dg-input text-xs font-mono" />
|
||||
<select value={t.operator} onChange={e => setTolerations(prev => prev.map((x, idx) => idx === i ? { ...x, operator: e.target.value } : x))}
|
||||
className="h-7 bg-slate-800 border border-slate-700 rounded text-xs text-slate-300 px-1">
|
||||
className="h-7 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-1">
|
||||
<option value="Equal">Equal</option>
|
||||
<option value="Exists">Exists</option>
|
||||
</select>
|
||||
<Input value={t.value} placeholder="value" disabled={t.operator === 'Exists'}
|
||||
onChange={e => setTolerations(prev => prev.map((x, idx) => idx === i ? { ...x, value: e.target.value } : x))}
|
||||
className="h-7 bg-slate-800 border-slate-700 text-xs font-mono" />
|
||||
className="h-7 dg-input text-xs font-mono" />
|
||||
<select value={t.effect} onChange={e => setTolerations(prev => prev.map((x, idx) => idx === i ? { ...x, effect: e.target.value } : x))}
|
||||
className="h-7 bg-slate-800 border border-slate-700 rounded text-xs text-slate-300 px-1">
|
||||
className="h-7 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-1">
|
||||
<option value="">任意</option>
|
||||
<option value="NoSchedule">NoSchedule</option>
|
||||
<option value="PreferNoSchedule">PreferNoSchedule</option>
|
||||
@@ -433,8 +433,8 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
</select>
|
||||
<Input value={t.tolerationSeconds} placeholder="秒" disabled={t.effect !== 'NoExecute'}
|
||||
onChange={e => setTolerations(prev => prev.map((x, idx) => idx === i ? { ...x, tolerationSeconds: e.target.value } : x))}
|
||||
className="h-7 bg-slate-800 border-slate-700 text-xs font-mono" />
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-red-400" onClick={() => setTolerations(prev => prev.filter((_, idx) => idx !== i))}>
|
||||
className="h-7 dg-input text-xs font-mono" />
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-red" onClick={() => setTolerations(prev => prev.filter((_, idx) => idx !== i))}>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
@@ -457,17 +457,17 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
/>
|
||||
|
||||
{/* Pod 级别杂项 */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-slate-200 flex items-center gap-2">
|
||||
<Settings className="h-4 w-4 text-slate-400" />Pod 级别
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<Settings className="h-4 w-4 dg-text-secondary" />Pod 级别
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">dnsPolicy</Label>
|
||||
<Label className="dg-text-muted text-xs">dnsPolicy</Label>
|
||||
<select value={dnsPolicy} onChange={e => setDnsPolicy(e.target.value)}
|
||||
className="h-8 mt-1 w-full bg-slate-800 border border-slate-700 rounded text-xs text-slate-300 px-2">
|
||||
className="h-8 mt-1 w-full bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-2">
|
||||
<option value="ClusterFirst">ClusterFirst</option>
|
||||
<option value="ClusterFirstWithHostNet">ClusterFirstWithHostNet</option>
|
||||
<option value="Default">Default</option>
|
||||
@@ -475,57 +475,57 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">restartPolicy</Label>
|
||||
<Label className="dg-text-muted text-xs">restartPolicy</Label>
|
||||
<select value={restartPolicy} onChange={e => setRestartPolicy(e.target.value)}
|
||||
className="h-8 mt-1 w-full bg-slate-800 border border-slate-700 rounded text-xs text-slate-300 px-2">
|
||||
className="h-8 mt-1 w-full bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-2">
|
||||
<option value="Always">Always</option>
|
||||
<option value="OnFailure">OnFailure</option>
|
||||
<option value="Never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">schedulerName</Label>
|
||||
<Label className="dg-text-muted text-xs">schedulerName</Label>
|
||||
<Input value={schedulerName} onChange={e => setSchedulerName(e.target.value)}
|
||||
className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">terminationGracePeriodSeconds</Label>
|
||||
<Label className="dg-text-muted text-xs">terminationGracePeriodSeconds</Label>
|
||||
<Input type="number" value={terminationGracePeriodSeconds} onChange={e => setTerminationGracePeriodSeconds(e.target.value)}
|
||||
className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<Label className="text-slate-500 text-xs">serviceAccountName</Label>
|
||||
<Label className="dg-text-muted text-xs">serviceAccountName</Label>
|
||||
<Input value={serviceAccountName} onChange={e => setServiceAccountName(e.target.value)}
|
||||
placeholder="default" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="default" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Pod 安全上下文 */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-slate-200 flex items-center gap-2">
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<Shield className="h-4 w-4 text-rose-400" />Pod 安全上下文 (securityContext)
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">fsGroup</Label>
|
||||
<Label className="dg-text-muted text-xs">fsGroup</Label>
|
||||
<Input type="number" value={podFsGroup} onChange={e => setPodFsGroup(e.target.value)}
|
||||
placeholder="1000" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="1000" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">runAsUser</Label>
|
||||
<Label className="dg-text-muted text-xs">runAsUser</Label>
|
||||
<Input type="number" value={podRunAsUser} onChange={e => setPodRunAsUser(e.target.value)}
|
||||
placeholder="1000" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="1000" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-slate-500 text-xs">runAsGroup</Label>
|
||||
<Label className="dg-text-muted text-xs">runAsGroup</Label>
|
||||
<Input type="number" value={podRunAsGroup} onChange={e => setPodRunAsGroup(e.target.value)}
|
||||
placeholder="1000" className="h-8 mt-1 bg-slate-800 border-slate-700 text-slate-200 text-sm font-mono" />
|
||||
placeholder="1000" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||
</div>
|
||||
<div className="flex items-end pb-1">
|
||||
<label className="flex items-center gap-2 text-xs text-slate-400 cursor-pointer">
|
||||
<label className="flex items-center gap-2 text-xs dg-text-secondary cursor-pointer">
|
||||
<input type="checkbox" checked={podRunAsNonRoot} onChange={e => setPodRunAsNonRoot(e.target.checked)}
|
||||
className="accent-blue-500" />
|
||||
runAsNonRoot
|
||||
@@ -535,29 +535,29 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
</Card>
|
||||
|
||||
{/* 主机设置(M8 补全) */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-slate-200 flex items-center gap-2">
|
||||
<Network className="h-4 w-4 text-cyan-400" />主机设置 (Host Namespace)
|
||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<Network className="h-4 w-4 dg-text-cyan" />主机设置 (Host Namespace)
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
||||
<label className="flex items-center gap-2 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-2 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="checkbox" checked={hostNetwork} onChange={e => setHostNetwork(e.target.checked)}
|
||||
className="accent-blue-500" />
|
||||
hostNetwork(共享主机网络命名空间)
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-2 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="checkbox" checked={hostIPC} onChange={e => setHostIPC(e.target.checked)}
|
||||
className="accent-blue-500" />
|
||||
hostIPC(共享主机 IPC 命名空间)
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-2 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="checkbox" checked={hostPID} onChange={e => setHostPID(e.target.checked)}
|
||||
className="accent-blue-500" />
|
||||
hostPID(共享主机 PID 命名空间)
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-xs text-slate-300 cursor-pointer">
|
||||
<label className="flex items-center gap-2 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||
<input type="checkbox" checked={shareProcessNamespace} onChange={e => setShareProcessNamespace(e.target.checked)}
|
||||
className="accent-blue-500" />
|
||||
shareProcessNamespace(共享进程命名空间)
|
||||
@@ -578,7 +578,7 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
||||
|
||||
{/* 操作栏 */}
|
||||
<div className="flex justify-end gap-2 pt-2">
|
||||
<Button variant="outline" className="border-slate-700 text-slate-400" onClick={onCancel}>取消</Button>
|
||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}>取消</Button>
|
||||
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
||||
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
||||
保存
|
||||
|
||||
Reference in new issue
Block a user