fix(frontend): 统一重构前端样式系统,消除重复、添加响应式、修复硬编码
Closes #61 ## 变更内容 ### CSS 变量扩展 - 新增 --radius-sm / --radius-lg / --radius-xl 圆角变量 - 新增 --accent-end 渐变终点色(浅色/深色模式) ### 公共样式提取到 global.css - 提取 15+ 组重复样式:.page-head / .panel / .stat-row / table / .tag / .status-text / .bar-wrap / .cols-2 / .pagination / .log-stream 等 - 所有 border-radius 硬编码值改用 CSS 变量 - 新增工具类:.text-xs / .text-dim / .cols-2-equal / .panel-body.padded / .search-input / .accent-pill ### 响应式设计 - @media (max-width: 1024px):stat-row 3 列,双栏布局单列化 - @media (max-width: 768px):page-head 纵向排列,stat-row 2 列, 表格横向滚动,卡片网格单列化 ### 内联 style 清理 - 非动态绑定的 style="color: ..." / style="font-size: ..." / style="flex: 1" / style="padding: ..." 改为 CSS 类 ### 硬编码颜色修复 - ConfigCenter.vue: #1C2A3A/#8EC8FF 改用 CSS 变量 - Login.vue: #1C8F69 改用 --accent-end 变量 ### 页面组件 scoped 样式精简 - 13 个页面组件删除已提取的重复样式,净减少 1070 行
This commit is contained in:
@@ -162,3 +162,486 @@ button {
|
|||||||
.card:hover {
|
.card:hover {
|
||||||
box-shadow: var(--shadow-md);
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========== 页面标题区 ========== */
|
||||||
|
.page-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-head h1 {
|
||||||
|
font-size: 19px;
|
||||||
|
margin: 0 0 4px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-head p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-size: 12.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 面板 ========== */
|
||||||
|
.panel {
|
||||||
|
background: var(--bg-panel);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 13px 16px;
|
||||||
|
border-bottom: 1px solid var(--line-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-head h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 13.5px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-head .meta {
|
||||||
|
font-size: 11.5px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-family: var(--mono);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body.padded {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 统计卡片行 ========== */
|
||||||
|
.stat-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: var(--bg-panel);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 14px 16px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value.accent-pill {
|
||||||
|
color: var(--accent);
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value.warn {
|
||||||
|
color: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value.err {
|
||||||
|
color: var(--err);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value.accent {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .delta {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .delta.up {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .delta.warn {
|
||||||
|
color: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .delta.err {
|
||||||
|
color: var(--err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 双栏布局 ========== */
|
||||||
|
.cols-2 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.4fr 1fr;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cols-2-equal {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 表格 ========== */
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 12.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.4px;
|
||||||
|
padding: 9px 16px;
|
||||||
|
border-bottom: 1px solid var(--line-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 11px 16px;
|
||||||
|
border-bottom: 1px solid var(--line-soft);
|
||||||
|
color: var(--text-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.tr-hover:hover td {
|
||||||
|
background: var(--bg-panel-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.tr-hover.active td {
|
||||||
|
background: var(--bg-panel-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.strong {
|
||||||
|
color: var(--text-hi);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-xs {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-dim {
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 标签 ========== */
|
||||||
|
.tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 10.5px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
color: var(--text-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag.zone-a {
|
||||||
|
color: var(--tag-blue-text);
|
||||||
|
border-color: var(--tag-blue-border);
|
||||||
|
background: var(--tag-blue-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag.zone-b {
|
||||||
|
color: var(--tag-purple-text);
|
||||||
|
border-color: var(--tag-purple-border);
|
||||||
|
background: var(--tag-purple-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag.zone-c {
|
||||||
|
color: var(--tag-amber-text);
|
||||||
|
border-color: var(--tag-amber-border);
|
||||||
|
background: var(--tag-amber-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 状态文本 ========== */
|
||||||
|
.status-text {
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text.ok {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text.warn {
|
||||||
|
color: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text.err {
|
||||||
|
color: var(--err);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text.idle {
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 进度条 ========== */
|
||||||
|
.bar-wrap {
|
||||||
|
width: 90px;
|
||||||
|
height: 5px;
|
||||||
|
background: var(--bar-bg);
|
||||||
|
border-radius: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-fill {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-fill.warn {
|
||||||
|
background: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-fill.err {
|
||||||
|
background: var(--err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 分页 ========== */
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 16px;
|
||||||
|
border-top: 1px solid var(--line-soft);
|
||||||
|
font-size: 11.5px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-btns {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-btn {
|
||||||
|
min-width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
padding: 0 6px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
color: var(--text-mid);
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 11px;
|
||||||
|
background: var(--bg-panel-2);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-btn.active {
|
||||||
|
background: var(--accent-dim);
|
||||||
|
border-color: var(--accent-dim);
|
||||||
|
color: var(--active-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-btn:hover {
|
||||||
|
border-color: var(--hover-border);
|
||||||
|
color: var(--text-hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-btn.disabled {
|
||||||
|
opacity: 0.35;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-sep {
|
||||||
|
color: var(--text-dim);
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 日志流 ========== */
|
||||||
|
.log-stream {
|
||||||
|
padding: 14px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-log-line {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 11.5px;
|
||||||
|
padding: 2px 0;
|
||||||
|
color: var(--text-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-log-line .t {
|
||||||
|
color: var(--text-dim);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-log-line.ok {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-log-line.tag-ok {
|
||||||
|
color: var(--tag-blue-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 工具栏 ========== */
|
||||||
|
.las-toolbar {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 子系统/扩展卡片网格 ========== */
|
||||||
|
.ext-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Apollo / 外部服务卡片 ========== */
|
||||||
|
.ext-card {
|
||||||
|
background: var(--bg-panel);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 18px;
|
||||||
|
max-width: 560px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-logo {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-logo.ap-logo {
|
||||||
|
background: var(--logo-ap-bg);
|
||||||
|
color: var(--tag-blue-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-sub {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-family: var(--mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 环境状态标签 ========== */
|
||||||
|
.env-pill {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--accent);
|
||||||
|
border: 1px solid var(--accent-dim);
|
||||||
|
background: var(--accent-dim);
|
||||||
|
padding: 3px 9px;
|
||||||
|
border-radius: 20px;
|
||||||
|
letter-spacing: 0.4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== SSO 行 ========== */
|
||||||
|
.sso-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sso-dot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 响应式断点 ========== */
|
||||||
|
|
||||||
|
/* 平板 */
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.stat-row {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cols-2,
|
||||||
|
.cols-2-equal {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.page-head {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-row {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cols-2,
|
||||||
|
.cols-2-equal {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.las-toolbar {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-grid,
|
||||||
|
.svc-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body table {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
/* 圆角 */
|
/* 圆角 */
|
||||||
--radius: 6px;
|
--radius: 6px;
|
||||||
|
--radius-sm: 4px;
|
||||||
|
--radius-lg: 8px;
|
||||||
|
--radius-xl: 12px;
|
||||||
|
|
||||||
/* 字体 */
|
/* 字体 */
|
||||||
--mono: 'IBM Plex Mono', monospace;
|
--mono: 'IBM Plex Mono', monospace;
|
||||||
@@ -35,6 +38,9 @@
|
|||||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
/* 渐变终点色 */
|
||||||
|
--accent-end: #1C8F69;
|
||||||
|
|
||||||
/* 标签/徽章颜色 - 蓝色系 */
|
/* 标签/徽章颜色 - 蓝色系 */
|
||||||
--tag-blue-text: #165DFF;
|
--tag-blue-text: #165DFF;
|
||||||
--tag-blue-bg: #E8F3FF;
|
--tag-blue-bg: #E8F3FF;
|
||||||
@@ -116,6 +122,9 @@
|
|||||||
|
|
||||||
/* 圆角 */
|
/* 圆角 */
|
||||||
--radius: 6px;
|
--radius: 6px;
|
||||||
|
--radius-sm: 4px;
|
||||||
|
--radius-lg: 8px;
|
||||||
|
--radius-xl: 12px;
|
||||||
|
|
||||||
/* 字体 */
|
/* 字体 */
|
||||||
--mono: 'IBM Plex Mono', monospace;
|
--mono: 'IBM Plex Mono', monospace;
|
||||||
@@ -126,6 +135,9 @@
|
|||||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
|
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
|
||||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
|
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
/* 渐变终点色 */
|
||||||
|
--accent-end: #1F6B52;
|
||||||
|
|
||||||
/* 标签/徽章颜色 - 蓝色系 */
|
/* 标签/徽章颜色 - 蓝色系 */
|
||||||
--tag-blue-text: #8EC8FF;
|
--tag-blue-text: #8EC8FF;
|
||||||
--tag-blue-bg: #0E1C2C;
|
--tag-blue-bg: #0E1C2C;
|
||||||
|
|||||||
@@ -52,23 +52,5 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 所有样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -53,23 +53,5 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 所有样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
size="large"
|
size="large"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@click="handleLogin"
|
@click="handleLogin"
|
||||||
style="width: 100%"
|
class="login-btn"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -105,10 +105,14 @@ const handleLogin = async () => {
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
background: var(--bg-panel);
|
background: var(--bg-panel);
|
||||||
border: 1px solid var(--line);
|
border: 1px solid var(--line);
|
||||||
border-radius: 12px;
|
border-radius: var(--radius-xl);
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.login-header {
|
.login-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
@@ -127,8 +131,8 @@ const handleLogin = async () => {
|
|||||||
.login-header .brand .mark {
|
.login-header .brand .mark {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-lg);
|
||||||
background: linear-gradient(135deg, var(--accent), #1C8F69);
|
background: linear-gradient(135deg, var(--accent), var(--accent-end));
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<td class="strong mono">{{ node.name }}</td>
|
<td class="strong mono">{{ node.name }}</td>
|
||||||
<td class="mono">{{ node.ip }}</td>
|
<td class="mono">{{ node.ip }}</td>
|
||||||
<td><span class="tag biz" :style="{ color: node.labelColor, borderColor: node.labelBorder }">{{ node.label }}</span></td>
|
<td><span class="tag biz" :style="{ color: node.labelColor, borderColor: node.labelBorder }">{{ node.label }}</span></td>
|
||||||
<td class="mono" style="font-size: 11px">{{ node.taint }}</td>
|
<td class="mono text-xs">{{ node.taint }}</td>
|
||||||
<td class="mono">{{ node.spec }}</td>
|
<td class="mono">{{ node.spec }}</td>
|
||||||
<td><span class="bar-wrap"><span class="bar-fill" :class="node.cpuClass" :style="{ width: node.cpu + '%' }"></span></span>{{ node.cpu }}%</td>
|
<td><span class="bar-wrap"><span class="bar-fill" :class="node.cpuClass" :style="{ width: node.cpu + '%' }"></span></span>{{ node.cpu }}%</td>
|
||||||
<td :class="['status-text', node.statusClass]">● {{ node.status }}</td>
|
<td :class="['status-text', node.statusClass]">● {{ node.status }}</td>
|
||||||
@@ -94,162 +94,9 @@ const nodes = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 公共样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 10.5px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-a {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
border-color: var(--tag-blue-border);
|
|
||||||
background: var(--tag-blue-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-b {
|
|
||||||
color: var(--tag-purple-text);
|
|
||||||
border-color: var(--tag-purple-border);
|
|
||||||
background: var(--tag-purple-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-c {
|
|
||||||
color: var(--tag-amber-text);
|
|
||||||
border-color: var(--tag-amber-border);
|
|
||||||
background: var(--tag-amber-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.biz {
|
.tag.biz {
|
||||||
color: var(--text-mid);
|
color: var(--text-mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar-wrap {
|
|
||||||
width: 90px;
|
|
||||||
height: 5px;
|
|
||||||
background: var(--bar-bg);
|
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-fill {
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 3px;
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-fill.warn {
|
|
||||||
background: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">同步状态</div>
|
<div class="label">同步状态</div>
|
||||||
<div class="value" style="color: var(--accent); font-size: 16px">● 正常</div>
|
<div class="value accent-pill">● 正常</div>
|
||||||
<div class="delta">最近发布 09:12:30</div>
|
<div class="delta">最近发布 09:12:30</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,10 +41,10 @@
|
|||||||
<h3>统一入口</h3>
|
<h3>统一入口</h3>
|
||||||
<span class="meta">Apollo Portal · LDAP 单点登录</span>
|
<span class="meta">Apollo Portal · LDAP 单点登录</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body" style="padding: 16px">
|
<div class="panel-body padded">
|
||||||
<div class="ext-card">
|
<div class="ext-card">
|
||||||
<div class="ext-top">
|
<div class="ext-top">
|
||||||
<div class="ext-logo" style="background: #1C2A3A; color: #8EC8FF">AP</div>
|
<div class="ext-logo ap-logo">AP</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>Apollo Portal</h4>
|
<h4>Apollo Portal</h4>
|
||||||
<div class="ext-sub">apollo.xinfra.internal</div>
|
<div class="ext-sub">apollo.xinfra.internal</div>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<tr v-for="cluster in clusters" :key="cluster.name" class="tr-hover">
|
<tr v-for="cluster in clusters" :key="cluster.name" class="tr-hover">
|
||||||
<td><span class="tag" :class="cluster.zoneClass">{{ cluster.name }}</span></td>
|
<td><span class="tag" :class="cluster.zoneClass">{{ cluster.name }}</span></td>
|
||||||
<td class="mono">cluster={{ cluster.cluster }}</td>
|
<td class="mono">cluster={{ cluster.cluster }}</td>
|
||||||
<td class="mono" style="font-size: 11px">{{ cluster.address }}</td>
|
<td class="mono text-xs">{{ cluster.address }}</td>
|
||||||
<td class="mono">{{ cluster.type }}</td>
|
<td class="mono">{{ cluster.type }}</td>
|
||||||
<td class="mono">{{ cluster.biz }}</td>
|
<td class="mono">{{ cluster.biz }}</td>
|
||||||
<td class="mono">{{ cluster.items }}</td>
|
<td class="mono">{{ cluster.items }}</td>
|
||||||
@@ -109,241 +109,17 @@ const clusters = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 公共样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.env-pill {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--accent);
|
|
||||||
border: 1px solid var(--accent-dim);
|
|
||||||
background: var(--accent-dim);
|
|
||||||
padding: 3px 9px;
|
|
||||||
border-radius: 20px;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ext-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 18px;
|
|
||||||
max-width: 560px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ext-top {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ext-logo {
|
|
||||||
width: 38px;
|
|
||||||
height: 38px;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ext-sub {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--text-mid);
|
color: var(--text-mid);
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sso-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sso-dot {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 10.5px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-a {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
border-color: var(--tag-blue-border);
|
|
||||||
background: var(--tag-blue-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-b {
|
|
||||||
color: var(--tag-purple-text);
|
|
||||||
border-color: var(--tag-purple-border);
|
|
||||||
background: var(--tag-purple-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-c {
|
|
||||||
color: var(--tag-amber-text);
|
|
||||||
border-color: var(--tag-amber-border);
|
|
||||||
background: var(--tag-amber-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.idle {
|
|
||||||
color: var(--text-dim);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">进行中任务</div>
|
<div class="label">进行中任务</div>
|
||||||
<div class="value" style="color: var(--warn)">2</div>
|
<div class="value warn">2</div>
|
||||||
<div class="delta warn">1 个待关注</div>
|
<div class="delta warn">1 个待关注</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<div class="topo-cluster">
|
<div class="topo-cluster">
|
||||||
<div class="tname">
|
<div class="tname">
|
||||||
<span class="tag zone-a">IDC-华北机房</span>
|
<span class="tag zone-a">IDC-华北机房</span>
|
||||||
<span class="mono" style="color: var(--text-dim)">46节点</span>
|
<span class="mono text-dim">46节点</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="node-grid">
|
<div class="node-grid">
|
||||||
<div v-for="i in 24" :key="i" :class="['node-cell', i <= 18 ? 'a' : '']"></div>
|
<div v-for="i in 24" :key="i" :class="['node-cell', i <= 18 ? 'a' : '']"></div>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<div class="topo-cluster">
|
<div class="topo-cluster">
|
||||||
<div class="tname">
|
<div class="tname">
|
||||||
<span class="tag zone-b">IDC-华东机房</span>
|
<span class="tag zone-b">IDC-华东机房</span>
|
||||||
<span class="mono" style="color: var(--text-dim)">52节点</span>
|
<span class="mono text-dim">52节点</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="node-grid">
|
<div class="node-grid">
|
||||||
<div v-for="i in 24" :key="i" :class="['node-cell', i <= 20 ? 'b' : '']"></div>
|
<div v-for="i in 24" :key="i" :class="['node-cell', i <= 20 ? 'b' : '']"></div>
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
<div class="topo-cluster">
|
<div class="topo-cluster">
|
||||||
<div class="tname">
|
<div class="tname">
|
||||||
<span class="tag zone-c">阿里云-华南</span>
|
<span class="tag zone-c">阿里云-华南</span>
|
||||||
<span class="mono" style="color: var(--text-dim)">30节点</span>
|
<span class="mono text-dim">30节点</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="node-grid">
|
<div class="node-grid">
|
||||||
<div v-for="i in 18" :key="i" :class="['node-cell', i <= 12 ? 'c' : '']"></div>
|
<div v-for="i in 18" :key="i" :class="['node-cell', i <= 12 ? 'c' : '']"></div>
|
||||||
@@ -127,107 +127,7 @@ const refresh = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 公共样式(.page-head, .stat-row, .cols-2, .panel, table, .tag, .status-text)已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.up {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cols-2 {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1.4fr 1fr;
|
|
||||||
gap: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topo {
|
.topo {
|
||||||
padding: 18px 16px;
|
padding: 18px 16px;
|
||||||
@@ -238,7 +138,7 @@ const refresh = () => {
|
|||||||
.topo-cluster {
|
.topo-cluster {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: 1px dashed var(--line);
|
border: 1px dashed var(--line);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-lg);
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,92 +198,4 @@ const refresh = () => {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: var(--text-dim);
|
color: var(--text-dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
td.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 10.5px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-a {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
border-color: var(--tag-blue-border);
|
|
||||||
background: var(--tag-blue-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-b {
|
|
||||||
color: var(--tag-purple-text);
|
|
||||||
border-color: var(--tag-purple-border);
|
|
||||||
background: var(--tag-purple-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-c {
|
|
||||||
color: var(--tag-amber-text);
|
|
||||||
border-color: var(--tag-amber-border);
|
|
||||||
background: var(--tag-amber-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.err {
|
|
||||||
color: var(--err);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cols-2">
|
<div class="cols-2-equal">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-head">
|
<div class="panel-head">
|
||||||
<h3>VictoriaMetrics · 指标概览</h3>
|
<h3>VictoriaMetrics · 指标概览</h3>
|
||||||
@@ -94,123 +94,5 @@ const logs = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* .page-head, .cols-2-equal, .panel, table, .status-text, .log-stream, .task-log-line 已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cols-2 {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 18px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-stream {
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11.5px;
|
|
||||||
padding: 2px 0;
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line .t {
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">最近一次同步</div>
|
<div class="label">最近一次同步</div>
|
||||||
<div class="value" style="color: var(--accent); font-size: 16px">● 正常</div>
|
<div class="value accent-pill">● 正常</div>
|
||||||
<div class="delta">07:39:10 · 新增 3 条</div>
|
<div class="delta">07:39:10 · 新增 3 条</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<el-option label="maas" value="maas" />
|
<el-option label="maas" value="maas" />
|
||||||
<el-option label="未分配" value="unassigned" />
|
<el-option label="未分配" value="unassigned" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input placeholder="搜索 hostname / asset_number / IP" style="flex: 1" />
|
<el-input placeholder="搜索 hostname / asset_number / IP" class="search-input" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
@@ -84,11 +84,11 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="item in resources" :key="item.hostname" class="tr-hover">
|
<tr v-for="item in resources" :key="item.hostname" class="tr-hover">
|
||||||
<td class="strong mono">{{ item.hostname }}</td>
|
<td class="strong mono">{{ item.hostname }}</td>
|
||||||
<td class="mono" style="font-size: 11px">{{ item.asset_number }}</td>
|
<td class="mono text-xs">{{ item.asset_number }}</td>
|
||||||
<td><span class="tag" :class="item.type === '物理机' ? '' : 'vm'">{{ item.type }}</span></td>
|
<td><span class="tag" :class="item.type === '物理机' ? '' : 'vm'">{{ item.type }}</span></td>
|
||||||
<td><span class="tag zone-a">{{ item.location }}</span></td>
|
<td><span class="tag zone-a">{{ item.location }}</span></td>
|
||||||
<td class="mono">{{ item.ip }}</td>
|
<td class="mono">{{ item.ip }}</td>
|
||||||
<td class="mono" style="font-size: 11px">{{ item.spec }}</td>
|
<td class="mono text-xs">{{ item.spec }}</td>
|
||||||
<td class="mono">{{ item.business_line }}</td>
|
<td class="mono">{{ item.business_line }}</td>
|
||||||
<td><span class="tag src-cmdb">{{ item.source }}</span></td>
|
<td><span class="tag src-cmdb">{{ item.source }}</span></td>
|
||||||
<td class="status-text ok">● {{ item.status }}</td>
|
<td class="status-text ok">● {{ item.status }}</td>
|
||||||
@@ -127,155 +127,7 @@ const resources = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 公共样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.up {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.las-toolbar {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 10.5px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.vm {
|
.tag.vm {
|
||||||
color: var(--tag-blue-text);
|
color: var(--tag-blue-text);
|
||||||
@@ -283,78 +135,9 @@ tr.tr-hover:hover td {
|
|||||||
background: var(--tag-blue-bg);
|
background: var(--tag-blue-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag.zone-a {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
border-color: var(--tag-blue-border);
|
|
||||||
background: var(--tag-blue-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.src-cmdb {
|
.tag.src-cmdb {
|
||||||
color: var(--tag-green-text);
|
color: var(--tag-green-text);
|
||||||
border-color: var(--tag-green-border);
|
border-color: var(--tag-green-border);
|
||||||
background: var(--tag-green-bg);
|
background: var(--tag-green-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 16px;
|
|
||||||
border-top: 1px solid var(--line-soft);
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btns {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn {
|
|
||||||
min-width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
padding: 0 6px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 5px;
|
|
||||||
color: var(--text-mid);
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11px;
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.active {
|
|
||||||
background: var(--accent-dim);
|
|
||||||
border-color: var(--accent-dim);
|
|
||||||
color: var(--active-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn:hover {
|
|
||||||
border-color: var(--hover-border);
|
|
||||||
color: var(--text-hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.disabled {
|
|
||||||
opacity: 0.35;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-sep {
|
|
||||||
color: var(--text-dim);
|
|
||||||
padding: 0 2px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -26,17 +26,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">P0 / Disaster 告警</div>
|
<div class="label">P0 / Disaster 告警</div>
|
||||||
<div class="value" style="color: var(--err)">1</div>
|
<div class="value err">1</div>
|
||||||
<div class="delta" style="color: var(--err)">来自 VictoriaMetrics</div>
|
<div class="delta err">来自 VictoriaMetrics</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">P1 / High 告警</div>
|
<div class="label">P1 / High 告警</div>
|
||||||
<div class="value" style="color: var(--warn)">5</div>
|
<div class="value warn">5</div>
|
||||||
<div class="delta warn">来自 Zabbix · 4 条 / VM · 1 条</div>
|
<div class="delta warn">来自 Zabbix · 4 条 / VM · 1 条</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cols-2">
|
<div class="cols-2-equal">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-head">
|
<div class="panel-head">
|
||||||
<h3>物理机状态 · 按机房</h3>
|
<h3>物理机状态 · 按机房</h3>
|
||||||
@@ -131,184 +131,5 @@ const refresh = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 所有样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.up {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cols-2 {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-wrap {
|
|
||||||
width: 90px;
|
|
||||||
height: 5px;
|
|
||||||
background: var(--bar-bg);
|
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-fill {
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 3px;
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-fill.warn {
|
|
||||||
background: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-fill.err {
|
|
||||||
background: var(--err);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.err {
|
|
||||||
color: var(--err);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -43,35 +43,12 @@ const handleDeploy = (service: any) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* .page-head, .svc-grid 已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.svc-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
gap: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.svc-card {
|
.svc-card {
|
||||||
background: var(--bg-panel);
|
background: var(--bg-panel);
|
||||||
border: 1px solid var(--line);
|
border: 1px solid var(--line);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-lg);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color 0.15s;
|
transition: border-color 0.15s;
|
||||||
|
|||||||
@@ -26,12 +26,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">健康实例占比</div>
|
<div class="label">健康实例占比</div>
|
||||||
<div class="value" style="color: var(--accent)">98.6%</div>
|
<div class="value accent">98.6%</div>
|
||||||
<div class="delta warn">12 个实例 critical</div>
|
<div class="delta warn">12 个实例 critical</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="label">最近同步</div>
|
<div class="label">最近同步</div>
|
||||||
<div class="value" style="color: var(--accent); font-size: 16px">● 正常</div>
|
<div class="value accent-pill">● 正常</div>
|
||||||
<div class="delta">07:41:05 · 间隔 30s</div>
|
<div class="delta">07:41:05 · 间隔 30s</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<el-option label="部分异常" value="partial" />
|
<el-option label="部分异常" value="partial" />
|
||||||
<el-option label="全部下线" value="offline" />
|
<el-option label="全部下线" value="offline" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input placeholder="搜索服务名 / IP" style="flex: 1" />
|
<el-input placeholder="搜索服务名 / IP" class="search-input" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
@@ -126,234 +126,5 @@ const services = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 所有样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .delta.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.las-toolbar {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
padding: 9px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 10.5px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-a {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
border-color: var(--tag-blue-border);
|
|
||||||
background: var(--tag-blue-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-b {
|
|
||||||
color: var(--tag-purple-text);
|
|
||||||
border-color: var(--tag-purple-border);
|
|
||||||
background: var(--tag-purple-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag.zone-c {
|
|
||||||
color: var(--tag-amber-text);
|
|
||||||
border-color: var(--tag-amber-border);
|
|
||||||
background: var(--tag-amber-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 16px;
|
|
||||||
border-top: 1px solid var(--line-soft);
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btns {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn {
|
|
||||||
min-width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
padding: 0 6px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 5px;
|
|
||||||
color: var(--text-mid);
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11px;
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.active {
|
|
||||||
background: var(--accent-dim);
|
|
||||||
border-color: var(--accent-dim);
|
|
||||||
color: var(--active-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn:hover {
|
|
||||||
border-color: var(--hover-border);
|
|
||||||
color: var(--text-hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.disabled {
|
|
||||||
opacity: 0.35;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-sep {
|
|
||||||
color: var(--text-dim);
|
|
||||||
padding: 0 2px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -34,29 +34,5 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* .page-head, .ext-grid 已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ext-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
gap: 14px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cols-2">
|
<div class="cols-2-equal">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-head">
|
<div class="panel-head">
|
||||||
<h3>任务列表</h3>
|
<h3>任务列表</h3>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<tr v-for="task in tasks" :key="task.id" class="tr-hover" :class="{ active: task.id === selectedTask }" @click="selectedTask = task.id">
|
<tr v-for="task in tasks" :key="task.id" class="tr-hover" :class="{ active: task.id === selectedTask }" @click="selectedTask = task.id">
|
||||||
<td :class="['status-text', task.statusClass]">● {{ task.status }}</td>
|
<td :class="['status-text', task.statusClass]">● {{ task.status }}</td>
|
||||||
<td class="strong">{{ task.name }}</td>
|
<td class="strong">{{ task.name }}</td>
|
||||||
<td class="mono" style="font-size: 11px; color: var(--text-dim)">{{ task.playbook }}</td>
|
<td class="mono text-xs text-dim">{{ task.playbook }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -83,138 +83,13 @@ const logs = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-head {
|
/* 公共样式已在 global.css 中定义 */
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head h1 {
|
|
||||||
font-size: 19px;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cols-2 {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: var(--bg-panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 13px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13.5px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-head .meta {
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-body {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-stream {
|
.log-stream {
|
||||||
padding: 14px 16px;
|
|
||||||
max-height: 340px;
|
max-height: 340px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 12.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 11px 16px;
|
|
||||||
border-bottom: 1px solid var(--line-soft);
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover:hover td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.tr-hover.active td {
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.strong {
|
|
||||||
color: var(--text-hi);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mono {
|
|
||||||
font-family: var(--mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.warn {
|
|
||||||
color: var(--warn);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text.err {
|
|
||||||
color: var(--err);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line {
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11.5px;
|
|
||||||
padding: 2px 0;
|
|
||||||
color: var(--text-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line .t {
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line.ok {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-log-line.tag-ok {
|
|
||||||
color: var(--tag-blue-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blink {
|
.blink {
|
||||||
animation: blink 1s step-start infinite;
|
animation: blink 1s step-start infinite;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
@@ -223,57 +98,4 @@ tr.tr-hover.active td {
|
|||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
50% { opacity: 0; }
|
50% { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 16px;
|
|
||||||
border-top: 1px solid var(--line-soft);
|
|
||||||
font-size: 11.5px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btns {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn {
|
|
||||||
min-width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
padding: 0 6px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 5px;
|
|
||||||
color: var(--text-mid);
|
|
||||||
font-family: var(--mono);
|
|
||||||
font-size: 11px;
|
|
||||||
background: var(--bg-panel-2);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.active {
|
|
||||||
background: var(--accent-dim);
|
|
||||||
border-color: var(--accent-dim);
|
|
||||||
color: var(--active-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn:hover {
|
|
||||||
border-color: var(--hover-border);
|
|
||||||
color: var(--text-hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-btn.disabled {
|
|
||||||
opacity: 0.35;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pg-sep {
|
|
||||||
color: var(--text-dim);
|
|
||||||
padding: 0 2px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user