fix(file-summary): 调整工作流批次轮播展示

This commit is contained in:
2026-06-06 22:20:26 +08:00
parent 7e561ea213
commit 3c6ec67371
4 changed files with 254 additions and 3 deletions

View File

@@ -941,6 +941,69 @@ input:focus {
list-style: none;
}
.workflow-batch-carousel {
gap: 10px;
}
.workflow-batch-carousel .workflow-card {
display: none;
}
.workflow-batch-carousel .workflow-card.active {
display: grid;
}
.workflow-batch-controls {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-height: 30px;
}
.workflow-batch-btn {
display: inline-grid;
place-items: center;
width: 28px;
height: 28px;
border: 1px solid var(--line);
border-radius: 999px;
background: #ffffff;
color: var(--text);
cursor: pointer;
font-size: 18px;
line-height: 1;
}
.workflow-batch-btn:hover {
border-color: var(--accent);
color: var(--accent);
}
.workflow-batch-dots {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
gap: 6px;
min-width: 0;
}
.workflow-batch-dot {
width: 7px;
height: 7px;
padding: 0;
border: 0;
border-radius: 999px;
background: #cbd5e1;
cursor: pointer;
}
.workflow-batch-dot.active {
width: 18px;
background: var(--accent);
}
.node-status {
display: flex;
align-items: center;

View File

@@ -554,9 +554,86 @@
escapeHtml(batch.batch_no || "文件汇总") +
'</strong><span class="workflow-status status-running">running</span></header><ol></ol>';
workflowCardList.prepend(card);
refreshWorkflowBatchCarousel(0);
return card;
}
function workflowCards() {
if (!workflowCardList) {
return [];
}
return Array.prototype.slice.call(workflowCardList.querySelectorAll(".workflow-card"));
}
function ensureWorkflowBatchControls() {
if (!workflowCardList || workflowCardList.querySelector(".workflow-batch-controls")) {
return;
}
var controls = document.createElement("div");
controls.className = "workflow-batch-controls";
controls.innerHTML =
'<button type="button" class="workflow-batch-btn" data-workflow-action="prev" aria-label="上一个工作流">&lsaquo;</button>' +
'<div class="workflow-batch-dots" aria-label="工作流批次"></div>' +
'<button type="button" class="workflow-batch-btn" data-workflow-action="next" aria-label="下一个工作流">&rsaquo;</button>';
workflowCardList.appendChild(controls);
}
function selectWorkflowBatchIndex(index) {
var cards = workflowCards();
if (!workflowCardList || !cards.length) {
return;
}
var safeIndex = Math.max(0, Math.min(index, cards.length - 1));
workflowCardList.setAttribute("data-active-index", safeIndex);
cards.forEach(function (card, cardIndex) {
var isActive = cardIndex === safeIndex;
card.classList.toggle("active", isActive);
card.setAttribute("data-workflow-index", cardIndex);
card.setAttribute("aria-hidden", isActive ? "false" : "true");
});
var dots = workflowCardList.querySelector(".workflow-batch-dots");
if (!dots) {
return;
}
dots.querySelectorAll("[data-workflow-index-dot]").forEach(function (dot) {
var dotIndex = parseInt(dot.getAttribute("data-workflow-index-dot"), 10);
var isActive = dotIndex === safeIndex;
dot.classList.toggle("active", isActive);
dot.setAttribute("aria-current", isActive ? "true" : "false");
});
}
function refreshWorkflowBatchCarousel(preferredIndex) {
var cards = workflowCards();
if (!workflowCardList || !cards.length) {
return;
}
workflowCardList.classList.add("workflow-batch-carousel");
ensureWorkflowBatchControls();
var dots = workflowCardList.querySelector(".workflow-batch-dots");
if (dots) {
dots.innerHTML = "";
cards.forEach(function (card, index) {
card.setAttribute("data-workflow-index", index);
var title = card.querySelector("strong");
var dot = document.createElement("button");
dot.type = "button";
dot.className = "workflow-batch-dot";
dot.setAttribute("data-workflow-index-dot", index);
dot.setAttribute("aria-label", "查看" + (title ? title.textContent.trim() : "工作流") + "状态");
dots.appendChild(dot);
});
}
var activeIndex =
typeof preferredIndex === "number"
? preferredIndex
: parseInt(workflowCardList.getAttribute("data-active-index") || "0", 10);
if (Number.isNaN(activeIndex)) {
activeIndex = 0;
}
selectWorkflowBatchIndex(activeIndex);
}
async function refreshWorkflowCard(batchId) {
if (!summaryPanel || !batchId) {
return "";
@@ -612,9 +689,37 @@
"%</em>";
list.appendChild(item);
});
refreshWorkflowBatchCarousel();
return payload.batch.status || "";
}
function bindWorkflowBatchCarouselControls() {
if (!workflowCardList) {
return;
}
workflowCardList.addEventListener("click", function (event) {
var cards = workflowCards();
if (!cards.length) {
return;
}
var actionButton = event.target.closest("[data-workflow-action]");
var dotButton = event.target.closest("[data-workflow-index-dot]");
var currentIndex = parseInt(workflowCardList.getAttribute("data-active-index") || "0", 10);
if (Number.isNaN(currentIndex)) {
currentIndex = 0;
}
if (actionButton) {
var nextIndex =
actionButton.getAttribute("data-workflow-action") === "next"
? (currentIndex + 1) % cards.length
: (currentIndex - 1 + cards.length) % cards.length;
selectWorkflowBatchIndex(nextIndex);
} else if (dotButton) {
selectWorkflowBatchIndex(parseInt(dotButton.getAttribute("data-workflow-index-dot"), 10));
}
});
}
function isWorkflowTerminalStatus(status) {
return status === "success" || status === "failed";
}
@@ -817,6 +922,8 @@
syncLatestMessageIdFromDom();
bindNodeAnchorClicks();
renderExistingAssistantMessages();
refreshWorkflowBatchCarousel(0);
bindWorkflowBatchCarouselControls();
refreshRunningWorkflowCards();
if (chatScroll) {