Sync latest TrueGrowth updates
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
TaskType,
|
||||
type Task,
|
||||
} from '../../types/task.types';
|
||||
import { isResumableAsyncImageTask } from '../task-utils';
|
||||
import { getTaskTimelineItems, isResumableAsyncImageTask } from '../task-utils';
|
||||
|
||||
function createImageTask(overrides: Partial<Task> = {}): Task {
|
||||
const now = Date.now();
|
||||
@@ -70,4 +70,50 @@ describe('task-utils', () => {
|
||||
expect(isResumableAsyncImageTask(task)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTaskTimelineItems', () => {
|
||||
it('labels completed tasks with created and completed times', () => {
|
||||
const createdAt = new Date(2024, 2, 10, 0, 0, 0).getTime();
|
||||
const task = createImageTask({
|
||||
status: TaskStatus.COMPLETED,
|
||||
createdAt,
|
||||
updatedAt: createdAt + 2000,
|
||||
completedAt: createdAt + 3000,
|
||||
});
|
||||
|
||||
expect(getTaskTimelineItems(task)).toEqual([
|
||||
{ label: '创建', value: '2024-03-10 00:00:00' },
|
||||
{ label: '完成', value: '2024-03-10 00:00:03' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('falls back to the update time for completed tasks without completedAt', () => {
|
||||
const createdAt = new Date(2024, 2, 10, 0, 0, 0).getTime();
|
||||
const task = createImageTask({
|
||||
status: TaskStatus.COMPLETED,
|
||||
createdAt,
|
||||
updatedAt: createdAt + 2000,
|
||||
completedAt: undefined,
|
||||
});
|
||||
|
||||
expect(getTaskTimelineItems(task)).toEqual([
|
||||
{ label: '创建', value: '2024-03-10 00:00:00' },
|
||||
{ label: '完成', value: '2024-03-10 00:00:02' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('labels failed tasks with the failure update time', () => {
|
||||
const createdAt = new Date(2024, 2, 10, 0, 0, 0).getTime();
|
||||
const task = createImageTask({
|
||||
status: TaskStatus.FAILED,
|
||||
createdAt,
|
||||
updatedAt: createdAt + 4000,
|
||||
});
|
||||
|
||||
expect(getTaskTimelineItems(task)).toEqual([
|
||||
{ label: '创建', value: '2024-03-10 00:00:00' },
|
||||
{ label: '失败', value: '2024-03-10 00:00:04' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -143,3 +143,66 @@ export function getTaskElapsedTime(task: Task): number {
|
||||
* formatDateTime(Date.now()) // Returns "2025-12-18 14:30:25"
|
||||
*/
|
||||
export const formatDateTime = formatDate;
|
||||
|
||||
export interface TaskTimelineItem {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
function isValidTimestamp(timestamp: number | undefined): timestamp is number {
|
||||
return (
|
||||
typeof timestamp === 'number' &&
|
||||
Number.isFinite(timestamp) &&
|
||||
timestamp > 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the labeled absolute times shown in task-center rows.
|
||||
*/
|
||||
export function getTaskTimelineItems(task: Task): TaskTimelineItem[] {
|
||||
const items: TaskTimelineItem[] = [];
|
||||
|
||||
if (isValidTimestamp(task.createdAt)) {
|
||||
items.push({
|
||||
label: '创建',
|
||||
value: formatDateTime(task.createdAt),
|
||||
});
|
||||
}
|
||||
|
||||
const completedAt = isValidTimestamp(task.completedAt)
|
||||
? task.completedAt
|
||||
: task.updatedAt;
|
||||
if (task.status === TaskStatus.COMPLETED && isValidTimestamp(completedAt)) {
|
||||
items.push({
|
||||
label: '完成',
|
||||
value: formatDateTime(completedAt),
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
if (
|
||||
(task.status === TaskStatus.FAILED ||
|
||||
task.status === TaskStatus.CANCELLED) &&
|
||||
isValidTimestamp(task.updatedAt)
|
||||
) {
|
||||
items.push({
|
||||
label: task.status === TaskStatus.FAILED ? '失败' : '取消',
|
||||
value: formatDateTime(task.updatedAt),
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
if (
|
||||
task.status === TaskStatus.PROCESSING &&
|
||||
isValidTimestamp(task.updatedAt) &&
|
||||
task.updatedAt !== task.createdAt
|
||||
) {
|
||||
items.push({
|
||||
label: '更新',
|
||||
value: formatDateTime(task.updatedAt),
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user