style(web): 列表状态灯挪到文件夹行左侧,数据行 space-between 均匀分布(bump 0.38.8)
终态徽章 + 运行圆点放进文件夹行行首(无文件夹行回落数据行,patch 逻辑同规则 找 host);底部数据行剩纯数据均匀铺开,时间自然落行尾。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
259dde502d
commit
d24165a2fe
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
## 已完成关键能力
|
||||
|
||||
### 2026-07-03 / web 列表状态灯挪到文件夹行左侧,数据行均匀分布(bump 0.38.8)
|
||||
用户建议:状态放文件夹名左侧、时间那行正常分布。落地:终态徽章 + 运行圆点挪进文件夹行行首(`● 📁 ppt4`,行首左上区最先被扫到;无文件夹行的 task 回落到数据行行首,`syncTaskRowRunIndicator` 按同规则找 host:`.wd-line` 优先、`.meta.stats` 兜底);底部数据行只剩纯数据(skill/条/tok/时间),改 `justify-content:space-between` 均匀铺开,时间自然落行尾。改 `web/static/js/chat.js` + `web/static/dev.html`。
|
||||
|
||||
### 2026-07-03 / web 列表 meta 行数字组改靠左跟排——修 active 静默后的左侧"缺口"(bump 0.38.7)
|
||||
用户发截图:0.38.6 active 徽章静默后,无 skill 的行(列表主体)meta 行左槽空了,数字组(条/tok)又被 `.num.right-group{margin-left:auto}` 整组挤右,中间留出一块像缺了东西。修:数字组改靠左跟排填上左槽,只有 time-ago 锚行尾(`margin-left:auto` 移到 time-ago);模板删掉已无意义的 `right-group` class。"条/tok"跨行对齐由原有 min-width+右对齐槽位保持。改 `web/static/dev.html` + `web/static/js/chat.js`。
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.38.7"
|
||||
__version__ = "0.38.8"
|
||||
|
|
|
|||
|
|
@ -552,10 +552,13 @@
|
|||
align-items: baseline; font-variant-numeric: tabular-nums; }
|
||||
.task-row .meta > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
|
||||
.task-row .meta .badge { flex-shrink: 0; }
|
||||
/* 数字组靠左跟排(active 徽章静默后左槽常空,整组右挤会留出一块"缺口");
|
||||
固定 min-width + 右对齐让"条/tok"跨行对齐;只有时间锚在行尾 */
|
||||
/* 底部数据行(stats):状态已挪去文件夹行,剩纯数据均匀铺开,时间自然落行尾;
|
||||
固定 min-width + 右对齐让"条/tok"跨行对齐 */
|
||||
.task-row .meta.stats { justify-content: space-between; }
|
||||
.task-row .meta .num { flex-shrink: 0; text-align: right; min-width: 44px; }
|
||||
.task-row .meta .time-ago { flex-shrink: 0; text-align: right; min-width: 64px; margin-left: auto; }
|
||||
.task-row .meta .time-ago { flex-shrink: 0; text-align: right; min-width: 64px; }
|
||||
/* 状态灯(终态徽章 + 运行圆点)在文件夹行(块级文本流)内:垂直居中 + 与 📁 留距 */
|
||||
.task-row .wd-line .badge, .task-row .wd-line .run-ind { vertical-align: middle; margin-right: 4px; }
|
||||
.task-row .badge {
|
||||
display: inline-block; padding: 0 6px; border-radius: var(--r-md); font-size: 11px;
|
||||
background: #eef; color: #336;
|
||||
|
|
|
|||
|
|
@ -163,15 +163,16 @@ function runIndicatorHtml(t) {
|
|||
function syncTaskRowRunIndicator(tid) {
|
||||
const row = document.querySelector(`.task-row[data-tid="${CSS.escape(tid)}"]`);
|
||||
if (!row) return;
|
||||
const metaLine = row.querySelector(".meta:not(.muted)");
|
||||
if (!metaLine) return;
|
||||
const old = metaLine.querySelector(".run-ind");
|
||||
// 圆点 host 与渲染时同规则:优先文件夹行,无文件夹行回落底部数据行
|
||||
const host = row.querySelector(".wd-line") || row.querySelector(".meta.stats");
|
||||
if (!host) return;
|
||||
const old = host.querySelector(".run-ind");
|
||||
if (old) old.remove();
|
||||
const html = runIndicatorHtml((state.tasksById || {})[tid] || { task_id: tid });
|
||||
if (!html) return;
|
||||
const badge = metaLine.querySelector(".badge");
|
||||
const badge = host.querySelector(".badge");
|
||||
if (badge) badge.insertAdjacentHTML("afterend", html);
|
||||
else metaLine.insertAdjacentHTML("afterbegin", html);
|
||||
else host.insertAdjacentHTML("afterbegin", html);
|
||||
}
|
||||
|
||||
function renderTaskList(tasks, append = false) {
|
||||
|
|
@ -195,16 +196,18 @@ function renderTaskList(tasks, append = false) {
|
|||
// st- 前缀防撞 .task-row.active(选中态)——status 值 "active" 不能直接当 class 用
|
||||
const stCls = statusLabel ? ` st-${t.status}` : "";
|
||||
const rowTitle = `${taskName}\n${t.task_id}`; // hover 出全名 + 完整 id(替代 meta 里被去掉的 id8)
|
||||
// 状态(终态徽章 + 运行圆点)放文件夹行左侧——行首左上区最先被扫到;
|
||||
// 无文件夹行的 task 回落到底部数据行行首(syncTaskRowRunIndicator 同规则找 host)
|
||||
const indHtml = `${statusLabel ? `<span class="badge ${t.status}">${statusLabel}</span>` : ""}${runIndicatorHtml(t)}`;
|
||||
// 渠道镜像 task(微信 / 企业微信)不进此列表 —— 后端 /v1/tasks 已排除,改由左栏卡片承载(loadChannelCards)
|
||||
return `
|
||||
<div class="task-row${active}${stCls}" data-tid="${t.task_id}" title="${escapeHtml(rowTitle)}" style="display:flex;align-items:flex-start;gap:6px;">
|
||||
<div style="flex:1;min-width:0;">
|
||||
<div class="desc">${escapeHtml(taskName)}</div>
|
||||
${wdName ? `<div class="meta muted" title="${escapeHtml(t.working_dir || "")}" style="display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">📁 ${escapeHtml(wdName)}</div>` : ""}
|
||||
${wdName ? `<div class="meta muted wd-line" title="${escapeHtml(t.working_dir || "")}" style="display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${indHtml}📁 ${escapeHtml(wdName)}</div>` : ""}
|
||||
${desc ? `<div class="meta muted" title="${escapeHtml(desc)}" style="display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${escapeHtml(desc)}</div>` : ""}
|
||||
<div class="meta">
|
||||
${statusLabel ? `<span class="badge ${t.status}">${statusLabel}</span>` : ""}
|
||||
${runIndicatorHtml(t)}
|
||||
<div class="meta stats">
|
||||
${wdName ? "" : indHtml}
|
||||
${t.skill ? `<span class="muted" title="${escapeHtml(t.skill)}">${escapeHtml(t.skill)}</span>` : ""}
|
||||
<span class="num">${t.n_messages || 0} 条</span>
|
||||
<span class="num" title="${escapeHtml(taskUsageTooltip(t))}">${fmtTokens(t.tokens)} tok</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue