feat(export): modal task center with pause/stop controls

This commit is contained in:
tisonhuang
2026-03-02 16:01:48 +08:00
parent 51bc60776d
commit 8d68a59799
7 changed files with 836 additions and 219 deletions

View File

@@ -236,7 +236,7 @@
min-width: 0;
}
.task-collapse-btn {
.task-open-btn {
border: 1px solid var(--border-color);
background: var(--bg-primary);
border-radius: 7px;
@@ -245,14 +245,38 @@
color: var(--text-secondary);
display: inline-flex;
align-items: center;
gap: 3px;
gap: 6px;
cursor: pointer;
flex-shrink: 0;
transition: border-color 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
&:hover {
border-color: var(--primary);
color: var(--primary);
}
&.active-running {
border-color: rgba(255, 77, 79, 0.45);
color: #ff4d4f;
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.16);
}
}
.task-running-badge {
min-width: 16px;
height: 16px;
border-radius: 999px;
background: #ff4d4f;
color: #fff;
font-size: 10px;
font-weight: 700;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0 4px;
line-height: 1;
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
animation: exportTaskBadgePulse 1.2s ease-in-out infinite;
}
.secondary-btn {
@@ -351,122 +375,232 @@
gap: 1px;
}
.task-center {
.task-center-modal-overlay {
position: fixed;
top: 40px;
right: 0;
bottom: 0;
left: 0;
z-index: 1180;
background: rgba(15, 23, 42, 0.28);
display: flex;
align-items: flex-start;
justify-content: center;
padding: 24px 20px;
}
.task-center-modal {
width: min(980px, calc(100vw - 40px));
max-height: calc(100vh - 72px);
border-radius: 14px;
border: 1px solid var(--border-color);
border-radius: 12px;
background: var(--card-bg);
padding: 12px;
flex-shrink: 0;
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.24);
display: flex;
flex-direction: column;
overflow: hidden;
}
.task-empty {
padding: 12px;
background: var(--bg-secondary);
border-radius: 8px;
font-size: 13px;
color: var(--text-secondary);
}
.task-center-modal-header {
padding: 12px 14px;
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.task-list {
display: grid;
gap: 8px;
max-height: 190px;
overflow-y: auto;
}
.task-center-modal-title {
min-width: 0;
.task-card {
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 10px;
display: flex;
gap: 10px;
align-items: flex-start;
background: var(--bg-secondary);
&.running {
border-color: var(--primary);
}
&.error {
border-color: rgba(255, 77, 79, 0.45);
}
&.success {
border-color: rgba(82, 196, 26, 0.4);
}
}
.task-main {
flex: 1;
min-width: 0;
}
.task-title {
font-size: 13px;
h3 {
margin: 0;
font-size: 16px;
color: var(--text-primary);
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.task-meta {
margin-top: 2px;
display: flex;
flex-wrap: wrap;
gap: 8px;
font-size: 11px;
color: var(--text-secondary);
}
.task-status {
border-radius: 999px;
padding: 2px 8px;
font-weight: 600;
&.queued {
background: rgba(var(--primary-rgb), 0.14);
color: var(--primary);
}
&.running {
background: rgba(var(--primary-rgb), 0.2);
color: var(--primary);
}
&.success {
background: rgba(82, 196, 26, 0.18);
color: #52c41a;
}
&.error {
background: rgba(255, 77, 79, 0.15);
color: #ff4d4f;
}
}
.task-progress-bar {
margin-top: 8px;
height: 6px;
background: rgba(0, 0, 0, 0.08);
border-radius: 3px;
overflow: hidden;
}
.task-progress-fill {
height: 100%;
background: var(--primary);
transition: width 0.2s ease;
}
.task-progress-text {
margin-top: 4px;
font-size: 11px;
color: var(--text-secondary);
}
.task-error {
margin-top: 6px;
span {
display: block;
margin-top: 3px;
font-size: 12px;
color: var(--text-secondary);
}
}
.task-center-modal-body {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 12px;
}
.task-empty {
padding: 12px;
background: var(--bg-secondary);
border-radius: 8px;
font-size: 13px;
color: var(--text-secondary);
}
.task-list {
display: grid;
gap: 8px;
}
.task-card {
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 10px;
display: flex;
gap: 10px;
align-items: flex-start;
background: var(--bg-secondary);
&.running {
border-color: var(--primary);
}
&.paused {
border-color: rgba(250, 173, 20, 0.55);
}
&.stopped {
border-color: rgba(148, 163, 184, 0.46);
}
&.error {
border-color: rgba(255, 77, 79, 0.45);
}
&.success {
border-color: rgba(82, 196, 26, 0.4);
}
}
.task-main {
flex: 1;
min-width: 0;
}
.task-title {
font-size: 13px;
color: var(--text-primary);
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.task-meta {
margin-top: 2px;
display: flex;
flex-wrap: wrap;
gap: 8px;
font-size: 11px;
color: var(--text-secondary);
}
.task-status {
border-radius: 999px;
padding: 2px 8px;
font-weight: 600;
&.queued {
background: rgba(var(--primary-rgb), 0.14);
color: var(--primary);
}
&.running {
background: rgba(var(--primary-rgb), 0.2);
color: var(--primary);
}
&.paused {
background: rgba(250, 173, 20, 0.2);
color: #d48806;
}
&.stopped {
background: rgba(148, 163, 184, 0.2);
color: #64748b;
}
&.success {
background: rgba(82, 196, 26, 0.18);
color: #52c41a;
}
&.error {
background: rgba(255, 77, 79, 0.15);
color: #ff4d4f;
}
}
.task-progress-bar {
margin-top: 8px;
height: 6px;
background: rgba(0, 0, 0, 0.08);
border-radius: 3px;
overflow: hidden;
}
.task-progress-fill {
height: 100%;
background: var(--primary);
transition: width 0.2s ease;
}
.task-progress-text {
margin-top: 4px;
font-size: 11px;
color: var(--text-secondary);
}
.task-error {
margin-top: 6px;
font-size: 12px;
color: #ff4d4f;
}
.task-actions {
display: flex;
flex-direction: column;
gap: 6px;
flex-shrink: 0;
}
.task-action-btn {
border: 1px solid var(--border-color);
border-radius: 8px;
background: var(--bg-primary);
color: var(--text-secondary);
min-height: 30px;
padding: 0 10px;
font-size: 12px;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
white-space: nowrap;
&:hover:not(:disabled) {
border-color: var(--primary);
color: var(--primary);
}
&:disabled {
opacity: 0.65;
cursor: not-allowed;
}
&.primary {
border-color: rgba(var(--primary-rgb), 0.35);
color: var(--primary);
}
&.danger {
border-color: rgba(255, 77, 79, 0.36);
color: #ff4d4f;
}
}
@@ -1034,6 +1168,12 @@
background: color-mix(in srgb, var(--primary) 80%, #000);
}
&.paused {
background: rgba(250, 173, 20, 0.16);
color: #d48806;
border: 1px solid rgba(250, 173, 20, 0.38);
}
&.no-session {
background: var(--bg-secondary);
color: var(--text-tertiary);
@@ -1677,6 +1817,21 @@
}
}
@keyframes exportTaskBadgePulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0.35);
}
70% {
transform: scale(1.02);
box-shadow: 0 0 0 6px rgba(255, 77, 79, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0);
}
}
@media (max-width: 1360px) {
.global-export-controls {
padding: 10px;
@@ -1725,6 +1880,19 @@
grid-template-columns: 1fr;
}
.task-center-modal-overlay {
padding: 12px 10px;
}
.task-center-modal {
width: calc(100vw - 20px);
max-height: calc(100vh - 56px);
}
.task-actions {
width: 84px;
}
.export-session-detail-panel {
width: calc(100vw - 12px);
}