压平infra和config结构
This commit is contained in:
parent
cdb84c8c96
commit
799038ad3b
216
static/app.css
216
static/app.css
@ -2220,9 +2220,41 @@ body.auth-page {
|
||||
|
||||
.config-workbench-panel {
|
||||
position: relative;
|
||||
background:
|
||||
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: var(--shadow-soft), inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 74%, transparent);
|
||||
background: var(--panel);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.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 {
|
||||
@ -2240,13 +2272,13 @@ body.auth-page {
|
||||
.mongo-stat-group {
|
||||
position: relative;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 14px;
|
||||
background: var(--panel-muted);
|
||||
transition: transform 180ms ease, 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);
|
||||
border-radius: 12px;
|
||||
background: var(--panel-strong);
|
||||
transition: border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.infra-focus-card::before,
|
||||
@ -2255,17 +2287,17 @@ body.auth-page {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, color-mix(in oklab, var(--accent) 48%, var(--ok)) 0%, transparent 76%);
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
width: 3px;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in oklab, var(--accent) 48%, var(--ok));
|
||||
}
|
||||
|
||||
.infra-focus-card:hover,
|
||||
.mongo-stat-group:hover {
|
||||
transform: translateY(-1px);
|
||||
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 {
|
||||
@ -2335,26 +2367,14 @@ body.auth-page {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.mongo-secondary-grid {
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.mongo-mini-card {
|
||||
min-height: 0;
|
||||
padding: 9px 10px;
|
||||
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;
|
||||
.infra-inline-strip {
|
||||
margin-bottom: 0;
|
||||
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;
|
||||
}
|
||||
|
||||
.mongo-detail-stack {
|
||||
@ -2363,12 +2383,13 @@ body.auth-page {
|
||||
|
||||
.mongo-detail-block {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, color-mix(in oklab, var(--panel-muted) 95%, var(--panel-strong)) 0%, var(--panel-strong) 100%);
|
||||
box-shadow: inset 0 1px 0 color-mix(in oklab, var(--panel-strong) 72%, transparent);
|
||||
gap: 8px;
|
||||
padding: 10px 0 0;
|
||||
border: 0;
|
||||
border-top: 1px solid color-mix(in oklab, var(--line) 90%, var(--panel-strong));
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mongo-detail-head {
|
||||
@ -2384,9 +2405,9 @@ body.auth-page {
|
||||
|
||||
.mongo-detail-head .panel-title p {
|
||||
margin-top: 3px;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.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 {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
@ -2718,6 +2750,30 @@ body.auth-page {
|
||||
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 {
|
||||
margin-top: 8px;
|
||||
padding: 12px;
|
||||
@ -3235,14 +3291,69 @@ body.auth-page {
|
||||
|
||||
.infra-mini-card {
|
||||
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;
|
||||
flex-direction: column;
|
||||
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%);
|
||||
justify-content: space-between;
|
||||
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 {
|
||||
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 {
|
||||
@ -4317,6 +4428,12 @@ body.auth-page {
|
||||
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 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@ -4484,7 +4601,8 @@ body.auth-page {
|
||||
.release-action-bar,
|
||||
.log-viewer-head,
|
||||
.compact-workbench-head,
|
||||
.release-service-head {
|
||||
.release-service-head,
|
||||
.infra-mini-head {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@ -1556,9 +1556,6 @@ createApp({
|
||||
releaseHistoryRows() {
|
||||
return this.releaseHistory.slice(0, 8);
|
||||
},
|
||||
activeConfigTabLabel() {
|
||||
return this.configTabs.find((item) => item.id === this.configTab)?.label || "";
|
||||
},
|
||||
configContextLabel() {
|
||||
if (this.configTab === "nacos") {
|
||||
return `Nacos / ${this.nacosConfig.namespaceName || "default"} / ${this.filteredNacosConfigs.length} 项`;
|
||||
|
||||
@ -809,33 +809,20 @@
|
||||
</template>
|
||||
|
||||
<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">
|
||||
<article v-for="card in overviewInfraCards" :key="'infra-' + card.key" class="panel infra-mini-card">
|
||||
<header class="panel-header">
|
||||
<div class="panel-title">
|
||||
<h2>{{ card.label }}</h2>
|
||||
<p>{{ card.meta }}</p>
|
||||
<article v-for="card in overviewInfraCards" :key="'infra-' + card.key" class="infra-mini-card">
|
||||
<header class="infra-mini-head">
|
||||
<div class="infra-mini-title">
|
||||
<strong>{{ card.label }}</strong>
|
||||
<small>{{ card.meta }}</small>
|
||||
</div>
|
||||
<span :class="['badge', card.tone === 'bad' ? 'bad' : card.tone === 'warn' ? 'warn' : 'ok']">{{ card.badge }}</span>
|
||||
</header>
|
||||
<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>
|
||||
<strong>{{ item.value }}</strong>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
@ -1127,23 +1114,11 @@
|
||||
</button>
|
||||
|
||||
<div v-if="infraMongoDetailsOpen" class="infra-detail-stack mongo-detail-stack">
|
||||
<div class="metric-grid mongo-secondary-grid">
|
||||
<div class="summary-card mongo-mini-card">
|
||||
<small>Virtual</small>
|
||||
<strong>{{ formatMb(payload.mongo.memory.virtualMb) }}</strong>
|
||||
</div>
|
||||
<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 class="metadata-strip infra-inline-strip mongo-secondary-strip">
|
||||
<span>Virtual {{ formatMb(payload.mongo.memory.virtualMb) }}</span>
|
||||
<span>Resident {{ formatMb(payload.mongo.memory.residentMb) }}</span>
|
||||
<span>Requests {{ formatNumber(payload.mongo.network.numRequests) }}</span>
|
||||
<span>WT Cache {{ formatBytes(payload.mongo.wiredTigerCache.bytesCurrentlyInCache) }}</span>
|
||||
</div>
|
||||
|
||||
<section class="mongo-detail-block">
|
||||
@ -2730,41 +2705,8 @@
|
||||
</template>
|
||||
|
||||
<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">
|
||||
<div class="compact-workbench-head">
|
||||
<div class="compact-workbench-head config-head-strip">
|
||||
<div class="metadata-strip metadata-strip-tight">
|
||||
<span class="mono">{{ truncateMiddle(nacosConfig.baseUrl, 18, 12) || '-' }}</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.detailError" class="metric-error">{{ explainError(nacosConfig.detailError) }}</p>
|
||||
|
||||
<div class="config-layout">
|
||||
<div class="config-layout config-only-layout">
|
||||
<aside class="config-sidebar">
|
||||
<div class="config-list config-list-ide">
|
||||
<section v-for="group in nacosConfigGroups" :key="group.key" class="config-group">
|
||||
@ -2849,7 +2791,7 @@
|
||||
</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>{{ nacosConfig.validationMessage ? '已校验' : '未校验' }}</span>
|
||||
<span v-if="nacosConfig.editor.appName">app {{ nacosConfig.editor.appName }}</span>
|
||||
@ -2886,7 +2828,7 @@
|
||||
</section>
|
||||
|
||||
<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">
|
||||
<span>{{ goConfig.hosts.length }} 台主机</span>
|
||||
<span>差异 key {{ goConfig.diffKeys.length }}</span>
|
||||
@ -2897,7 +2839,7 @@
|
||||
</span>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
@ -2933,7 +2875,7 @@
|
||||
</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.hosts.length > 0 ? '已加载' : '未加载' }}</span>
|
||||
</div>
|
||||
@ -2961,7 +2903,7 @@
|
||||
</section>
|
||||
|
||||
<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">
|
||||
<span>本地记录 {{ configHistoryRows.length }}</span>
|
||||
<span>当前未接远端版本历史</span>
|
||||
@ -2969,7 +2911,7 @@
|
||||
<span class="badge neutral">历史版本</span>
|
||||
</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}`]">
|
||||
<div class="activity-item-main">
|
||||
<strong>{{ item.title }}</strong>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user