feat: tighten mobile workbench summaries

This commit is contained in:
kris
2026-03-29 23:53:41 +08:00
parent 5ec86ae48a
commit 151129ce26
3 changed files with 43 additions and 0 deletions

View File

@@ -5794,6 +5794,12 @@ function renderPlaybookScreen() {
<div class="panel-subtitle">先处理你当前真的会用到的 Agent 信息系统治理内容已移到管理员配置台</div>
</div>
</div>
<div class="mobile-only compact-summary-row" style="margin-bottom:14px;">
<span class="tag blue"> Agent ${escapeHtml(appState.onelinerProfile?.display_name || "OneLiner")}</span>
<span class="tag">${escapeHtml(currentAssistant ? `当前 ${currentAssistant.name}` : "当前未选 Agent")}</span>
<span class="tag green">模型 ${escapeHtml(formatNumber(models.length))}</span>
<span class="tag ${activeAdminOverrideNotice?.title ? "orange" : "blue"}">${escapeHtml(activeAdminOverrideNotice?.title ? "有管理员覆盖" : "无管理员覆盖")}</span>
</div>
${renderDetailTabs("playbookDetailTab", tabs)}
${activeTab === "workspace" ? `
<div class="layout-grid grid-main">
@@ -6268,6 +6274,12 @@ function renderStrategyScreen() {
<div class="panel-subtitle">先看当前生效,再回看你自己的历史和管理员覆盖,不必再通过多个弹窗来回切。</div>
</div>
</div>
<div class="mobile-only compact-summary-row" style="margin-bottom:14px;">
<span class="tag blue">当前生效 ${escapeHtml(formatNumber(safeArray(appState.onelinerGovernanceEffective?.layers).length))} 层</span>
<span class="tag">${escapeHtml(platformLabel(platform))} 平台策略</span>
<span class="tag green">变更 ${escapeHtml(formatNumber(safeArray(appState.userPolicyAudits).length))}</span>
<span class="tag ${activeAdminOverrideNotice?.title ? "orange" : "blue"}">${escapeHtml(activeAdminOverrideNotice?.title ? "管理员覆盖生效" : "无管理员覆盖")}</span>
</div>
${renderDetailTabs("strategyDetailTab", tabs)}
${activeTab === "effective" ? `
<div class="layout-grid grid-main">

View File

@@ -2040,6 +2040,13 @@ tbody tr:hover {
overflow: hidden;
}
.panel-subtitle {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.action-row {
width: 100%;
flex-wrap: nowrap;
@@ -2186,6 +2193,17 @@ tbody tr:hover {
align-items: flex-start;
}
.task-item p,
.entity-card p,
.topic-card p,
.queue-card p,
.review-card p {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.avatar-lg {
width: 40px;
height: 40px;

View File

@@ -81,6 +81,13 @@ test("strategy navigation and screen are real routes", () => {
assert.match(APP, /screenMap\.strategy\.innerHTML = renderStrategyScreen\(\);/);
});
test("strategy screen exposes a compact mobile summary for current governance state", () => {
const source = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
assert.match(source, /mobile-only compact-summary-row/);
assert.match(source, /当前生效/);
assert.match(source, /平台策略/);
});
test("automation screen stays user-facing and excludes admin-only panels", () => {
const source = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
@@ -94,6 +101,7 @@ test("agent screen excludes quota and registry panels and uses page tabs", () =>
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
assert.doesNotMatch(source, /renderOneLinerActionRegistryPanel\(/);
assert.match(source, /renderDetailTabs\("playbookDetailTab"/);
assert.match(source, /mobile-only compact-summary-row/);
assert.match(source, /renderGovernanceSummaryCard\(/);
assert.match(source, /open-user-global-policy/);
assert.match(source, /open-user-platform-policy/);
@@ -122,6 +130,11 @@ test("projects screen uses an adaptive project grid instead of a fixed three-col
assert.match(CSS, /\.entity-card\.pad\s*\{[\s\S]*padding:\s*15px/);
});
test("mobile typography clamps subtitles and dense card copy on small screens", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.panel-subtitle\s*\{[\s\S]*-webkit-line-clamp:\s*2/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.task-item p,[\s\S]*\.review-card p\s*\{[\s\S]*-webkit-line-clamp:\s*3/);
});
test("dashboard and project screens distinguish auto-connecting from truly disconnected", () => {
const dashboard = extractBetween(APP, "function renderDashboardScreen()", "function renderProjectsScreen()");
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");