feat: refocus quota and admin ops mutations
This commit is contained in:
@@ -311,3 +311,9 @@
|
||||
- 管理员在切换“覆盖目标”后,会自动回到 `管理员配置台 -> 覆盖与审计`,直接进入当前目标的审计区。
|
||||
- 系统主 Agent 历史回滚、系统平台策略历史回滚完成后,会自动回到 `管理员配置台 -> Agent 治理`,方便连续调整系统默认策略。
|
||||
- 前端回归新增了这三条管理员治理落点断言,锁住“改完就能继续治理”的交互。
|
||||
|
||||
### 额度与管理员运维动作回跳补齐
|
||||
|
||||
- `租户额度` 保存后,现在会自动回到 `额度` 工作区的策略区域,不再只留一条成功提示。
|
||||
- `运维扫描 / 事件审计 / 修复计划生成 / 修复计划审计` 完成后,会统一回到 `管理员配置台 -> 运维审计`,方便连续处理下一条事件。
|
||||
- 前端回归新增了这批动作的 refocus 断言,并锁住了 `credits-quota-anchor` 与 `admin-ops-anchor` 两个工作区锚点。
|
||||
|
||||
@@ -4615,7 +4615,7 @@ function renderAdminOpsPanel() {
|
||||
const overview = appState.adminOpsOverview;
|
||||
if (!overview) {
|
||||
return `
|
||||
<div class="panel pad" style="margin-top:18px;">
|
||||
<div class="panel pad" id="admin-ops-anchor" style="margin-top:18px;">
|
||||
<div class="panel-head"><div><h3>运维与审计 Agent</h3><div class="panel-subtitle">仅平台最高权限用户可见。</div></div></div>
|
||||
<div class="task-item"><h4>尚未拉到概览</h4><p>刷新后会自动读取失败任务、集成健康和待审事件。</p></div>
|
||||
${renderAdminFixRunsPanel()}
|
||||
@@ -4626,7 +4626,7 @@ function renderAdminOpsPanel() {
|
||||
const incidents = safeArray(overview.incidents).slice(0, 6);
|
||||
const audits = safeArray(overview.recent_audits).slice(0, 5);
|
||||
return `
|
||||
<div class="panel pad" style="margin-top:18px;">
|
||||
<div class="panel pad" id="admin-ops-anchor" style="margin-top:18px;">
|
||||
<div class="panel-head">
|
||||
<div>
|
||||
<h3>运维与审计 Agent</h3>
|
||||
@@ -5749,6 +5749,15 @@ function focusTrackingWorkspace() {
|
||||
});
|
||||
}
|
||||
|
||||
function focusCreditsWorkspace(anchorId = "credits-quota-anchor") {
|
||||
setScreen("credits");
|
||||
renderAll();
|
||||
window.requestAnimationFrame(() => {
|
||||
(document.getElementById(anchorId) || document.querySelector('[data-screen="credits"] .mobile-flow-focus-card, [data-screen="credits"] .panel'))
|
||||
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
}
|
||||
|
||||
function focusProductionDetailTab(tabValue) {
|
||||
appState.productionDetailTab = tabValue;
|
||||
setScreen("production");
|
||||
@@ -5803,6 +5812,16 @@ function focusReviewWorkspace(reviewId = "") {
|
||||
});
|
||||
}
|
||||
|
||||
function focusAdminOpsWorkspace(anchorId = "admin-ops-anchor") {
|
||||
appState.adminWorkbenchTab = "ops";
|
||||
setScreen("admin-workbench");
|
||||
renderAll();
|
||||
window.requestAnimationFrame(() => {
|
||||
(document.getElementById(anchorId) || document.querySelector('[data-screen="admin-workbench"] .mobile-flow-focus-card, [data-screen="admin-workbench"] .panel'))
|
||||
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
}
|
||||
|
||||
function renderDiscoveryOverviewSection({ selected, selectedProject, importedSources, tracked, topVideos, reports, latestVideos, currentPlatformLabel, topVideoBatchResult }) {
|
||||
return `
|
||||
<div class="layout-grid grid-main">
|
||||
@@ -7485,7 +7504,7 @@ function renderCreditsScreen() {
|
||||
</div>
|
||||
<div class="layout-grid grid-main" style="margin-top:18px;">
|
||||
<div class="side-stack">
|
||||
<div class="panel pad">
|
||||
<div class="panel pad" id="credits-quota-anchor">
|
||||
<div class="panel-head"><div><h3>当前额度策略</h3><div class="panel-subtitle">先让用户能看懂“还剩多少、风险在哪、下一步怎么做”。</div></div></div>
|
||||
<div class="list">
|
||||
<div class="task-item">
|
||||
@@ -10034,7 +10053,7 @@ function openTenantQuotaAction() {
|
||||
});
|
||||
rememberAction("租户额度已更新", "当前项目的预算与配额已经保存。", "green", saved);
|
||||
await loadAgentControlSurfaces(project.id);
|
||||
renderAll();
|
||||
focusCreditsWorkspace("credits-quota-anchor");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -10284,6 +10303,7 @@ function openBenchmarkLinkAction(defaults = {}) {
|
||||
async function scanAdminOpsAction() {
|
||||
if (!isSuperAdmin()) throw new Error("只有平台管理者才能调用运维 Agent。");
|
||||
setBusy(true, "运维 Agent 正在扫描故障事件...");
|
||||
let shouldRefocus = false;
|
||||
try {
|
||||
const payload = await storyforgeFetch("/v2/admin/ops/incidents/scan", {
|
||||
method: "POST",
|
||||
@@ -10291,9 +10311,14 @@ async function scanAdminOpsAction() {
|
||||
});
|
||||
rememberAction("运维扫描已完成", `本轮共归集 ${formatNumber(payload.count)} 条故障事件。`, payload.count ? "orange" : "green", payload);
|
||||
await loadAgentControlSurfaces(getOneLinerProjectId());
|
||||
shouldRefocus = true;
|
||||
} finally {
|
||||
setBusy(false, "");
|
||||
renderAll();
|
||||
if (shouldRefocus) {
|
||||
focusAdminOpsWorkspace("admin-ops-anchor");
|
||||
} else {
|
||||
renderAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10352,7 +10377,7 @@ function openAdminIncidentReviewAction(incidentId) {
|
||||
});
|
||||
rememberAction("审计结果已保存", `事件「${saved.title}」已更新为 ${saved.status}。`, "green", saved);
|
||||
await loadAgentControlSurfaces(getOneLinerProjectId());
|
||||
renderAll();
|
||||
focusAdminOpsWorkspace("admin-ops-anchor");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -10388,7 +10413,7 @@ function openAdminRepairPlanAction(incidentId) {
|
||||
});
|
||||
rememberAction("修复计划已生成", `已为事件「${incident.title}」生成 repair plan。`, "green", saved);
|
||||
await loadAgentControlSurfaces(getOneLinerProjectId());
|
||||
renderAll();
|
||||
focusAdminOpsWorkspace("admin-ops-anchor");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -10490,7 +10515,7 @@ function openAdminFixRunAuditAction(runId) {
|
||||
});
|
||||
rememberAction("修复计划已审计", `修复计划 ${runId} 已更新为 ${saved.audit_status || values.reviewStatus}。`, "green", saved);
|
||||
await loadAgentControlSurfaces(getOneLinerProjectId());
|
||||
renderAll();
|
||||
focusAdminOpsWorkspace("admin-ops-anchor");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1017,6 +1017,24 @@ test("review actions return to the review workspace with the saved review in foc
|
||||
assert.match(APP, /data-review-id="\$\{escapeHtml\(review\.id\)\}"/);
|
||||
});
|
||||
|
||||
test("quota and admin ops mutations refocus the user into the most relevant workbench area", () => {
|
||||
const quota = extractBetween(APP, "function openTenantQuotaAction()", "function openCreateAssistantAction()");
|
||||
const scanOps = extractBetween(APP, "async function scanAdminOpsAction()", "function openAdminIncidentReviewAction(incidentId)");
|
||||
const reviewIncident = extractBetween(APP, "function openAdminIncidentReviewAction(incidentId)", "function openAdminRepairPlanAction(incidentId)");
|
||||
const repairPlan = extractBetween(APP, "function openAdminRepairPlanAction(incidentId)", "function openAdminFixRunDetailAction(runId)");
|
||||
const auditFixRun = extractBetween(APP, "function openAdminFixRunAuditAction(runId)", "function openJobDetailAction(jobId)");
|
||||
|
||||
assert.match(APP, /function focusCreditsWorkspace\(anchorId = "credits-quota-anchor"\)/);
|
||||
assert.match(APP, /function focusAdminOpsWorkspace\(anchorId = "admin-ops-anchor"\)/);
|
||||
assert.match(APP, /id="credits-quota-anchor"/);
|
||||
assert.match(APP, /id="admin-ops-anchor"/);
|
||||
assert.match(quota, /focusCreditsWorkspace\("credits-quota-anchor"\)/);
|
||||
assert.match(scanOps, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
|
||||
assert.match(reviewIncident, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
|
||||
assert.match(repairPlan, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
|
||||
assert.match(auditFixRun, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
|
||||
});
|
||||
|
||||
test("assistant actions return to the playbook workspace with the saved assistant in focus", () => {
|
||||
const createAssistant = extractBetween(APP, "function openCreateAssistantAction()", "function openEditAssistantAction(assistantId = \"\")");
|
||||
const editAssistant = extractBetween(APP, "function openEditAssistantAction(assistantId = \"\")", "function openAnalyzeSelectedAccountAction()");
|
||||
|
||||
Reference in New Issue
Block a user