diff --git a/frontend/src/components/ui/RecorderSettings.tsx b/frontend/src/components/ui/RecorderSettings.tsx index 3f203cd..f2f8cfe 100644 --- a/frontend/src/components/ui/RecorderSettings.tsx +++ b/frontend/src/components/ui/RecorderSettings.tsx @@ -166,10 +166,11 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { const [assetsTask, setAssetsTask] = useState({ id: 'generate-assets', status: 'idle', - title: 'Assets generieren', // oder '' wenn du es komplett weg willst + title: 'Assets generieren', text: '', cancellable: true, fading: false, + startedAtMs: 0, }) const [cleanupTask, setCleanupTask] = useState({ @@ -179,6 +180,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { text: '', cancellable: true, fading: false, + startedAtMs: 0, }) const [regenerateAssetsTasks, setRegenerateAssetsTasks] = useState([]) @@ -321,6 +323,11 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { const state = String(job?.state || '').trim().toLowerCase() const error = String(job?.error || '').trim() + const startedAtMs = + Number(job?.startedAt ?? 0) || + Number(job?.enqueuedAt ?? 0) || + Date.now() + const cancelled = state === 'cancelled' || error.toLowerCase() === 'abgebrochen' || @@ -377,12 +384,11 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { err: status === 'error' ? error || 'Fehler beim Regenerieren.' : undefined, cancellable: status === 'running', fading: false, + startedAtMs, } }) .filter(Boolean) as TaskItem[] - nextTasks.sort((a, b) => a.title.localeCompare(b.title, undefined, { sensitivity: 'base' })) - setRegenerateAssetsTasks((prev) => { const nextById = new Map(nextTasks.map((t) => [t.id, t])) const prevById = new Map(prev.map((t) => [t.id, t])) @@ -419,9 +425,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { } } - return merged.sort((a, b) => - a.title.localeCompare(b.title, undefined, { sensitivity: 'base' }) - ) + return merged }) const cleanup = data.cleanup @@ -654,7 +658,16 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { window.setTimeout(() => { setter((t) => ({ ...t, fading: true })) window.setTimeout(() => { - setter((t) => ({ ...t, status: 'idle', text: '', err: undefined, done: 0, total: 0, fading: false })) + setter((t) => ({ + ...t, + status: 'idle', + text: '', + err: undefined, + done: 0, + total: 0, + fading: false, + startedAtMs: 0, + })) }, fadeMs) }, delayMs) } @@ -702,12 +715,13 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { setCleanupTask((t) => ({ ...t, status: 'running', - title: 'Aufräumen', // ✅ HINZUFÜGEN (reset) + title: 'Aufräumen', text: 'Räume auf…', err: undefined, done: 0, total: 0, fading: false, + startedAtMs: t.startedAtMs || Date.now(), })) try { @@ -917,6 +931,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { total: 0, err: undefined, fading: false, + startedAtMs: t.startedAtMs || Date.now(), })) }} onProgress={(p) => { diff --git a/frontend/src/components/ui/TaskList.tsx b/frontend/src/components/ui/TaskList.tsx index bfb6608..dbaf7b1 100644 --- a/frontend/src/components/ui/TaskList.tsx +++ b/frontend/src/components/ui/TaskList.tsx @@ -10,8 +10,9 @@ export type TaskItem = { done?: number total?: number err?: string - cancellable?: boolean // zeigt X nur wenn true - fading?: boolean // für sanftes Ausblenden + cancellable?: boolean + fading?: boolean + startedAtMs?: number } type Props = { @@ -27,7 +28,13 @@ function pct(done?: number, total?: number) { } export default function TaskList({ tasks, onCancel }: Props) { - const visible = (tasks || []).filter((t) => t.status !== 'idle') + const visible = [...(tasks || [])] + .filter((t) => t.status !== 'idle') + .sort((a, b) => { + const aMs = Number(a.startedAtMs ?? 0) + const bMs = Number(b.startedAtMs ?? 0) + return aMs - bMs + }) return (