Skip to content

Commit 20ead48

Browse files
committed
v10.2: 全局蓝本优先级UI+互斥逻辑+默认勾选全局(947 passed)
1 parent 802b127 commit 20ead48

1 file changed

Lines changed: 74 additions & 6 deletions

File tree

extension/src/sidebarProvider.ts

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -703,15 +703,27 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
703703
704704
// 获取所有选中的蓝本路径
705705
function getSelectedBlueprints() {
706-
const cbs = blueprintListEl.querySelectorAll('input[type="checkbox"]:checked');
706+
const globalCb = document.getElementById("cbGlobalBlueprint");
707+
if (globalCb && globalCb.checked) {
708+
// 全局蓝本:返回所有蓝本路径
709+
return blueprintEntries.map(e => typeof e === "string" ? e : e.path);
710+
}
711+
// 局部蓝本:返回勾选的
712+
const cbs = blueprintListEl.querySelectorAll('.local-blueprint-cb:checked');
707713
return Array.from(cbs).map(cb => cb.value);
708714
}
709715
710-
// 全选/取消全选
716+
// 全选/取消全选(只影响局部蓝本)
711717
document.getElementById("btnSelectAll").addEventListener("click", () => {
712-
const cbs = blueprintListEl.querySelectorAll('input[type="checkbox"]');
713-
const allChecked = Array.from(cbs).every(cb => cb.checked);
714-
cbs.forEach(cb => { cb.checked = !allChecked; });
718+
const globalCb = document.getElementById("cbGlobalBlueprint");
719+
if (globalCb && globalCb.checked) {
720+
// 如果全局已勾选,提示用户先取消全局
721+
addLog("已勾选全局蓝本,无需全选局部。如需局部测试,请先取消全局勾选。", "warn");
722+
return;
723+
}
724+
const localCbs = blueprintListEl.querySelectorAll('.local-blueprint-cb');
725+
const allChecked = Array.from(localCbs).every(cb => cb.checked);
726+
localCbs.forEach(cb => { cb.checked = !allChecked; });
715727
});
716728
717729
// 扫描按钮
@@ -921,6 +933,32 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
921933
blueprintListEl.innerHTML = '<div style="color:var(--muted);padding:8px;text-align:center;font-size:12px">未找到蓝本文件</div>';
922934
return;
923935
}
936+
937+
// 全局蓝本选项(固定在顶部)
938+
const globalItem = document.createElement("label");
939+
globalItem.style.cssText = "display:flex;align-items:center;gap:4px;padding:4px 4px;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;background:var(--bg-secondary,#1e1e1e);border:1px solid var(--border);margin-bottom:4px";
940+
globalItem.title = "勾选后将测试所有蓝本";
941+
942+
const globalCb = document.createElement("input");
943+
globalCb.type = "checkbox";
944+
globalCb.id = "cbGlobalBlueprint";
945+
globalCb.checked = true; // 默认勾选全局
946+
globalCb.style.cssText = "flex-shrink:0;width:14px;height:14px";
947+
948+
const globalLabel = document.createElement("span");
949+
globalLabel.textContent = "🌍 全局蓝本(测试所有)";
950+
globalLabel.style.cssText = "flex:1;color:var(--fg)";
951+
952+
globalItem.appendChild(globalCb);
953+
globalItem.appendChild(globalLabel);
954+
blueprintListEl.appendChild(globalItem);
955+
956+
// 分割线
957+
const divider = document.createElement("div");
958+
divider.style.cssText = "height:1px;background:var(--border);margin:4px 0";
959+
blueprintListEl.appendChild(divider);
960+
961+
// 局部蓝本列表
924962
entries.forEach((entry, i) => {
925963
const path = typeof entry === "string" ? entry : entry.path;
926964
const appName = entry.appName || "";
@@ -937,15 +975,18 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
937975
const tooltipText = desc ? (desc + "\\n场景:" + scenarios + " 步骤:" + steps + "\\n" + path) : ("场景:" + scenarios + " 步骤:" + steps + "\\n" + path);
938976
939977
const item = document.createElement("label");
978+
item.className = "local-blueprint-item";
940979
item.style.cssText = "display:flex;align-items:flex-start;gap:4px;padding:3px 4px;border-radius:4px;cursor:pointer;font-size:12px;line-height:1.4;overflow:hidden;width:100%;box-sizing:border-box";
941980
item.title = tooltipText;
942981
item.addEventListener("mouseenter", () => { item.style.background = "var(--hover-bg,#2a2d2e)"; });
943982
item.addEventListener("mouseleave", () => { item.style.background = "transparent"; });
944983
945984
const cb = document.createElement("input");
946985
cb.type = "checkbox";
986+
cb.className = "local-blueprint-cb";
947987
cb.value = path;
948-
cb.checked = (i === 0);
988+
cb.checked = false; // 默认不选(因为全局已选)
989+
cb.disabled = true; // 默认禁用(因为全局已选)
949990
cb.style.cssText = "margin-top:2px;flex-shrink:0;width:14px;height:14px";
950991
951992
const fileName = path.replace(/\\\\/g, "/").split("/").pop() || path;
@@ -960,6 +1001,33 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
9601001
item.appendChild(info);
9611002
blueprintListEl.appendChild(item);
9621003
});
1004+
1005+
// 全局蓝本checkbox交互逻辑
1006+
globalCb.addEventListener("change", () => {
1007+
const localItems = blueprintListEl.querySelectorAll(".local-blueprint-item");
1008+
const localCbs = blueprintListEl.querySelectorAll(".local-blueprint-cb");
1009+
if (globalCb.checked) {
1010+
// 勾选全局 → 局部全部禁用+灰化
1011+
localCbs.forEach(cb => { cb.disabled = true; cb.checked = false; });
1012+
localItems.forEach(item => {
1013+
item.style.opacity = "0.5";
1014+
item.title = "已勾选全局蓝本,无需勾选局部。如需局部测试,请取消全局勾选。";
1015+
});
1016+
} else {
1017+
// 取消全局 → 局部恢复可选
1018+
localCbs.forEach(cb => { cb.disabled = false; });
1019+
localItems.forEach((item, i) => {
1020+
item.style.opacity = "1";
1021+
const entry = entries[i];
1022+
const desc = entry.description || "";
1023+
const scenarios = entry.scenarioCount || 0;
1024+
const steps = entry.stepCount || 0;
1025+
const path = entry.path;
1026+
item.title = desc ? (desc + "\\n场景:" + scenarios + " 步骤:" + steps + "\\n" + path) : ("场景:" + scenarios + " 步骤:" + steps + "\\n" + path);
1027+
});
1028+
}
1029+
});
1030+
9631031
// 填入第一个路径到手动输入框
9641032
const firstPath = typeof entries[0] === "string" ? entries[0] : entries[0].path;
9651033
inputBlueprintPath.value = firstPath;

0 commit comments

Comments
 (0)