压平infra和config结构

This commit is contained in:
hy 2026-04-23 12:37:19 +08:00
parent cdb84c8c96
commit 799038ad3b
3 changed files with 187 additions and 130 deletions

View File

@ -2220,9 +2220,41 @@ body.auth-page {
.config-workbench-panel { .config-workbench-panel {
position: relative; position: relative;
background: background: var(--panel);
linear-gradient(180deg, color-mix(in oklab, var(--panel-strong) 96%, var(--accent-soft)) 0%, color-mix(in oklab, var(--panel) 98%, var(--panel-muted)) 100%); box-shadow: none;
box-shadow: var(--shadow-soft), inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 74%, transparent); }
.config-workbench-panel::before {
content: none;
}
.config-head-strip {
margin-bottom: 12px;
padding: 0 0 10px;
border: 0;
border-bottom: 1px solid var(--line);
border-radius: 0;
background: transparent;
}
.config-head-strip .metadata-strip {
gap: 8px;
}
.config-inline-strip {
margin-bottom: 10px;
padding: 0 0 8px;
border: 0;
border-bottom: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
border-radius: 0;
background: transparent;
box-shadow: none;
}
.config-inline-strip span {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
} }
.infra-overview-panel { .infra-overview-panel {
@ -2240,13 +2272,13 @@ body.auth-page {
.mongo-stat-group { .mongo-stat-group {
position: relative; position: relative;
display: grid; display: grid;
gap: 10px; gap: 8px;
padding: 12px; padding: 10px 12px;
border: 1px solid var(--line); border: 1px solid var(--line);
border-radius: 14px; border-radius: 12px;
background: var(--panel-muted); background: var(--panel-strong);
transition: transform 180ms ease, border-color 180ms ease, background 180ms ease, box-shadow 180ms ease; transition: border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
box-shadow: inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 70%, transparent); box-shadow: none;
} }
.infra-focus-card::before, .infra-focus-card::before,
@ -2255,17 +2287,17 @@ body.auth-page {
content: ""; content: "";
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; top: 8px;
top: 0; bottom: 8px;
height: 3px; width: 3px;
background: linear-gradient(90deg, color-mix(in oklab, var(--accent) 48%, var(--ok)) 0%, transparent 76%); border-radius: 999px;
background: color-mix(in oklab, var(--accent) 48%, var(--ok));
} }
.infra-focus-card:hover, .infra-focus-card:hover,
.mongo-stat-group:hover { .mongo-stat-group:hover {
transform: translateY(-1px);
border-color: color-mix(in oklab, var(--accent) 22%, var(--line)); border-color: color-mix(in oklab, var(--accent) 22%, var(--line));
box-shadow: var(--shadow-soft), inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 70%, transparent); box-shadow: none;
} }
.infra-focus-head { .infra-focus-head {
@ -2335,26 +2367,14 @@ body.auth-page {
margin-bottom: 12px; margin-bottom: 12px;
} }
.mongo-secondary-grid { .infra-inline-strip {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-bottom: 0;
gap: 10px; padding: 0 0 8px;
} border: 0;
border-bottom: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
.mongo-mini-card { border-radius: 0;
min-height: 0; background: transparent;
padding: 9px 10px; box-shadow: none;
border-radius: 14px;
background: linear-gradient(180deg, color-mix(in oklab, var(--panel-strong) 96%, var(--accent-soft)) 0%, var(--panel-muted) 100%);
}
.mongo-mini-card small {
font-size: 10px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.mongo-mini-card strong {
margin-top: 5px;
} }
.mongo-detail-stack { .mongo-detail-stack {
@ -2363,12 +2383,13 @@ body.auth-page {
.mongo-detail-block { .mongo-detail-block {
display: grid; display: grid;
gap: 10px; gap: 8px;
padding: 12px; padding: 10px 0 0;
border: 1px solid var(--line); border: 0;
border-radius: 16px; border-top: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
background: linear-gradient(180deg, color-mix(in oklab, var(--panel-muted) 95%, var(--panel-strong)) 0%, var(--panel-strong) 100%); border-radius: 0;
box-shadow: inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 72%, transparent); background: transparent;
box-shadow: none;
} }
.mongo-detail-head { .mongo-detail-head {
@ -2384,9 +2405,9 @@ body.auth-page {
.mongo-detail-head .panel-title p { .mongo-detail-head .panel-title p {
margin-top: 3px; margin-top: 3px;
font-size: 10px; font-size: 11px;
letter-spacing: 0.08em; letter-spacing: 0.02em;
text-transform: uppercase; text-transform: none;
} }
.mongo-detail-block .table-wrap { .mongo-detail-block .table-wrap {
@ -2407,6 +2428,17 @@ body.auth-page {
box-shadow: inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 72%, transparent); box-shadow: inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 72%, transparent);
} }
.config-only-layout > .config-sidebar {
gap: 6px;
max-height: calc(100vh - 124px);
padding: 0 10px 0 0;
border: 0;
border-right: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
border-radius: 0;
background: transparent;
box-shadow: none;
}
.config-sidebar-head { .config-sidebar-head {
display: grid; display: grid;
gap: 6px; gap: 6px;
@ -2718,6 +2750,30 @@ body.auth-page {
text-align: right; text-align: right;
} }
.config-history-list {
gap: 0;
border: 1px solid var(--line);
border-radius: 12px;
overflow: hidden;
background: var(--panel-strong);
}
.config-history-list .activity-item {
border: 0;
border-bottom: 1px solid color-mix(in oklab, var(--line) 92%, var(--panel-strong));
border-radius: 0;
background: transparent;
}
.config-history-list .activity-item:last-child {
border-bottom: 0;
}
.config-history-list .activity-item:hover {
transform: none;
background: color-mix(in oklab, var(--accent-soft) 14%, var(--panel-strong));
}
.release-status-strip { .release-status-strip {
margin-top: 8px; margin-top: 8px;
padding: 12px; padding: 12px;
@ -3235,14 +3291,69 @@ body.auth-page {
.infra-mini-card { .infra-mini-card {
position: relative; position: relative;
overflow: hidden; display: grid;
gap: 8px;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: 12px;
background: var(--panel-strong);
}
.infra-mini-card::before {
content: "";
position: absolute;
left: 0;
top: 8px;
bottom: 8px;
width: 3px;
border-radius: 999px;
background: color-mix(in oklab, var(--accent) 44%, var(--group-app));
}
.infra-mini-head {
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
background: linear-gradient(180deg, color-mix(in oklab, var(--panel-strong) 94%, var(--accent-soft)) 0%, color-mix(in oklab, var(--panel) 98%, var(--panel-muted)) 100%); gap: 10px;
align-items: flex-start;
}
.infra-mini-title {
display: grid;
gap: 4px;
}
.infra-mini-title strong {
font-size: 13px;
}
.infra-mini-title small {
color: var(--muted);
font-size: 11px;
} }
.infra-mini-metrics { .infra-mini-metrics {
margin-bottom: 12px; display: flex;
gap: 6px 12px;
flex-wrap: wrap;
align-items: center;
}
.infra-mini-metric {
display: inline-flex;
gap: 6px;
align-items: baseline;
min-width: 0;
}
.infra-mini-metric small {
color: var(--muted);
font-size: 10px;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.infra-mini-metric strong {
font-size: 12px;
} }
.infra-card-action { .infra-card-action {
@ -4317,6 +4428,12 @@ body.auth-page {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.config-only-layout > .config-sidebar {
padding: 0 0 10px;
border-right: 0;
border-bottom: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
}
.mongo-panel-grid.narrow { .mongo-panel-grid.narrow {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
@ -4484,7 +4601,8 @@ body.auth-page {
.release-action-bar, .release-action-bar,
.log-viewer-head, .log-viewer-head,
.compact-workbench-head, .compact-workbench-head,
.release-service-head { .release-service-head,
.infra-mini-head {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
} }

View File

@ -1556,9 +1556,6 @@ createApp({
releaseHistoryRows() { releaseHistoryRows() {
return this.releaseHistory.slice(0, 8); return this.releaseHistory.slice(0, 8);
}, },
activeConfigTabLabel() {
return this.configTabs.find((item) => item.id === this.configTab)?.label || "";
},
configContextLabel() { configContextLabel() {
if (this.configTab === "nacos") { if (this.configTab === "nacos") {
return `Nacos / ${this.nacosConfig.namespaceName || "default"} / ${this.filteredNacosConfigs.length}`; return `Nacos / ${this.nacosConfig.namespaceName || "default"} / ${this.filteredNacosConfigs.length}`;

View File

@ -809,33 +809,20 @@
</template> </template>
<template v-if="!showLoadingSkeleton && activeView === 'infra'"> <template v-if="!showLoadingSkeleton && activeView === 'infra'">
<section class="panel task-page-head">
<header class="panel-header">
<div class="panel-title">
<h2>基础设施</h2>
</div>
<div class="panel-meta">
<span class="badge neutral">Nacos {{ payload.nacos && payload.nacos.ok ? '在线' : '异常' }}</span>
<span class="badge neutral">Mongo {{ payload.mongo && payload.mongo.ok ? '在线' : '异常' }}</span>
<span :class="['badge', (summary.hostMetricDown || 0) > 0 ? 'warn' : 'neutral']">TAT {{ summary.hostMetricOk || 0 }} / {{ summary.hostTotal || 0 }}</span>
</div>
</header>
</section>
<section class="overview-infra-grid"> <section class="overview-infra-grid">
<article v-for="card in overviewInfraCards" :key="'infra-' + card.key" class="panel infra-mini-card"> <article v-for="card in overviewInfraCards" :key="'infra-' + card.key" class="infra-mini-card">
<header class="panel-header"> <header class="infra-mini-head">
<div class="panel-title"> <div class="infra-mini-title">
<h2>{{ card.label }}</h2> <strong>{{ card.label }}</strong>
<p>{{ card.meta }}</p> <small>{{ card.meta }}</small>
</div> </div>
<span :class="['badge', card.tone === 'bad' ? 'bad' : card.tone === 'warn' ? 'warn' : 'ok']">{{ card.badge }}</span> <span :class="['badge', card.tone === 'bad' ? 'bad' : card.tone === 'warn' ? 'warn' : 'ok']">{{ card.badge }}</span>
</header> </header>
<div class="infra-mini-metrics"> <div class="infra-mini-metrics">
<div v-for="item in card.metrics" :key="'infra-' + card.key + '-' + item.label" class="summary-card"> <span v-for="item in card.metrics" :key="'infra-' + card.key + '-' + item.label" class="infra-mini-metric">
<small>{{ item.label }}</small> <small>{{ item.label }}</small>
<strong>{{ item.value }}</strong> <strong>{{ item.value }}</strong>
</div> </span>
</div> </div>
</article> </article>
</section> </section>
@ -1127,23 +1114,11 @@
</button> </button>
<div v-if="infraMongoDetailsOpen" class="infra-detail-stack mongo-detail-stack"> <div v-if="infraMongoDetailsOpen" class="infra-detail-stack mongo-detail-stack">
<div class="metric-grid mongo-secondary-grid"> <div class="metadata-strip infra-inline-strip mongo-secondary-strip">
<div class="summary-card mongo-mini-card"> <span>Virtual {{ formatMb(payload.mongo.memory.virtualMb) }}</span>
<small>Virtual</small> <span>Resident {{ formatMb(payload.mongo.memory.residentMb) }}</span>
<strong>{{ formatMb(payload.mongo.memory.virtualMb) }}</strong> <span>Requests {{ formatNumber(payload.mongo.network.numRequests) }}</span>
</div> <span>WT Cache {{ formatBytes(payload.mongo.wiredTigerCache.bytesCurrentlyInCache) }}</span>
<div class="summary-card mongo-mini-card">
<small>Resident</small>
<strong>{{ formatMb(payload.mongo.memory.residentMb) }}</strong>
</div>
<div class="summary-card mongo-mini-card">
<small>Requests</small>
<strong>{{ formatNumber(payload.mongo.network.numRequests) }}</strong>
</div>
<div class="summary-card mongo-mini-card">
<small>WT Cache</small>
<strong>{{ formatBytes(payload.mongo.wiredTigerCache.bytesCurrentlyInCache) }}</strong>
</div>
</div> </div>
<section class="mongo-detail-block"> <section class="mongo-detail-block">
@ -2730,41 +2705,8 @@
</template> </template>
<template v-if="!showLoadingSkeleton && activeView === 'config'"> <template v-if="!showLoadingSkeleton && activeView === 'config'">
<section class="panel task-page-head">
<header class="panel-header">
<div class="panel-title">
<h2>配置</h2>
<p>{{ configContextLabel }}</p>
</div>
<div class="panel-meta">
<span class="badge neutral">{{ activeConfigTabLabel }}</span>
<span v-if="configTab === 'nacos'" class="badge neutral">{{ filteredNacosConfigs.length }} 项</span>
<span v-if="configTab === 'go'" class="badge neutral">{{ goConfig.hosts.length }} 台主机</span>
<span v-if="configTab === 'history'" class="badge neutral">{{ configHistoryRows.length }} 条记录</span>
<span
:class="[
'badge',
configTab === 'nacos'
? (nacosConfig.error || nacosConfig.detailError ? 'bad' : 'ok')
: configTab === 'go'
? (goConfig.error ? 'bad' : goConfig.diffKeys.length > 0 ? 'warn' : 'ok')
: 'neutral'
]"
>
{{
configTab === 'nacos'
? (nacosConfig.error || nacosConfig.detailError ? '存在错误' : '已连接')
: configTab === 'go'
? (goConfig.error ? '存在错误' : goConfig.diffKeys.length > 0 ? '双机有差异' : '已同步')
: '本地记录'
}}
</span>
</div>
</header>
</section>
<section v-if="configTab === 'nacos'" class="panel infra-panel config-workbench-panel"> <section v-if="configTab === 'nacos'" class="panel infra-panel config-workbench-panel">
<div class="compact-workbench-head"> <div class="compact-workbench-head config-head-strip">
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight">
<span class="mono">{{ truncateMiddle(nacosConfig.baseUrl, 18, 12) || '-' }}</span> <span class="mono">{{ truncateMiddle(nacosConfig.baseUrl, 18, 12) || '-' }}</span>
<span>{{ nacosConfig.namespaceName || 'default' }}</span> <span>{{ nacosConfig.namespaceName || 'default' }}</span>
@ -2778,7 +2720,7 @@
<p v-if="nacosConfig.error" class="metric-error">{{ explainError(nacosConfig.error) }}</p> <p v-if="nacosConfig.error" class="metric-error">{{ explainError(nacosConfig.error) }}</p>
<p v-if="nacosConfig.detailError" class="metric-error">{{ explainError(nacosConfig.detailError) }}</p> <p v-if="nacosConfig.detailError" class="metric-error">{{ explainError(nacosConfig.detailError) }}</p>
<div class="config-layout"> <div class="config-layout config-only-layout">
<aside class="config-sidebar"> <aside class="config-sidebar">
<div class="config-list config-list-ide"> <div class="config-list config-list-ide">
<section v-for="group in nacosConfigGroups" :key="group.key" class="config-group"> <section v-for="group in nacosConfigGroups" :key="group.key" class="config-group">
@ -2849,7 +2791,7 @@
</div> </div>
</div> </div>
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight config-inline-strip">
<span>最近修改 {{ formatDateTime(nacosConfig.editor.lastModifiedTime) }}</span> <span>最近修改 {{ formatDateTime(nacosConfig.editor.lastModifiedTime) }}</span>
<span>{{ nacosConfig.validationMessage ? '已校验' : '未校验' }}</span> <span>{{ nacosConfig.validationMessage ? '已校验' : '未校验' }}</span>
<span v-if="nacosConfig.editor.appName">app {{ nacosConfig.editor.appName }}</span> <span v-if="nacosConfig.editor.appName">app {{ nacosConfig.editor.appName }}</span>
@ -2886,7 +2828,7 @@
</section> </section>
<section v-if="configTab === 'go'" class="panel infra-panel config-workbench-panel"> <section v-if="configTab === 'go'" class="panel infra-panel config-workbench-panel">
<div class="compact-workbench-head"> <div class="compact-workbench-head config-head-strip">
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight">
<span>{{ goConfig.hosts.length }} 台主机</span> <span>{{ goConfig.hosts.length }} 台主机</span>
<span>差异 key {{ goConfig.diffKeys.length }}</span> <span>差异 key {{ goConfig.diffKeys.length }}</span>
@ -2897,7 +2839,7 @@
</span> </span>
</div> </div>
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight config-inline-strip">
<span v-for="host in goConfig.hosts" :key="host.host" class="mono">{{ host.host }} {{ truncateMiddle(host.path, 14, 10) }}</span> <span v-for="host in goConfig.hosts" :key="host.host" class="mono">{{ host.host }} {{ truncateMiddle(host.path, 14, 10) }}</span>
</div> </div>
@ -2933,7 +2875,7 @@
</div> </div>
</div> </div>
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight config-inline-strip">
<span>差异 key {{ goConfig.diffKeys.length }}</span> <span>差异 key {{ goConfig.diffKeys.length }}</span>
<span>基线 key {{ goConfig.hosts.length > 0 ? '已加载' : '未加载' }}</span> <span>基线 key {{ goConfig.hosts.length > 0 ? '已加载' : '未加载' }}</span>
</div> </div>
@ -2961,7 +2903,7 @@
</section> </section>
<section v-if="configTab === 'history'" class="panel infra-panel config-workbench-panel"> <section v-if="configTab === 'history'" class="panel infra-panel config-workbench-panel">
<div class="compact-workbench-head"> <div class="compact-workbench-head config-head-strip">
<div class="metadata-strip metadata-strip-tight"> <div class="metadata-strip metadata-strip-tight">
<span>本地记录 {{ configHistoryRows.length }}</span> <span>本地记录 {{ configHistoryRows.length }}</span>
<span>当前未接远端版本历史</span> <span>当前未接远端版本历史</span>
@ -2969,7 +2911,7 @@
<span class="badge neutral">历史版本</span> <span class="badge neutral">历史版本</span>
</div> </div>
<div class="activity-list activity-grid"> <div class="activity-list activity-grid config-history-list">
<article v-for="item in configHistoryRows" :key="item.id" :class="['activity-item', `tone-${item.tone}`]"> <article v-for="item in configHistoryRows" :key="item.id" :class="['activity-item', `tone-${item.tone}`]">
<div class="activity-item-main"> <div class="activity-item-main">
<strong>{{ item.title }}</strong> <strong>{{ item.title }}</strong>