修复画布任务列表完成展示

阻止画布生成完成快照自动展开生成器对话框
已完成任务按完成时间排序
恢复任务列表状态、时间和进度展示

(cherry picked from commit febe4811768b1bce73dbc37ca412b3834da2d699)
This commit is contained in:
2026-06-30 14:05:25 +08:00
parent c556d42d22
commit dbb651e1f4
5 changed files with 81 additions and 39 deletions
@@ -90,6 +90,15 @@ describe('ImageCanvasTaskSidebarView', () => {
}),
]
: [
createExternalTask({
jobId: 'older-done-task',
requestLabel: '较早完成',
requestPrompt: '较早完成任务',
status: 'completed',
startedAt: new Date(Date.now() - 9000).toISOString(),
completedAt: new Date(Date.now() - 8000).toISOString(),
updatedAt: new Date(Date.now() - 500).toISOString(),
}),
createExternalTask({
jobId: 'done-task',
requestLabel: '视频生成',
@@ -151,8 +160,14 @@ describe('ImageCanvasTaskSidebarView', () => {
const completedTab = screen.getByRole('tab', { name: //u });
fireEvent.click(completedTab);
expect(await screen.findByText('视频生成')).toBeTruthy();
const completedTitles = screen
.getAllByRole('button')
.map((button) => button.textContent ?? '')
.filter((text) => text.includes('视频生成') || text.includes('较早完成'));
expect(completedTitles[0]).toContain('视频生成');
expect(completedTitles[1]).toContain('较早完成');
expect(screen.getByText(//u)).toBeTruthy();
expect(screen.queryByText(//u)).not.toBeNull();
expect(screen.queryAllByText(//u).length).toBeGreaterThan(0);
expect(screen.queryByText(//u)).toBeNull();
fireEvent.wheel(screen.getByLabelText('画布任务列表'), { deltaY: 120 });
@@ -220,9 +235,11 @@ describe('ImageCanvasTaskSidebarView', () => {
/>,
);
expect(await screen.findByText('生成图片')).toBeTruthy();
expect(screen.getByText(/ 35% · 2\/4 /u)).toBeTruthy();
expect(await screen.findByText('图片画布生成图片')).toBeTruthy();
expect(screen.getByText(//u)).toBeTruthy();
expect(screen.getByText(/35% · 2\/4 /u)).toBeTruthy();
expect(screen.getByText(/ 1/u)).toBeTruthy();
expect(screen.queryByText(//u)).toBeNull();
expect(screen.queryByText(//u)).toBeNull();
await waitFor(() =>
expect(
@@ -101,8 +101,13 @@ function externalTaskDetail(
);
}
const phaseLabel = task.phaseLabel.trim();
const phaseDetail = task.phaseDetail.trim();
return phaseLabel || phaseDetail || task.requestLabel.trim() || task.jobKind;
const requestLabel = task.requestLabel.trim();
const prompt = normalizeTaskPrompt(task.requestPrompt);
return (
(prompt && prompt !== requestLabel ? prompt : null) ||
(phaseLabel && phaseLabel !== requestLabel ? phaseLabel : null) ||
''
);
}
function externalTaskProgressDetail(
@@ -114,7 +119,7 @@ function externalTaskProgressDetail(
}
const values = [
Number.isFinite(task.progress) && task.progress > 0
? `总进度 ${Math.min(100, Math.max(0, Math.round(task.progress)))}%`
? `${Math.min(100, Math.max(0, Math.round(task.progress)))}%`
: null,
task.phaseDetail.trim(),
].filter((value): value is string => Boolean(value));
@@ -445,23 +450,7 @@ export function ImageCanvasTaskSidebarView({
}, [externalTasks]);
const items = useMemo<TaskSidebarItem[]>(() => {
const externalVisibleTasks = mergeExternalTasks(
externalTasks.filter(
(task) => task.status === 'queued' || task.status === 'running',
),
externalTasks
.filter(isTerminalExternalTask)
.sort(
(left, right) =>
(parseTaskTimeMs(right.completedAt) ??
parseTaskTimeMs(right.updatedAt) ??
0) -
(parseTaskTimeMs(left.completedAt) ??
parseTaskTimeMs(left.updatedAt) ??
0),
)
.slice(0, completedListLimit),
);
const externalVisibleTasks = externalTasks;
const externalItems = externalVisibleTasks.map<TaskSidebarItem>((task) => {
const status = canvasTaskStatusFromExternalTask(task.status);
const startedAt =
@@ -493,7 +482,7 @@ export function ImageCanvasTaskSidebarView({
};
});
return externalItems;
}, [completedListLimit, externalTasks, now, onFocusExternalTask]);
}, [externalTasks, now, onFocusExternalTask]);
const activeItems = useMemo(
() =>
@@ -635,6 +624,7 @@ export function ImageCanvasTaskSidebarView({
const titleText = [detailText, item.progressDetail, timeText]
.filter((value): value is string => Boolean(value))
.join(' · ');
const metaTimeText = timeText;
return (
<button
key={item.id}
@@ -651,8 +641,15 @@ export function ImageCanvasTaskSidebarView({
<span className="image-canvas-editor__task-sidebar-item-title">
{item.title}
</span>
<span className="image-canvas-editor__task-sidebar-item-status">
{statusLabel(item.status)}
<span className="image-canvas-editor__task-sidebar-item-meta">
<span className="image-canvas-editor__task-sidebar-item-status">
{statusLabel(item.status)}
</span>
{metaTimeText ? (
<span className="image-canvas-editor__task-sidebar-item-time">
{metaTimeText}
</span>
) : null}
</span>
</span>
<span
@@ -669,11 +666,6 @@ export function ImageCanvasTaskSidebarView({
{item.progressDetail}
</span>
) : null}
{timeText ? (
<span className="image-canvas-editor__task-sidebar-item-time">
{timeText}
</span>
) : null}
</span>
</button>
);
+9 -1
View File
@@ -6445,7 +6445,7 @@ html[data-mobile-keyboard-open='true'] .platform-mobile-bottom-dock {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
min-width: 0;
align-items: center;
align-items: start;
gap: 0.45rem;
}
@@ -6485,6 +6485,14 @@ html[data-mobile-keyboard-open='true'] .platform-mobile-bottom-dock {
white-space: nowrap;
}
.image-canvas-editor__task-sidebar-item-meta {
display: inline-flex;
min-width: max-content;
align-items: center;
justify-content: flex-end;
gap: 0.36rem;
}
.image-canvas-editor__task-sidebar-item-status {
color: #64748b;
font-size: 0.68rem;