- 基于第七版稳定基线(be647bb)重构 admin 前端为模块化架构:
tokens.css(设计token唯一来源) + shared.css(公共组件) + core.js(状态/API/事件总线/轮询/路由)
+ main.js(入口) + layouts/{flowline,ledger,strata}.{css,js}(三方向独立布局)
+ layouts/shared.js(三方向共用数据视图与操作绑定)
- 三个页面(A装配线/B值班台账/C地层剖面)通过 ?layout= 查询参数独立可达、可刷新、可前进后退导航,
共享登录态、真实后端数据(overview/sources/jobs/batches/datasets/audit)、错误处理与主题
- 六大板块(总览/数据源/调度任务/盘后发布/数据集/审计)在三个方向均可查看与操作(探测/触发/回滚/补数)
- 修正健康状态语义:CircuitBreaker closed/half_open/open 与适配器 ok/error/empty/unconfigured/unknown
统一归一化为 ok/warn/error/unconfigured/unknown 供三方向一致展示
- 事件驱动动效:A 水平接力光梭、B 行级高亮+实时调用跑马灯、C 纵向贯穿光点+分层标记;
统一使用 transform/opacity/WAAPI,避免 transition:all,支持 prefers-reduced-motion 静态降级
- 修复响应式布局在 1024/1280 断点因 CSS Grid 默认 min-width:auto 被内部宽表格撑爆轨道的问题
- 修复布局切换/前进后退时残留 setTimeout 回调在 unmount 后访问 null root 导致的报错(mounted 标志位+
safeTimeout+统一清理定时器)
- 自测:Playwright 全断点(1440/1280/1024)x 双主题矩阵截图、90 次连续布局切换+前进后退压力测试无报错、
探测/触发/回滚danger操作流程验证、reduced-motion 验证;后端 pytest 全量 133 用例通过,无回归
- 未改动:登录/鉴权契约、后端 API、'问天'冻结区、生产数据/权限
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
82 lines
4.8 KiB
CSS
82 lines
4.8 KiB
CSS
/* B · 值班台账 Ledger Desk —— 表格本身就是主舞台,每条真实事件一行。
|
|
高密度、精密仪器感;按钮/状态/异常一眼可读。 */
|
|
#lg-root { padding: var(--sp3) var(--sp4); max-width: 1680px; margin: 0 auto; }
|
|
#lg-grid { display: grid; grid-template-columns: 250px 1fr 300px; gap: 12px; align-items: start; }
|
|
/* CSS Grid 子项默认 min-width:auto,会被内部宽表格的内在尺寸撑爆整条 1fr 轨道;
|
|
显式清零,让表格自己用 overflow 滚动,而不是撑破布局。 */
|
|
#lg-grid > * { min-width: 0; }
|
|
|
|
#lg-side, #lg-side-r { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
|
|
.lg-panel { padding: 10px 12px; min-width: 0; }
|
|
.lg-panel .sec-label { display: block; margin-bottom: 8px; }
|
|
|
|
.lg-src-row { display: flex; align-items: center; gap: 7px; padding: 5px 0; border-bottom: 1px solid var(--line-soft); font-size: 12px; }
|
|
.lg-src-row:last-child { border-bottom: 0; }
|
|
.lg-src-row .nm { flex: 1; color: var(--t1); }
|
|
.lg-src-row .lat { color: var(--t3); font-size: 11px; }
|
|
.lg-src-row .lamps { display: flex; gap: 3px; }
|
|
|
|
.lg-jobline { display: flex; align-items: center; gap: 6px; padding: 5px 0; border-bottom: 1px solid var(--line-soft); font-size: 12px; }
|
|
.lg-jobline:last-child { border-bottom: 0; }
|
|
.lg-jobline .nm { flex: 1; color: var(--t1); }
|
|
.lg-jobline .at { color: var(--t3); font-size: 11px; }
|
|
.lg-jobline button { margin-left: 4px; }
|
|
|
|
/* -------- 主舞台:事件台账表 -------- */
|
|
#lg-ledger { padding: 10px 12px; }
|
|
#lg-ledger .lg-ledger-hd { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 8px; }
|
|
#lg-ledger .lg-ledger-hd .hint { font-size: 11px; color: var(--t3); }
|
|
table.lg-ledger { width: 100%; border-collapse: collapse; font-size: 12px; }
|
|
table.lg-ledger th {
|
|
position: sticky; top: 0; background: var(--bg1); text-align: left; font-weight: 500; color: var(--t3);
|
|
font-size: 11px; padding: 6px 8px; border-bottom: 1px solid var(--line); white-space: nowrap; z-index: 1;
|
|
}
|
|
table.lg-ledger th.stage { text-align: center; }
|
|
table.lg-ledger td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
|
|
table.lg-ledger td.ev { min-width: 150px; }
|
|
table.lg-ledger td.ev .nm { color: var(--t1); font-weight: 600; font-size: 12.5px; }
|
|
table.lg-ledger td.ev .sub { color: var(--t3); font-size: 10.5px; }
|
|
table.lg-ledger td.src { color: var(--t2); font-size: 11.5px; white-space: nowrap; }
|
|
table.lg-ledger td.stage { text-align: center; white-space: nowrap; }
|
|
.lg-cell {
|
|
display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-width: 58px;
|
|
padding: 3px 7px; border-radius: var(--r-chip); font-family: var(--font-mono); font-size: 11px;
|
|
background: var(--bg2); color: var(--t3); transition: background var(--dur-ui) var(--ease-out), color var(--dur-ui) var(--ease-out);
|
|
}
|
|
.lg-cell.ok { background: var(--alive-soft); color: var(--alive); }
|
|
.lg-cell.err { background: var(--error-soft); color: var(--error); }
|
|
.lg-cell.warn { background: var(--act-soft); color: var(--act); }
|
|
.lg-cell.dash { opacity: .4; }
|
|
tr.lg-row { transition: background var(--dur-ui) var(--ease-out); }
|
|
tr.lg-row.flashnew td { background: var(--action-soft); }
|
|
tr.lg-row.flashnew.err td { background: var(--error-soft); }
|
|
|
|
/* -------- 调用带(持续,只滚真实数据) -------- */
|
|
#lg-tape { margin-top: 10px; padding: 8px 0 0; border-top: 1px solid var(--line-soft); }
|
|
#lg-tape .sec-label { display: block; margin-bottom: 6px; }
|
|
#lg-tape-track { overflow: hidden; white-space: nowrap; position: relative; height: 24px; }
|
|
#lg-tape-inner { display: inline-flex; gap: 22px; will-change: transform; }
|
|
.lg-tape-item { font-family: var(--font-mono); font-size: 11.5px; color: var(--t2); white-space: nowrap; }
|
|
.lg-tape-item b { color: var(--t1); }
|
|
.lg-tape-item.err { color: var(--error); }
|
|
#lg-tape.paused #lg-tape-inner { animation-play-state: paused; }
|
|
|
|
/* -------- 右侧发布/审计 -------- */
|
|
#lg-release table.grid td, #lg-release table.grid th { padding: 5px 6px; font-size: 11px; }
|
|
#lg-release .toolrow { display: flex; gap: 6px; margin-bottom: 8px; }
|
|
#lg-release .toolrow input { width: 84px; font-family: var(--font-mono); font-size: 11px; background: var(--bg2); border: 1px solid var(--line); border-radius: var(--r-chip); padding: 4px 6px; color: var(--t1); }
|
|
.lg-auditline { font-size: 11px; color: var(--t2); padding: 5px 0; border-bottom: 1px solid var(--line-soft); line-height: 1.5; }
|
|
.lg-auditline:last-child { border-bottom: 0; }
|
|
.lg-auditline .dim { color: var(--t3); }
|
|
|
|
@media (max-width: 1280px) {
|
|
#lg-grid { grid-template-columns: 1fr; }
|
|
#lg-side, #lg-side-r { flex-direction: row; flex-wrap: wrap; }
|
|
.lg-panel { flex: 1 1 260px; }
|
|
}
|
|
@media (max-width: 1100px) {
|
|
#lg-root { padding: var(--sp2) var(--sp3); }
|
|
table.lg-ledger { font-size: 11px; }
|
|
.lg-cell { min-width: 46px; font-size: 10px; padding: 2px 5px; }
|
|
}
|