diff --git a/docs/screenshots/list-pagination.png b/docs/screenshots/list-pagination.png index 27f2cbc..866a379 100644 Binary files a/docs/screenshots/list-pagination.png and b/docs/screenshots/list-pagination.png differ diff --git a/graylog_ops/watch.py b/graylog_ops/watch.py index 883a80f..641872c 100644 --- a/graylog_ops/watch.py +++ b/graylog_ops/watch.py @@ -1779,6 +1779,32 @@ a:hover{text-decoration:underline} .notes div{font-size:12.5px;color:var(--ink-2);background:var(--surface-2); border:1px solid var(--line);border-radius:9px;padding:9px 12px;line-height:1.55} .hint{color:var(--muted);font-size:12px;margin-top:11px;line-height:1.7} +.pager{display:flex;align-items:center;justify-content:center;gap:18px; + margin:18px 0 2px;color:var(--muted);font-size:12.5px;flex-wrap:wrap} +.pg-total b{color:var(--ink);font-weight:600} +.pg-nav{display:flex;align-items:center;gap:4px} +.pg-num,.pg-arrow{min-width:32px;height:32px;padding:0 9px;border:1px solid transparent; + border-radius:10px;background:transparent;color:var(--ink-2);font-size:13px; + font-family:inherit;line-height:1;cursor:pointer;transition:all .16s ease} +.pg-num:hover,.pg-arrow:hover:not(:disabled){background:#F3EAE0;color:var(--ink)} +.pg-num.active{background:var(--accent);border-color:var(--accent);color:#fff; + font-weight:600;box-shadow:0 3px 10px rgba(193,95,60,.28)} +.pg-arrow{border-color:var(--line);background:var(--card);font-size:16px} +.pg-arrow:hover:not(:disabled){border-color:var(--accent);color:var(--accent); + background:var(--card)} +.pg-arrow:disabled{opacity:.32;cursor:default} +.pg-gap{padding:0 3px;color:#C3B9AA;user-select:none} +.pg-size{display:flex;align-items:center;gap:6px;color:var(--muted)} +.pg-size select{appearance:none;-webkit-appearance:none;padding:6px 26px 6px 10px; + border:1px solid var(--line);border-radius:9px;background:var(--card) + url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%238A8175' fill='none' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E") + no-repeat right 8px center;font-size:12px;color:var(--ink-2);cursor:pointer; + transition:border-color .16s} +.pg-size select:hover,.pg-size select:focus{border-color:#D3B39F;outline:none} +@media (max-width:640px){ + .pager{gap:10px;padding:0 2px} + .pg-total{order:3;width:100%;text-align:center} +} .advice{display:flex;gap:12px;align-items:flex-start;padding:15px 18px; border-radius:12px;border:1px solid #EBC9BD;background:var(--red-soft); color:#7E3020;font-size:13px;line-height:1.6} @@ -2015,7 +2041,6 @@ async function loadList() { render(); renderPager(); $('#listHint').textContent = - `共 ${fmt(state.total)} 条 · 第 ${state.page}/${state.pages} 页 · ` + `按发现时间倒序(最新在前)· 每 30 秒更新`; } catch (err) { $('#rows').innerHTML = `加载失败:${esc(err.message)}`; @@ -2033,17 +2058,43 @@ function filteredItems() { return state.items; } +function pageWindow(current, total) { + const picked = []; + const add = n => { if (n >= 1 && n <= total && !picked.includes(n)) picked.push(n); }; + add(1); + for (let n = current - 2; n <= current + 2; n += 1) add(n); + add(total); + picked.sort((a, b) => a - b); + const out = []; + picked.forEach((n, index) => { + if (index > 0 && n - picked[index - 1] > 1) out.push('gap'); + out.push(n); + }); + return out; +} + function renderPager() { const pager = $('#pager'); if (!pager) return; - const sizes = [20, 50, 100].map(n => - `` + if (state.pages <= 1) { pager.innerHTML = ''; return; } + const nums = pageWindow(state.page, state.pages).map(n => + n === 'gap' + ? '…' + : `` ).join(''); - pager.innerHTML = - `` + - `第 ${state.page} / ${state.pages} 页 · 共 ${fmt(state.total)} 条` + - `` + - ``; + const sizes = [20, 50, 100].map(n => + `` + ).join(''); + pager.innerHTML = ` +
共 ${fmt(state.total)} 条
+
+ + ${nums} + +
+ `; } let toastTimer = null;