fix(web): improve right workspace spacing

This commit is contained in:
caoqianming 2026-08-19 11:29:35 +08:00
parent d03a743756
commit 6eb382fbda
5 changed files with 51 additions and 10 deletions

View File

@ -52,3 +52,10 @@ test("mobile navigation distinguishes list, files, and software jobs", () => {
assert.match(pageHtml, /id="mv-tab-right"[^>]*data-right-tab="files"/);
assert.match(pageHtml, /id="mv-tab-jobs"[^>]*data-right-tab="jobs"/);
});
test("right workspace widens the legacy default without overriding custom widths", () => {
assert.match(layoutJs, /right: \{ min: 220, max: 560, def: 360 \}/);
assert.match(layoutJs, /!migrated && \(!storedRight \|\| storedRight === "320"\)/);
assert.match(layoutJs, /localStorage\.setItem\(LS_RIGHT_WIDTH_360_MIGRATED, "1"\)/);
assert.match(pageHtml, /--right-grid-width: var\(--right-pane-width, 360px\)/);
});

View File

@ -145,6 +145,11 @@ class StaticVendorTests(unittest.TestCase):
)
self.assertNotIn("hiddenToggle.hidden", files_js)
self.assertRegex(html, r'id="btn-file-add" class="[^"]*\bsmall\b[^"]*\bdd-toggle\b')
self.assertRegex(
html,
r'id="btn-file-add"[^>]*aria-label="添加文件或文件夹"[^>]*></button>',
)
self.assertIn("@container (max-width: 280px)", html)
self.assertNotIn('id="btn-new-folder"', html)
self.assertNotIn('id="btn-src-pick"', html)
self.assertNotIn('id="btn-upload"', html)

View File

