fix(ui): 表格行高统一 + 事件区块改为与表格同一套样式
1) 行高不一致(「狼的评论系统」明显矮一截) 实测在线行 58px / 离线行 43px。根因是可用率列的 90 格 mini 条: 它是 inline-flex,参与行内布局时基线把行盒抬高约 15px,于是「有可用率 数据的行」比不带条的行高出一截。 修复:单元格内容统一 vertical-align: middle + mini 条容器改 flex; 实测 6 行全部 43px。 2) 「最近事件」与表格样式不统一 去掉独立的时间线卡片风格,改为与监控表格同构的表格(相同容器圆角、 表头、行分隔、hover、状态底色);故障行淡红、证书行淡琥珀、恢复行不染。 刻意不共用 .monitor-table 类名 —— 共用时面板条目统计被多算 1~8 个 (测试当场抓到),改为独立 .events-table 并显式声明所需样式。 说明:内容长度相当时保证等高;名称/地址特别长时允许换行(上一版按用户 要求做的「完整显示」),此时行更高属于数据本身需要,不再用截断换整齐。 测试:verify-views 新增「内容等长时各行等高」「事件表与监控表同构」 「事件行复用状态底色」断言(并修正了断言脚本改错文件的问题 —— 名称来自 monitors.json 而非 status.json)。六套 171 项全通过。
This commit is contained in:
+42
-14
@@ -300,15 +300,31 @@ async function main() {
|
||||
const dt = await dp.evaluate(() => document.querySelector('tr[data-status] .t-uptime')?.title ?? '');
|
||||
check('表格可用率 tooltip 含 90 天日均延迟', /90 天日均延迟 \d+ ms/.test(dt), dt.slice(0, 60));
|
||||
|
||||
// ---- 极端内容:表格不得把数据截断,同时不得出现横向滚动 ----
|
||||
// 行高一致性要在「内容长度相当」的前提下检查:先把配置里的名称统一成等长短名
|
||||
// (注意:名称来自 monitors.json,不是 status.json),再单独注入超长内容验证不截断
|
||||
const statusPath = path.join(tmpDir, 'status.json');
|
||||
const snap = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
|
||||
const ids = Object.keys(snap.monitors);
|
||||
const cfgPath2 = path.join(tmpDir, 'monitors.json');
|
||||
const cfgJson = JSON.parse(fs.readFileSync(cfgPath2, 'utf8'));
|
||||
let ids = Object.keys(snap.monitors);
|
||||
cfgJson.monitors.forEach((m, i) => { m.name = `目标 ${i + 1}`; });
|
||||
fs.writeFileSync(cfgPath2, `${JSON.stringify(cfgJson, null, 2)}\n`);
|
||||
await dp.goto('http://localhost:8894/?source=static&view=table', { waitUntil: 'domcontentloaded' });
|
||||
await dp.waitForSelector('table.monitor-table tbody tr[data-status]', { timeout: 20000 });
|
||||
await dp.waitForTimeout(900);
|
||||
const heights = await dp.evaluate(() => {
|
||||
const hs = [...document.querySelectorAll('table.monitor-table tbody tr[data-status]')].map((tr) => Math.round(tr.getBoundingClientRect().height));
|
||||
return { hs, unique: [...new Set(hs)] };
|
||||
});
|
||||
check('内容等长时表格各行等高(可用率条不再撑高行)', heights.unique.length === 1, `行高 ${heights.unique.join('/')}(共 ${heights.hs.length} 行)`);
|
||||
|
||||
// ---- 极端内容:表格不得把数据截断,同时不得出现横向滚动 ----
|
||||
let injected = 0;
|
||||
for (const id of ids.slice(0, 2)) {
|
||||
snap.monitors[id].name = `这是一个相当长的监控目标名称用于验证表格完整显示-${id}`;
|
||||
injected++;
|
||||
const m = cfgJson.monitors.find((x) => x.id === id);
|
||||
if (m) { m.name = `这是一个相当长的监控目标名称用于验证表格完整显示-${id}`; injected++; }
|
||||
}
|
||||
fs.writeFileSync(cfgPath2, `${JSON.stringify(cfgJson, null, 2)}\n`);
|
||||
// 注入事件,验证事件区块的时间线样式与折叠
|
||||
snap.events = Array.from({ length: 12 }, (_, i) => ({
|
||||
t: new Date(Date.now() - i * 60000).toISOString(),
|
||||
@@ -337,26 +353,38 @@ async function main() {
|
||||
check(`长名称/长地址不再被截断(注入 ${injected} 个)`, clip.clipped === 0, `截断单元格 ${clip.clipped} 个,最大 ${clip.worst}px`);
|
||||
check('表格仍无横向滚动', clip.pageOverflow <= 0 && clip.tableOverflow <= 0, `页面 ${clip.pageOverflow} / 表格 ${clip.tableOverflow}`);
|
||||
const evr = await dp.evaluate(() => {
|
||||
const ev = document.querySelector('.ev');
|
||||
const cs = ev ? getComputedStyle(ev) : null;
|
||||
const dot = ev ? getComputedStyle(ev, '::before') : null;
|
||||
const table = document.querySelector('.events-table');
|
||||
const evRow = table?.querySelector('tbody tr');
|
||||
const cs = evRow ? getComputedStyle(evRow) : null;
|
||||
const more = document.getElementById('events-more');
|
||||
return {
|
||||
shown: document.querySelectorAll('.ev').length,
|
||||
grid: cs?.display ?? 'none',
|
||||
dotVisible: dot ? dot.width !== '0px' && dot.backgroundColor !== 'rgba(0, 0, 0, 0)' : false,
|
||||
leftBorder: cs?.borderLeftWidth ?? '',
|
||||
shown: (evRow ? table.querySelectorAll('tbody tr').length : 0),
|
||||
tag: table?.tagName ?? 'none',
|
||||
hasThead: Boolean(table?.querySelector('thead th')),
|
||||
headerSameSize: (() => {
|
||||
const mon = document.querySelector('.monitor-table thead th');
|
||||
const ev = table?.querySelector('thead th');
|
||||
return mon && ev ? getComputedStyle(mon).fontSize === getComputedStyle(ev).fontSize : false;
|
||||
})(),
|
||||
rowBg: cs?.backgroundColor ?? '',
|
||||
cellBorder: evRow ? getComputedStyle(evRow.querySelector('td')).borderBottomWidth : '',
|
||||
moreHidden: more?.hidden ?? true,
|
||||
moreText: more?.textContent ?? '',
|
||||
count: document.getElementById('events-count')?.textContent ?? '',
|
||||
};
|
||||
});
|
||||
check('事件区块使用时间线布局(grid + 圆点)', evr.grid === 'grid' && evr.dotVisible === true, `display=${evr.grid} 圆点=${evr.dotVisible}`);
|
||||
check('事件行按类型着色(左描边)', evr.leftBorder === '3px', evr.leftBorder);
|
||||
check('事件区块与监控表格同构(table + thead)', evr.tag === 'TABLE' && evr.hasThead === true && evr.headerSameSize === true, `${evr.tag},表头字号一致=${evr.headerSameSize}`);
|
||||
const evBg = await dp.evaluate(() => {
|
||||
const rows = [...document.querySelectorAll('.events-table tbody tr')];
|
||||
const down = rows.find((r) => r.dataset.status === 'down');
|
||||
const up = rows.find((r) => r.dataset.status === 'up');
|
||||
return { down: down ? getComputedStyle(down).backgroundColor : '无', up: up ? getComputedStyle(up).backgroundColor : '无', downCells: down ? down.querySelectorAll('td').length : 0 };
|
||||
});
|
||||
check('事件行复用表格状态底色(故障行着色、恢复行不染)', /^(color\(|rgba?\(\d)/.test(evBg.down) && evBg.down !== 'rgba(0, 0, 0, 0)' && evBg.up === 'rgba(0, 0, 0, 0)' && evBg.downCells === 4, `故障=${evBg.down.slice(0, 30)} 恢复=${evBg.up} 列数=${evBg.downCells}`);
|
||||
check('事件默认折叠为 8 条并可展开', evr.shown === 8 && evr.moreHidden === false && /展开全部 12 条/.test(evr.moreText), `显示 ${evr.shown} 条,按钮「${evr.moreText}」,计数「${evr.count}」`);
|
||||
await dp.click('#events-more');
|
||||
await dp.waitForTimeout(300);
|
||||
const evExpanded = await dp.evaluate(() => ({ shown: document.querySelectorAll('.ev').length, text: document.getElementById('events-more').textContent }));
|
||||
const evExpanded = await dp.evaluate(() => ({ shown: document.querySelectorAll('.events-table tbody tr').length, text: document.getElementById('events-more').textContent }));
|
||||
check('展开后显示全部事件', evExpanded.shown === 12 && evExpanded.text === '收起', `显示 ${evExpanded.shown} 条`);
|
||||
await dp.close();
|
||||
await new Promise((r) => demoServer.close(r));
|
||||
|
||||
Reference in New Issue
Block a user