style: v1.6.1 — 状态页明细表排版优化
原来每列都挤、仓库名和分支名被折成两三行、核对时间占两行、提交信息撑高行高、 两个操作按钮上下堆叠。重做表格: - 固定列宽(table-layout:fixed + colgroup),按内容实测分配,1280px 起不再折行 仓库名 17%(DCU_DesktopController 全名显示不截断)、提交列 19% - 仓库名下方小字显示占用大小,省掉一列 - 状态/GitHub 核对改为彩色圆角小标签(✓ 已同步 / ≠ 不同 等),一眼可辨 - 最新提交:短 hash 灰底小标签 + 单行省略的消息,作者/时间降到下方小字 - 最近推送:时间在上、日期在下两行,不再挤成一坨 - 分支/标签合并为「1 / 0」紧凑格式,表头说明 - 操作列两个按钮横排,同步为主色按钮 - 标题栏右侧放「核对 GitHub 实况」,说明文字单独一行,不再和按钮抢位置 - 窄屏卡片模式同步适配新结构(仓库名整行、内容右对齐) - 修 ckChip 映射 bug:same 状态误用了 check 类名,导致「一致」标签没样式
This commit is contained in:
@@ -1042,6 +1042,38 @@ td.ok{color:#0a7d34;font-weight:600;white-space:nowrap}
|
|||||||
td.warn{color:#b45309;font-weight:600;white-space:nowrap}
|
td.warn{color:#b45309;font-weight:600;white-space:nowrap}
|
||||||
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
|
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
|
||||||
.commit{color:#646a73;font-size:12px;margin-top:2px;line-height:1.5}
|
.commit{color:#646a73;font-size:12px;margin-top:2px;line-height:1.5}
|
||||||
|
/* ---------- 状态页明细表(紧凑排版) ---------- */
|
||||||
|
.tblhead{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin:12px 0 10px}
|
||||||
|
.tbltip{font-size:12px;color:#8a919e;line-height:1.6;flex:1;min-width:220px}
|
||||||
|
table.detail{table-layout:fixed;font-size:13px}
|
||||||
|
table.detail th,table.detail td{padding:11px 9px;vertical-align:middle}
|
||||||
|
table.detail th{font-size:11.5px;color:#8a919e;font-weight:600;border-bottom:1.5px solid #e8ebef;white-space:nowrap;padding-bottom:9px}
|
||||||
|
table.detail tbody tr{border-bottom:1px solid #f1f3f6}
|
||||||
|
table.detail tbody tr:hover{background:#fafbfc}
|
||||||
|
table.detail tbody tr:last-child{border-bottom:none}
|
||||||
|
.repo-name{font-weight:600;font-size:13.5px;color:#1f2329;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||||
|
.repo-sub{font-size:11px;color:#a0a6b0;margin-top:3px;white-space:nowrap}
|
||||||
|
.stg{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap}
|
||||||
|
.stg.ok{background:#e3f5e9;color:#0a7d34}
|
||||||
|
.stg.warn{background:#fffaeb;color:#b45309}
|
||||||
|
.ck{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap;cursor:default}
|
||||||
|
.ck.same{background:#e3f5e9;color:#0a7d34}
|
||||||
|
.ck.diff{background:#fffaeb;color:#b45309}
|
||||||
|
.ck.unknown{background:#f1f3f5;color:#959ca8}
|
||||||
|
.br-name{font-size:12.5px;color:#374151;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
|
||||||
|
.br-count{font-size:12.5px;color:#4e5969;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
|
||||||
|
.br-count b{font-weight:600;color:#1f2329}
|
||||||
|
.time-cell{font-size:12.5px;color:#4e5969;white-space:nowrap;line-height:1.35}
|
||||||
|
.time-cell .d{display:block;font-size:11px;color:#a0a6b0;margin-top:2px}
|
||||||
|
.cmt{display:flex;align-items:center;gap:7px;min-width:0}
|
||||||
|
.cmt .h{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;background:#f1f3f5;color:#4e5969;border-radius:5px;padding:2px 6px;flex:none;letter-spacing:.2px}
|
||||||
|
.cmt .m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;color:#1f2329;font-size:12.5px}
|
||||||
|
.cmt-sub{font-size:11px;color:#a0a6b0;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||||
|
.size-cell{font-size:12.5px;color:#4e5969;white-space:nowrap;text-align:right}
|
||||||
|
.rowact{display:flex;gap:6px;justify-content:flex-end;flex-wrap:nowrap}
|
||||||
|
.rowact button{padding:5px 11px;font-size:12px;border-radius:8px;white-space:nowrap}
|
||||||
|
.rowact .b-pri{background:#0a7d34;color:#fff}
|
||||||
|
.rowact .b-pri:hover{background:#086b2c}
|
||||||
h2{font-size:15px;margin-bottom:12px;color:#1f2329}
|
h2{font-size:15px;margin-bottom:12px;color:#1f2329}
|
||||||
pre{background:#0d1117;color:#c9d1d9;border-radius:10px;padding:14px;font-size:12px;line-height:1.6;max-height:300px;overflow:auto;white-space:pre-wrap;word-break:break-all}
|
pre{background:#0d1117;color:#c9d1d9;border-radius:10px;padding:14px;font-size:12px;line-height:1.6;max-height:300px;overflow:auto;white-space:pre-wrap;word-break:break-all}
|
||||||
.tip{font-size:12px;color:#646a73;margin-top:10px;line-height:1.6}
|
.tip{font-size:12px;color:#646a73;margin-top:10px;line-height:1.6}
|
||||||
@@ -1167,6 +1199,22 @@ td.ops button,td.ops .pill{margin:2px 4px 2px 0}
|
|||||||
table.resp tbody td .val{flex:1;text-align:right;min-width:0;word-break:break-word}
|
table.resp tbody td .val{flex:1;text-align:right;min-width:0;word-break:break-word}
|
||||||
table.resp tbody td:has(button){justify-content:flex-end}
|
table.resp tbody td:has(button){justify-content:flex-end}
|
||||||
table.resp tbody td:has(button)::before{margin-right:auto}
|
table.resp tbody td:has(button)::before{margin-right:auto}
|
||||||
|
/* 明细表在窄屏也保持卡片化,但内容右对齐更整齐 */
|
||||||
|
table.detail{font-size:13px}
|
||||||
|
table.detail tbody td{padding:6px 0;align-items:center}
|
||||||
|
table.detail tbody td[data-label="项目"]{padding-top:2px;padding-bottom:8px;border-bottom:1px dashed #eef0f3;margin-bottom:4px;justify-content:flex-start}
|
||||||
|
table.detail tbody td[data-label="项目"]::before{display:none}
|
||||||
|
table.detail .repo-name{font-size:14px;white-space:normal;word-break:break-all}
|
||||||
|
table.detail .repo-sub{display:inline-block;margin-top:2px}
|
||||||
|
table.detail tbody td[data-label="最新提交"]{align-items:flex-start}
|
||||||
|
table.detail tbody td[data-label="最新提交"]>div{max-width:78%}
|
||||||
|
table.detail .cmt{justify-content:flex-end;flex-wrap:wrap}
|
||||||
|
table.detail .cmt .m{white-space:normal;word-break:break-word;text-align:right}
|
||||||
|
table.detail .cmt-sub{white-space:normal}
|
||||||
|
table.detail .size-cell{text-align:right}
|
||||||
|
table.detail .rowact{flex:1;justify-content:flex-end;flex-wrap:wrap}
|
||||||
|
table.detail .rowact button{flex:none}
|
||||||
|
.tbltip{display:none}
|
||||||
pre{font-size:11px;padding:10px}
|
pre{font-size:11px;padding:10px}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@@ -1283,16 +1331,22 @@ PAGE_STATUS = """
|
|||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 style="margin:0">项目明细</h2>
|
<h2 style="margin:0">项目明细<span class="h2sub" id="sTarget"></span></h2>
|
||||||
<span class="tip" id="sTarget"></span>
|
|
||||||
</div>
|
|
||||||
<div class="row" style="margin:10px 0 12px">
|
|
||||||
<div class="tip" id="cmpTip" style="flex:1"></div>
|
|
||||||
<button class="b-mini" id="btnCheck" onclick="checkAll()">🔍 核对 GitHub 实况</button>
|
<button class="b-mini" id="btnCheck" onclick="checkAll()">🔍 核对 GitHub 实况</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tblhead">
|
||||||
|
<div class="tbltip" id="cmpTip"></div>
|
||||||
|
</div>
|
||||||
<div style="overflow-x:auto">
|
<div style="overflow-x:auto">
|
||||||
<table class="resp">
|
<table class="resp detail">
|
||||||
<thead><tr><th>项目</th><th>状态</th><th>默认分支</th><th>分支/标签</th><th>最近推送同步</th><th>GitHub 核对</th><th>最新提交</th><th>大小</th><th></th></tr></thead>
|
<colgroup>
|
||||||
|
<col style="width:17%"><col style="width:9%"><col style="width:13%"><col style="width:11%">
|
||||||
|
<col style="width:11%"><col style="width:10%"><col style="width:19%"><col style="width:10%">
|
||||||
|
</colgroup>
|
||||||
|
<thead><tr>
|
||||||
|
<th>项目</th><th>状态</th><th>默认分支</th><th>分支/标签</th>
|
||||||
|
<th>最近推送</th><th>GitHub 核对</th><th>最新提交</th><th style="text-align:right">操作</th>
|
||||||
|
</tr></thead>
|
||||||
<tbody id="tb"></tbody>
|
<tbody id="tb"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -1318,27 +1372,56 @@ async function refresh(){
|
|||||||
?(rt.pending.length+' 个待重试 · '+rt.next_in+'s后(最多'+rt.max+'次)')
|
?(rt.pending.length+' 个待重试 · '+rt.next_in+'s后(最多'+rt.max+'次)')
|
||||||
:'无待重试';
|
:'无待重试';
|
||||||
document.getElementById('sSize').textContent=s.total_size_mb+' MB';
|
document.getElementById('sSize').textContent=s.total_size_mb+' MB';
|
||||||
document.getElementById('sTarget').textContent='同步目标: '+(s.account?s.account.gh_user+'('+s.account.method+')':'未配置')+' · '+(s.max_workers||1)+' 个并行 · Gitea '+(s.gitea_online?'在线 ✓':'离线 ✗');
|
document.getElementById('sTarget').textContent=(s.account?s.account.gh_user+'('+s.account.method+')':'未配置')+' · '+(s.max_workers||1)+' 个并行 · Gitea '+(s.gitea_online?'在线 ✓':'离线 ✗');
|
||||||
const vg=!!s.verify_github;
|
const vg=!!s.verify_github;
|
||||||
document.getElementById('cmpTip').innerHTML='推送前会先读 GitHub 上的分支和提交号:一致就跳过,不同才推送。'
|
document.getElementById('cmpTip').innerHTML='推送前先读 GitHub 上的分支和提交号,一致就跳过,不同才推送。当前模式:<b>'+(vg?'每轮都核对(严格)':'仅本地有新提交时核对(省流量)')+'</b>,可在 <a href="settings">设置</a> 里切换。';
|
||||||
+'当前模式:<b>'+(vg?'每轮都核对(严格)':'仅本地有新提交时核对(省流量)')+'</b>,可在<a href="settings">设置</a>里切换。';
|
const stChip=(t,c)=>`<span class="stg ${c}">${t}</span>`;
|
||||||
|
const ckChip=(v)=>{
|
||||||
|
const m={same:['same','✓ 一致'],diff:['diff','≠ 不同'],unknown:['unknown','? 未知']};
|
||||||
|
const it=m[v]||m.unknown;
|
||||||
|
return `<span class="ck ${it[0]}">${it[1]}</span>`;
|
||||||
|
};
|
||||||
document.getElementById('tb').innerHTML=s.repos.map(r=>{
|
document.getElementById('tb').innerHTML=s.repos.map(r=>{
|
||||||
const att=(rt.attempts||{})[r.name];
|
const att=(rt.attempts||{})[r.name];
|
||||||
const stTxt=r.status==='已同步'?'✓ 已同步':(att!=null?('⏳ 重试中 '+att+'/'+(rt.max||5)):'⏳ 未同步');
|
const stTxt=r.status==='已同步'?'✓ 已同步':(att!=null?('⏳ 重试 '+att+'/'+(rt.max||5)):'⏳ 未同步');
|
||||||
const stCls=r.status==='已同步'?'ok':'warn';
|
const st=stChip(stTxt, r.status==='已同步'?'ok':'warn');
|
||||||
const st=`<td class="${stCls}">${stTxt}</td>`;
|
|
||||||
const cp=r.compare;
|
const cp=r.compare;
|
||||||
let cpHtml='<span class="tip">未核对</span>';
|
const cpHtml=cp?ckChip(cp.verdict):'<span class="ck unknown">— 未核对</span>';
|
||||||
if(cp){
|
const cpTip=cp?(` title="核对时间 ${esc(cp.at)} · ${esc(cp.detail)}"`):'';
|
||||||
const map={same:['✓ 一致','ok'],diff:['≠ 不同','warn'],unknown:['? 未知','warn']};
|
// 最近推送:日期与时间分行,避免挤成一坨
|
||||||
const mm=map[cp.verdict]||['? 未知','warn'];
|
let pushHtml='<span style="color:#c2c7d0">—</span>';
|
||||||
cpHtml=`<span class="${mm[1]}" title="${esc(cp.detail)} ${esc(cp.at)}">${mm[0]}</span>`
|
if(r.last_push&&r.last_push.includes(' ')){
|
||||||
+`<div class="commit">${esc(cp.at)}</div>`;
|
const [d,t]=r.last_push.split(' ');
|
||||||
|
pushHtml=`<div class="time-cell">${esc(t)}<span class="d">${esc(d)}</span></div>`;
|
||||||
|
}else if(r.last_push){pushHtml=`<div class="time-cell">${esc(r.last_push)}</div>`}
|
||||||
|
// 最新提交:hash 用小标签,消息单行省略,作者/时间放下方
|
||||||
|
let cmtHtml='<span style="color:#c2c7d0">—</span>';
|
||||||
|
if(r.last_commit){
|
||||||
|
const c=r.last_commit;
|
||||||
|
cmtHtml=`<div class="cmt" title="${esc(c.msg||'')}">
|
||||||
|
<span class="h">${esc(c.hash)}</span><span class="m">${esc(c.msg||'')}</span>
|
||||||
|
</div>
|
||||||
|
<div class="cmt-sub" title="${esc((c.author||'')+' · '+(c.time||''))}">${esc(c.author||'')}${c.time?' · '+esc(c.time):''}</div>`;
|
||||||
}
|
}
|
||||||
const c=r.last_commit?`<div class="commit">${esc(r.last_commit.hash)} ${esc(r.last_commit.msg)} · ${esc(r.last_commit.author)} · ${esc(r.last_commit.time)}</div>`:'<div class="commit">—</div>';
|
const headHtml=`<div class="br-name" title="${esc(r.head||'')}">${esc(r.head||'—')}</div>`;
|
||||||
return `<tr><td data-label="项目"><b>${esc(r.name)}</b></td>${st}<td data-label="默认分支">${esc(r.head||'—')}</td><td data-label="分支/标签">${r.branches} / ${r.tags}</td><td data-label="最近推送同步">${r.last_push||'—'}</td><td data-label="GitHub 核对">${cpHtml}</td><td data-label="最新提交">${c}</td><td data-label="大小">${r.size_mb} MB</td><td data-label="操作"><button class="b-mini" onclick="checkOne('${esc(r.name)}')">核对</button> <button class="b-mini" onclick="syncOne('${esc(r.name)}')">同步</button></td></tr>`;
|
return `<tr>
|
||||||
}).join('')||'<tr><td colspan="9" style="color:#646a73">还没有同步项目,去<a href="manage">项目管理</a>添加</td></tr>';
|
<td data-label="项目">
|
||||||
}catch(e){document.getElementById('tb').innerHTML='<tr><td colspan="9">刷新失败: '+e+'</td></tr>'}
|
<div class="repo-name" title="${esc(r.name)}">${esc(r.name)}</div>
|
||||||
|
<div class="repo-sub">${r.size_mb} MB</div>
|
||||||
|
</td>
|
||||||
|
<td data-label="状态">${st}</td>
|
||||||
|
<td data-label="默认分支">${headHtml}</td>
|
||||||
|
<td data-label="分支/标签"><div class="br-count"><b>${r.branches}</b> / ${r.tags}</div></td>
|
||||||
|
<td data-label="最近推送">${pushHtml}</td>
|
||||||
|
<td data-label="GitHub 核对"><span${cpTip}>${cpHtml}</span></td>
|
||||||
|
<td data-label="最新提交">${cmtHtml}</td>
|
||||||
|
<td data-label="操作"><div class="rowact">
|
||||||
|
<button class="b-mini" onclick="checkOne('${esc(r.name)}')">核对</button>
|
||||||
|
<button class="b-mini b-pri" onclick="syncOne('${esc(r.name)}')">同步</button>
|
||||||
|
</div></td>
|
||||||
|
</tr>`;
|
||||||
|
}).join('')||'<tr><td colspan="8" style="color:#646a73;padding:28px;text-align:center">还没有同步项目,去<a href="manage">项目管理</a>添加</td></tr>';
|
||||||
|
}catch(e){document.getElementById('tb').innerHTML='<tr><td colspan="8">刷新失败: '+e+'</td></tr>'}
|
||||||
}
|
}
|
||||||
async function checkOne(n){
|
async function checkOne(n){
|
||||||
const r=await (await fetch('api/repos/check',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:n})})).json();
|
const r=await (await fetch('api/repos/check',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:n})})).json();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
appname = GiteaHubSync
|
appname = GiteaHubSync
|
||||||
version = 1.6.0
|
version = 1.6.1
|
||||||
display_name = Gitea→GitHub 同步助手
|
display_name = Gitea→GitHub 同步助手
|
||||||
desc = 每次推送到飞牛 Gitea 的代码,10 秒内自动镜像到 GitHub 的 7 个私有仓库。内置控制面板:自动同步开关、立即同步、仓库状态、同步日志,一键打开 Gitea。数据全部保存在 NAS 本地。
|
desc = 每次推送到飞牛 Gitea 的代码,10 秒内自动镜像到 GitHub 的 7 个私有仓库。内置控制面板:自动同步开关、立即同步、仓库状态、同步日志,一键打开 Gitea。数据全部保存在 NAS 本地。
|
||||||
platform = all
|
platform = all
|
||||||
|
|||||||
Reference in New Issue
Block a user