@ -498,7 +498,7 @@
#app { display: none; height: 100vh; }
#app.ready {
--left-grid-width: var(--left-pane-width, 320px);
--right-grid-width: var(--right-pane-width, 320px);
--right-grid-width: var(--right-pane-width, 360px);
display: grid;
grid-template-columns: var(--left-grid-width) 6px minmax(0, 1fr) 6px var(--right-grid-width);
grid-template-rows: auto 1fr;
@ -560,7 +560,7 @@
/* min-height: 0 + overflow: hidden 让内部 flex 子项的 overflow: auto 真正生效(否则被默认 min-height: auto 顶出) */
#pane-mid { grid-area: mid; display: flex; flex-direction: column; border-right: 1px solid var(--border); background: var(--panel); min-height: 0; min-width: 0; overflow: hidden; position: relative; }
/* 右侧工作区:页签头固定,文件 / 作业面板各自管理内部滚动 */
#pane-right { grid-area: right; border-right: none; display: flex; flex-direction: column; overflow: hidden; background: var(--panel); min-height: 0; }
#pane-right { grid-area: right; border-right: none; display: flex; flex-direction: column; overflow: hidden; background: var(--panel); min-height: 0; container-type: inline-size; }
#pane-right > .pane-head { flex-shrink: 0; }
.right-workspace-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#right-jobs-panel { display: none; }
@ -1077,16 +1077,30 @@
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px;
}
.proc-toast.fail { border-color: rgba(192,57,43,0.5); }
.right-workspace-head { gap: 4px; }
.right-workspace-head {
gap: 3px; padding-inline: 8px; flex-wrap: nowrap; overflow: hidden;
}
.right-workspace-head .spacer { min-width: 0; }
.mobile-workspace-title { display: none; font-size: 13px; font-weight: 600; }
.workspace-tab {
position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
min-width: 0; padding: 4px 7px; border: 0; border-radius: 6px; background: transparent;
color: var(--muted); cursor: pointer; font-size: 12px;
color: var(--muted); cursor: pointer; font-size: 12px; white-space: nowrap; flex: 0 1 auto;
}
.workspace-tab:hover { background: var(--hover); color: var(--text); }
.workspace-tab.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.workspace-tab svg { width: 16px; height: 16px; flex-shrink: 0; }
.right-workspace-head > .file-panel-control,
.right-workspace-head > #pane-toggle-right {
width: 28px; height: 28px; min-width: 28px; padding: 0;
display: inline-flex; align-items: center; justify-content: center;
white-space: nowrap; flex: 0 0 28px;
}
.right-workspace-head > #btn-file-add { font-size: 18px; line-height: 1; }
@container (max-width: 280px) {
.right-workspace-head .workspace-tab > span:not(.workspace-badge) { display: none; }
.right-workspace-head .workspace-tab { width: 28px; height: 28px; padding: 0; flex: 0 0 28px; }
}
.workspace-badge {
min-width: 16px; height: 16px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center;
border-radius: 999px; background: var(--accent); color: #fff; font-size: 10px; font-style: normal; line-height: 1;
@ -2173,9 +2187,9 @@
</button>
<span class="spacer"></span>
<button id="btn-toggle-hidden" class="small file-panel-control" title="显示技术目录" aria-label="显示技术目录" aria-pressed="false">.*</button>
<button id="btn-file-add" class="small dd-toggle file-panel-control" title="添加文件或文件夹" aria-label="添加文件或文件夹"> 添加</button>
<button id="btn-refresh-files" class="small file-panel-control" title="刷新文件"></button>
<button id="pane-toggle-right" class="small" title="折叠工作区"></button>
<button id="btn-file-add" class="small dd-toggle file-panel-control" title="添加文件或文件夹" aria-label="添加文件或文件夹"></button>
<button id="btn-refresh-files" class="small file-panel-control" title="刷新文件" aria-label="刷新文件"></button>
<button id="pane-toggle-right" class="small" title="折叠工作区" aria-label="折叠工作区"></button>
</div>
<div id="right-files-panel" class="right-workspace-panel" role="tabpanel" aria-labelledby="right-tab-files">
<div id="file-context" class="file-context">

View File

@ -2,10 +2,16 @@
// 右栏是应用内工作区:展开时在“文件 / 软件作业”之间切换,折叠时两个
// activity icon 仍可达。这一层不依赖外层 header标准 / embed 共用。
import { $ } from "./dom.js";
import { LS_LEFT_COLLAPSED, LS_RIGHT_COLLAPSED, LS_LEFT_WIDTH, LS_RIGHT_WIDTH } from "./state.js";
import {
LS_LEFT_COLLAPSED,
LS_RIGHT_COLLAPSED,
LS_LEFT_WIDTH,
LS_RIGHT_WIDTH,
LS_RIGHT_WIDTH_360_MIGRATED,
} from "./state.js";
// ───── pane 折叠 + splitters(rail 模式 + localStorage 持久化) ─────
const PANE_W = { left: { min: 220, max: 560, def: 320 }, right: { min: 220, max: 560, def: 320 } };
const PANE_W = { left: { min: 220, max: 560, def: 320 }, right: { min: 220, max: 560, def: 360 } };
function clampPaneWidth(side, value) {
const cfg = PANE_W[side];
const n = Number(value);
@ -19,7 +25,15 @@ function applyPaneWidth(side, value) {
}
function restorePaneWidths() {
applyPaneWidth("left", localStorage.getItem(LS_LEFT_WIDTH) || PANE_W.left.def);
applyPaneWidth("right", localStorage.getItem(LS_RIGHT_WIDTH) || PANE_W.right.def);
const storedRight = localStorage.getItem(LS_RIGHT_WIDTH);
const migrated = localStorage.getItem(LS_RIGHT_WIDTH_360_MIGRATED) === "1";
// 旧版启动时会把 320px 默认值写进 localStorage。仅一次性提升这个旧默认
// 用户手动拖到的其他宽度继续尊重,迁移后再拖回 320px 也不会被重复覆盖。
const rightWidth = !migrated && (!storedRight || storedRight === "320")
? PANE_W.right.def
: (storedRight || PANE_W.right.def);
applyPaneWidth("right", rightWidth);
localStorage.setItem(LS_RIGHT_WIDTH_360_MIGRATED, "1");
}
// 折叠 = pane 收成 40px rail,只留 toggle 一直可点;按钮符号根据状态翻向

View File

@ -10,6 +10,7 @@ export const LS_LEFT_COLLAPSED = "zcbot.left-collapsed";
export const LS_RIGHT_COLLAPSED = "zcbot.right-collapsed";
export const LS_LEFT_WIDTH = "zcbot.left-width";
export const LS_RIGHT_WIDTH = "zcbot.right-width";
export const LS_RIGHT_WIDTH_360_MIGRATED = "zcbot.right-width-360-migrated";
export const LS_TASK_FILTERS_COLLAPSED = "zcbot.task-filters-collapsed"; // 左栏筛选区折叠偏好(默认折叠)
// ?embed=1&parent_origin=https://... → iframe 模式;父页面用 postMessage 推 token