mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-05-24 00:14:08 +02:00
Add files via upload
This commit is contained in:
@@ -6246,6 +6246,27 @@ header {
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.tasks-filters input[type="text"] {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
font-size: 0.875rem;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
width: 100%;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tasks-filters input[type="text"]:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-color);
|
||||
box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1);
|
||||
}
|
||||
|
||||
.tasks-filters input[type="text"]:hover {
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.tasks-batch-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
+22
-14
@@ -871,10 +871,6 @@ function addMessage(role, content, mcpExecutionIds = null, progressId = null, cr
|
||||
|
||||
// 渲染过程详情
|
||||
function renderProcessDetails(messageId, processDetails) {
|
||||
if (!processDetails || processDetails.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const messageElement = document.getElementById(messageId);
|
||||
if (!messageElement) {
|
||||
return;
|
||||
@@ -942,7 +938,7 @@ function renderProcessDetails(messageId, processDetails) {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建时间线
|
||||
// 创建时间线(即使没有processDetails也要创建,以便展开详情按钮能正常工作)
|
||||
const timelineId = detailsId + '-timeline';
|
||||
let timeline = document.getElementById(timelineId);
|
||||
|
||||
@@ -958,9 +954,19 @@ function renderProcessDetails(messageId, processDetails) {
|
||||
detailsContainer.appendChild(contentDiv);
|
||||
}
|
||||
|
||||
// 如果没有processDetails或为空,显示空状态
|
||||
if (!processDetails || processDetails.length === 0) {
|
||||
// 显示空状态提示
|
||||
timeline.innerHTML = '<div class="progress-timeline-empty">暂无过程详情(可能执行过快或未触发详细事件)</div>';
|
||||
// 默认折叠
|
||||
timeline.classList.remove('expanded');
|
||||
return;
|
||||
}
|
||||
|
||||
// 清空时间线并重新渲染
|
||||
timeline.innerHTML = '';
|
||||
|
||||
|
||||
// 渲染每个过程详情事件
|
||||
processDetails.forEach(detail => {
|
||||
const eventType = detail.eventType || '';
|
||||
@@ -1606,17 +1612,19 @@ async function loadConversation(conversationId) {
|
||||
|
||||
// 传递消息的创建时间
|
||||
const messageId = addMessage(msg.role, displayContent, msg.mcpExecutionIds || [], null, msg.createdAt);
|
||||
// 如果有过程详情,显示它们
|
||||
if (msg.processDetails && msg.processDetails.length > 0 && msg.role === 'assistant') {
|
||||
// 对于助手消息,总是渲染过程详情(即使没有processDetails也要显示展开详情按钮)
|
||||
if (msg.role === 'assistant') {
|
||||
// 延迟一下,确保消息已经渲染
|
||||
setTimeout(() => {
|
||||
renderProcessDetails(messageId, msg.processDetails);
|
||||
// 检查是否有错误或取消事件,如果有,确保详情默认折叠
|
||||
const hasErrorOrCancelled = msg.processDetails.some(d =>
|
||||
d.eventType === 'error' || d.eventType === 'cancelled'
|
||||
);
|
||||
if (hasErrorOrCancelled) {
|
||||
collapseAllProgressDetails(messageId, null);
|
||||
renderProcessDetails(messageId, msg.processDetails || []);
|
||||
// 如果有过程详情,检查是否有错误或取消事件,如果有,确保详情默认折叠
|
||||
if (msg.processDetails && msg.processDetails.length > 0) {
|
||||
const hasErrorOrCancelled = msg.processDetails.some(d =>
|
||||
d.eventType === 'error' || d.eventType === 'cancelled'
|
||||
);
|
||||
if (hasErrorOrCancelled) {
|
||||
collapseAllProgressDetails(messageId, null);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
+218
-28
@@ -706,7 +706,14 @@ window.clearTasksHistory = clearTasksHistory;
|
||||
const batchQueuesState = {
|
||||
queues: [],
|
||||
currentQueueId: null,
|
||||
refreshInterval: null
|
||||
refreshInterval: null,
|
||||
// 筛选和分页状态
|
||||
filterStatus: 'all', // 'all', 'pending', 'running', 'paused', 'completed', 'cancelled'
|
||||
searchKeyword: '',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
totalPages: 1
|
||||
};
|
||||
|
||||
// 显示批量导入模态框
|
||||
@@ -802,19 +809,37 @@ async function createBatchQueue() {
|
||||
}
|
||||
|
||||
// 加载批量任务队列列表
|
||||
async function loadBatchQueues() {
|
||||
async function loadBatchQueues(page) {
|
||||
const section = document.getElementById('batch-queues-section');
|
||||
if (!section) return;
|
||||
|
||||
// 如果指定了page,使用它;否则使用当前页
|
||||
if (page !== undefined) {
|
||||
batchQueuesState.currentPage = page;
|
||||
}
|
||||
|
||||
// 构建查询参数
|
||||
const params = new URLSearchParams();
|
||||
params.append('page', batchQueuesState.currentPage.toString());
|
||||
params.append('limit', batchQueuesState.pageSize.toString());
|
||||
if (batchQueuesState.filterStatus && batchQueuesState.filterStatus !== 'all') {
|
||||
params.append('status', batchQueuesState.filterStatus);
|
||||
}
|
||||
if (batchQueuesState.searchKeyword) {
|
||||
params.append('keyword', batchQueuesState.searchKeyword);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiFetch('/api/batch-tasks');
|
||||
const response = await apiFetch(`/api/batch-tasks?${params.toString()}`);
|
||||
if (!response.ok) {
|
||||
throw new Error('获取批量任务队列失败');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
batchQueuesState.queues = result.queues || [];
|
||||
renderBatchQueues(batchQueuesState.queues);
|
||||
batchQueuesState.total = result.total || 0;
|
||||
batchQueuesState.totalPages = result.total_pages || 1;
|
||||
renderBatchQueues();
|
||||
} catch (error) {
|
||||
console.error('加载批量任务队列失败:', error);
|
||||
section.style.display = 'block';
|
||||
@@ -825,26 +850,42 @@ async function loadBatchQueues() {
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选批量任务队列
|
||||
function filterBatchQueues() {
|
||||
const statusFilter = document.getElementById('batch-queues-status-filter');
|
||||
const searchInput = document.getElementById('batch-queues-search');
|
||||
|
||||
if (statusFilter) {
|
||||
batchQueuesState.filterStatus = statusFilter.value;
|
||||
}
|
||||
if (searchInput) {
|
||||
batchQueuesState.searchKeyword = searchInput.value.trim();
|
||||
}
|
||||
|
||||
// 重置到第一页并重新加载
|
||||
batchQueuesState.currentPage = 1;
|
||||
loadBatchQueues(1);
|
||||
}
|
||||
|
||||
// 渲染批量任务队列列表
|
||||
function renderBatchQueues(queues) {
|
||||
function renderBatchQueues() {
|
||||
const section = document.getElementById('batch-queues-section');
|
||||
const list = document.getElementById('batch-queues-list');
|
||||
const pagination = document.getElementById('batch-queues-pagination');
|
||||
|
||||
if (!section || !list) return;
|
||||
|
||||
section.style.display = 'block';
|
||||
|
||||
const queues = batchQueuesState.queues;
|
||||
|
||||
if (queues.length === 0) {
|
||||
list.innerHTML = '<div class="tasks-empty"><p>当前没有批量任务队列</p></div>';
|
||||
if (pagination) pagination.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// 按创建时间倒序排序
|
||||
const sortedQueues = [...queues].sort((a, b) =>
|
||||
new Date(b.createdAt) - new Date(a.createdAt)
|
||||
);
|
||||
|
||||
list.innerHTML = sortedQueues.map(queue => {
|
||||
list.innerHTML = queues.map(queue => {
|
||||
const statusMap = {
|
||||
'pending': { text: '待执行', class: 'batch-queue-status-pending' },
|
||||
'running': { text: '执行中', class: 'batch-queue-status-running' },
|
||||
@@ -874,7 +915,8 @@ function renderBatchQueues(queues) {
|
||||
});
|
||||
|
||||
const progress = stats.total > 0 ? Math.round((stats.completed + stats.failed + stats.cancelled) / stats.total * 100) : 0;
|
||||
const canDelete = queue.status === 'pending'; // 只有待执行状态的队列可以删除
|
||||
// 允许删除待执行、已完成或已取消状态的队列
|
||||
const canDelete = queue.status === 'pending' || queue.status === 'completed' || queue.status === 'cancelled';
|
||||
|
||||
return `
|
||||
<div class="batch-queue-item" data-queue-id="${queue.id}" onclick="showBatchQueueDetail('${queue.id}')">
|
||||
@@ -905,6 +947,134 @@ function renderBatchQueues(queues) {
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
// 渲染分页控件
|
||||
renderBatchQueuesPagination();
|
||||
}
|
||||
|
||||
// 渲染批量任务队列分页控件
|
||||
function renderBatchQueuesPagination() {
|
||||
const paginationContainer = document.getElementById('batch-queues-pagination');
|
||||
if (!paginationContainer) return;
|
||||
|
||||
const { currentPage, pageSize, total, totalPages } = batchQueuesState;
|
||||
|
||||
// 如果没有数据,不显示分页控件
|
||||
if (total === 0) {
|
||||
paginationContainer.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 即使只有一页,也显示分页信息(总数和每页条数选择器)
|
||||
|
||||
// 计算显示的页码范围
|
||||
let startPage = Math.max(1, currentPage - 2);
|
||||
let endPage = Math.min(totalPages, currentPage + 2);
|
||||
|
||||
// 确保显示5个页码(如果可能)
|
||||
if (endPage - startPage < 4) {
|
||||
if (startPage === 1) {
|
||||
endPage = Math.min(totalPages, startPage + 4);
|
||||
} else if (endPage === totalPages) {
|
||||
startPage = Math.max(1, endPage - 4);
|
||||
}
|
||||
}
|
||||
|
||||
let paginationHTML = '<div class="pagination">';
|
||||
|
||||
const startItem = (currentPage - 1) * pageSize + 1;
|
||||
const endItem = Math.min(currentPage * pageSize, total);
|
||||
paginationHTML += `<div class="pagination-info">显示 ${startItem}-${endItem} / 共 ${total} 条</div>`;
|
||||
|
||||
// 每页条数选择器
|
||||
paginationHTML += `
|
||||
<div class="pagination-page-size">
|
||||
<label for="batch-queues-page-size-pagination">每页:</label>
|
||||
<select id="batch-queues-page-size-pagination" onchange="changeBatchQueuesPageSize()">
|
||||
<option value="10" ${pageSize === 10 ? 'selected' : ''}>10</option>
|
||||
<option value="20" ${pageSize === 20 ? 'selected' : ''}>20</option>
|
||||
<option value="50" ${pageSize === 50 ? 'selected' : ''}>50</option>
|
||||
<option value="100" ${pageSize === 100 ? 'selected' : ''}>100</option>
|
||||
</select>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 只有当有多页时才显示页码导航
|
||||
if (totalPages > 1) {
|
||||
paginationHTML += '<div class="pagination-controls">';
|
||||
|
||||
// 上一页按钮
|
||||
if (currentPage > 1) {
|
||||
paginationHTML += `<button class="pagination-btn" onclick="goBatchQueuesPage(${currentPage - 1})" title="上一页">‹</button>`;
|
||||
} else {
|
||||
paginationHTML += '<button class="pagination-btn disabled" disabled>‹</button>';
|
||||
}
|
||||
|
||||
// 第一页
|
||||
if (startPage > 1) {
|
||||
paginationHTML += `<button class="pagination-btn" onclick="goBatchQueuesPage(1)">1</button>`;
|
||||
if (startPage > 2) {
|
||||
paginationHTML += '<span class="pagination-ellipsis">...</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// 页码按钮
|
||||
for (let i = startPage; i <= endPage; i++) {
|
||||
if (i === currentPage) {
|
||||
paginationHTML += `<button class="pagination-btn active">${i}</button>`;
|
||||
} else {
|
||||
paginationHTML += `<button class="pagination-btn" onclick="goBatchQueuesPage(${i})">${i}</button>`;
|
||||
}
|
||||
}
|
||||
|
||||
// 最后一页
|
||||
if (endPage < totalPages) {
|
||||
if (endPage < totalPages - 1) {
|
||||
paginationHTML += '<span class="pagination-ellipsis">...</span>';
|
||||
}
|
||||
paginationHTML += `<button class="pagination-btn" onclick="goBatchQueuesPage(${totalPages})">${totalPages}</button>`;
|
||||
}
|
||||
|
||||
// 下一页按钮
|
||||
if (currentPage < totalPages) {
|
||||
paginationHTML += `<button class="pagination-btn" onclick="goBatchQueuesPage(${currentPage + 1})" title="下一页">›</button>`;
|
||||
} else {
|
||||
paginationHTML += '<button class="pagination-btn disabled" disabled>›</button>';
|
||||
}
|
||||
|
||||
paginationHTML += '</div>';
|
||||
}
|
||||
|
||||
paginationHTML += '</div>';
|
||||
|
||||
paginationContainer.innerHTML = paginationHTML;
|
||||
}
|
||||
|
||||
// 跳转到指定页面
|
||||
function goBatchQueuesPage(page) {
|
||||
const { totalPages } = batchQueuesState;
|
||||
if (page < 1 || page > totalPages) return;
|
||||
|
||||
loadBatchQueues(page);
|
||||
|
||||
// 滚动到列表顶部
|
||||
const list = document.getElementById('batch-queues-list');
|
||||
if (list) {
|
||||
list.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
}
|
||||
|
||||
// 改变每页显示数量
|
||||
function changeBatchQueuesPageSize() {
|
||||
const pageSizeSelect = document.getElementById('batch-queues-page-size-pagination');
|
||||
if (!pageSizeSelect) return;
|
||||
|
||||
const newPageSize = parseInt(pageSizeSelect.value, 10);
|
||||
if (newPageSize && newPageSize > 0) {
|
||||
batchQueuesState.pageSize = newPageSize;
|
||||
batchQueuesState.currentPage = 1; // 重置到第一页
|
||||
loadBatchQueues(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示批量任务队列详情
|
||||
@@ -934,22 +1104,39 @@ async function showBatchQueueDetail(queueId) {
|
||||
}
|
||||
|
||||
// 更新按钮显示
|
||||
const pauseBtn = document.getElementById('batch-queue-pause-btn');
|
||||
if (addTaskBtn) {
|
||||
addTaskBtn.style.display = queue.status === 'pending' ? 'inline-block' : 'none';
|
||||
}
|
||||
if (startBtn) {
|
||||
// pending状态显示"开始执行",paused状态显示"继续执行"
|
||||
startBtn.style.display = (queue.status === 'pending' || queue.status === 'paused') ? 'inline-block' : 'none';
|
||||
if (startBtn && queue.status === 'paused') {
|
||||
startBtn.textContent = '继续执行';
|
||||
} else if (startBtn && queue.status === 'pending') {
|
||||
startBtn.textContent = '开始执行';
|
||||
}
|
||||
}
|
||||
if (cancelBtn) {
|
||||
cancelBtn.style.display = (queue.status === 'running' || queue.status === 'paused') ? 'inline-block' : 'none';
|
||||
if (pauseBtn) {
|
||||
// running状态显示"暂停队列"
|
||||
pauseBtn.style.display = queue.status === 'running' ? 'inline-block' : 'none';
|
||||
}
|
||||
if (deleteBtn) {
|
||||
// 允许删除待执行、已完成或已取消状态的队列
|
||||
deleteBtn.style.display = (queue.status === 'pending' || queue.status === 'completed' || queue.status === 'cancelled') ? 'inline-block' : 'none';
|
||||
deleteBtn.style.display = (queue.status === 'pending' || queue.status === 'completed' || queue.status === 'cancelled' || queue.status === 'paused') ? 'inline-block' : 'none';
|
||||
}
|
||||
|
||||
// 渲染任务列表
|
||||
const statusMap = {
|
||||
// 队列状态映射
|
||||
const queueStatusMap = {
|
||||
'pending': { text: '待执行', class: 'batch-queue-status-pending' },
|
||||
'running': { text: '执行中', class: 'batch-queue-status-running' },
|
||||
'paused': { text: '已暂停', class: 'batch-queue-status-paused' },
|
||||
'completed': { text: '已完成', class: 'batch-queue-status-completed' },
|
||||
'cancelled': { text: '已取消', class: 'batch-queue-status-cancelled' }
|
||||
};
|
||||
|
||||
// 任务状态映射
|
||||
const taskStatusMap = {
|
||||
'pending': { text: '待执行', class: 'batch-task-status-pending' },
|
||||
'running': { text: '执行中', class: 'batch-task-status-running' },
|
||||
'completed': { text: '已完成', class: 'batch-task-status-completed' },
|
||||
@@ -963,7 +1150,7 @@ async function showBatchQueueDetail(queueId) {
|
||||
<strong>队列ID:</strong> <code>${escapeHtml(queue.id)}</code>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<strong>状态:</strong> <span class="batch-queue-status ${statusMap[queue.status]?.class || ''}">${statusMap[queue.status]?.text || queue.status}</span>
|
||||
<strong>状态:</strong> <span class="batch-queue-status ${queueStatusMap[queue.status]?.class || ''}">${queueStatusMap[queue.status]?.text || queue.status}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<strong>创建时间:</strong> ${new Date(queue.createdAt).toLocaleString('zh-CN')}
|
||||
@@ -977,7 +1164,7 @@ async function showBatchQueueDetail(queueId) {
|
||||
<div class="batch-queue-tasks-list">
|
||||
<h4>任务列表</h4>
|
||||
${queue.tasks.map((task, index) => {
|
||||
const taskStatus = statusMap[task.status] || { text: task.status, class: 'batch-task-status-unknown' };
|
||||
const taskStatus = taskStatusMap[task.status] || { text: task.status, class: 'batch-task-status-unknown' };
|
||||
const canEdit = queue.status === 'pending' && task.status === 'pending';
|
||||
const taskMessageEscaped = escapeHtml(task.message).replace(/'/g, "'").replace(/"/g, """).replace(/\n/g, "\\n");
|
||||
return `
|
||||
@@ -1036,31 +1223,31 @@ async function startBatchQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
// 取消批量任务队列
|
||||
async function cancelBatchQueue() {
|
||||
// 暂停批量任务队列
|
||||
async function pauseBatchQueue() {
|
||||
const queueId = batchQueuesState.currentQueueId;
|
||||
if (!queueId) return;
|
||||
|
||||
if (!confirm('确定要取消这个批量任务队列吗?当前正在执行的任务将被停止,后续任务也不会执行。')) {
|
||||
if (!confirm('确定要暂停这个批量任务队列吗?当前正在执行的任务将被停止,后续任务将保留待执行状态。')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiFetch(`/api/batch-tasks/${queueId}/cancel`, {
|
||||
const response = await apiFetch(`/api/batch-tasks/${queueId}/pause`, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const result = await response.json().catch(() => ({}));
|
||||
throw new Error(result.error || '取消批量任务失败');
|
||||
throw new Error(result.error || '暂停批量任务失败');
|
||||
}
|
||||
|
||||
// 刷新详情
|
||||
showBatchQueueDetail(queueId);
|
||||
refreshBatchQueues();
|
||||
} catch (error) {
|
||||
console.error('取消批量任务失败:', error);
|
||||
alert('取消批量任务失败: ' + error.message);
|
||||
console.error('暂停批量任务失败:', error);
|
||||
alert('暂停批量任务失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1158,7 +1345,7 @@ function stopBatchQueueRefresh() {
|
||||
|
||||
// 刷新批量任务队列列表
|
||||
async function refreshBatchQueues() {
|
||||
await loadBatchQueues();
|
||||
await loadBatchQueues(batchQueuesState.currentPage);
|
||||
}
|
||||
|
||||
// 查看批量任务的对话
|
||||
@@ -1487,7 +1674,7 @@ window.closeBatchImportModal = closeBatchImportModal;
|
||||
window.createBatchQueue = createBatchQueue;
|
||||
window.showBatchQueueDetail = showBatchQueueDetail;
|
||||
window.startBatchQueue = startBatchQueue;
|
||||
window.cancelBatchQueue = cancelBatchQueue;
|
||||
window.pauseBatchQueue = pauseBatchQueue;
|
||||
window.deleteBatchQueue = deleteBatchQueue;
|
||||
window.closeBatchQueueDetailModal = closeBatchQueueDetailModal;
|
||||
window.refreshBatchQueues = refreshBatchQueues;
|
||||
@@ -1496,6 +1683,9 @@ window.editBatchTask = editBatchTask;
|
||||
window.editBatchTaskFromElement = editBatchTaskFromElement;
|
||||
window.closeEditBatchTaskModal = closeEditBatchTaskModal;
|
||||
window.saveBatchTask = saveBatchTask;
|
||||
window.filterBatchQueues = filterBatchQueues;
|
||||
window.goBatchQueuesPage = goBatchQueuesPage;
|
||||
window.changeBatchQueuesPageSize = changeBatchQueuesPageSize;
|
||||
window.showAddBatchTaskModal = showAddBatchTaskModal;
|
||||
window.closeAddBatchTaskModal = closeAddBatchTaskModal;
|
||||
window.saveAddBatchTask = saveAddBatchTask;
|
||||
|
||||
@@ -571,7 +571,28 @@
|
||||
<div class="batch-queues-header">
|
||||
<h3>批量任务队列</h3>
|
||||
</div>
|
||||
<!-- 筛选控件 -->
|
||||
<div class="batch-queues-filters tasks-filters">
|
||||
<label>
|
||||
<span>状态筛选</span>
|
||||
<select id="batch-queues-status-filter" onchange="filterBatchQueues()">
|
||||
<option value="all">全部</option>
|
||||
<option value="pending">待执行</option>
|
||||
<option value="running">执行中</option>
|
||||
<option value="paused">已暂停</option>
|
||||
<option value="completed">已完成</option>
|
||||
<option value="cancelled">已取消</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="flex: 1; max-width: 300px;">
|
||||
<span>搜索队列ID或创建时间</span>
|
||||
<input type="text" id="batch-queues-search" placeholder="输入关键字搜索..."
|
||||
oninput="filterBatchQueues()">
|
||||
</label>
|
||||
</div>
|
||||
<div id="batch-queues-list" class="batch-queues-list"></div>
|
||||
<!-- 分页控件 -->
|
||||
<div id="batch-queues-pagination"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1166,7 +1187,7 @@
|
||||
<div class="modal-header-actions">
|
||||
<button class="btn-secondary" id="batch-queue-add-task-btn" onclick="showAddBatchTaskModal()" style="display: none;">添加任务</button>
|
||||
<button class="btn-primary" id="batch-queue-start-btn" onclick="startBatchQueue()" style="display: none;">开始执行</button>
|
||||
<button class="btn-secondary btn-danger" id="batch-queue-cancel-btn" onclick="cancelBatchQueue()" style="display: none;">取消队列</button>
|
||||
<button class="btn-secondary" id="batch-queue-pause-btn" onclick="pauseBatchQueue()" style="display: none;">暂停队列</button>
|
||||
<button class="btn-secondary btn-danger" id="batch-queue-delete-btn" onclick="deleteBatchQueue()" style="display: none;">删除队列</button>
|
||||
</div>
|
||||
<span class="modal-close" onclick="closeBatchQueueDetailModal()">×</span>
|
||||
|
||||
Reference in New Issue
Block a user