mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-05 05:46:24 -04:00
* refactor job manager ui * huge improvements to job ui api * improve indexer errors * minor improvements * make icon bigger + improve styling * Update useJobInfo.tsx better * improve job status reporting * fix job indexer backend for ui responsiveness * attempt at debugging job.getRunning slow invalidation during indexer's walk phase * remove progress debounce, invalidate has its own throttle layer * hotfix ghost jobs * basic pause/resume * pause functionality immaculate * pause resume working for first job in group, testable on indexer phase two * WIP - refactored job manager - added better job api * fix merge issues * add throttle to job update events and correct index * improve front end job data handling * move subscription to job * wip active job indicator * minor tweak * Isolated subscriptions for job events + cleanup Co-authored-by: Brendan Allan <Brendonovich@users.noreply.github.com> Co-authored-by: Oscar Beaumont <oscar@otbeaumont.me> * mutable ctx * plz let me build rspc typesafe errors Jamie * fix merge * working job reporting * fix thumbnail text * faster tick speed * fix error --------- Co-authored-by: Brendan Allan <Brendonovich@users.noreply.github.com> Co-authored-by: Oscar Beaumont <oscar@otbeaumont.me>
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import dayjs from 'dayjs';
|
|
import duration from 'dayjs/plugin/duration';
|
|
import { useEffect, useMemo } from 'react';
|
|
import { JobReport } from '@sd/client';
|
|
import { useForceUpdate } from '~/util';
|
|
|
|
dayjs.extend(duration);
|
|
|
|
// TODO: refactor this, its a mess.
|
|
export function useTotalElapsedTimeText(jobs: JobReport[] = []) {
|
|
const forceUpdate = useForceUpdate();
|
|
|
|
const elapsedTimeText = useMemo(() => {
|
|
let total = 0;
|
|
let text: string | null = '';
|
|
|
|
const groupedJobs = jobs.reduce((acc: Record<string, JobReport[]>, job) => {
|
|
const parentId = String(job.parent_id);
|
|
if (!acc[parentId]) {
|
|
acc[parentId] = [];
|
|
}
|
|
acc[parentId]?.push(job);
|
|
return acc;
|
|
}, {});
|
|
|
|
Object.values(groupedJobs).forEach((group: JobReport[]) => {
|
|
let groupTotal = 0;
|
|
group.forEach((job) => {
|
|
const start = dayjs(job.started_at);
|
|
const end = job.completed_at ? dayjs(job.completed_at) : dayjs();
|
|
|
|
groupTotal += end.diff(start, 'minutes');
|
|
});
|
|
|
|
total += groupTotal;
|
|
|
|
const lastJob = group[group.length - 1];
|
|
if (lastJob?.status === 'Failed' || lastJob?.status === 'Canceled') {
|
|
text = 'Job failed or canceled';
|
|
} else {
|
|
text = lastJob?.completed_at
|
|
? `Took ${dayjs.duration(groupTotal, 'minutes').humanize()}`
|
|
: null;
|
|
}
|
|
});
|
|
|
|
return text;
|
|
}, [jobs]);
|
|
|
|
useEffect(() => {
|
|
const allJobsCompleted = jobs.every((job) => job.completed_at);
|
|
const isJobsQueued = jobs.some((job) => job.status === 'Queued');
|
|
|
|
if (!allJobsCompleted || isJobsQueued) {
|
|
const interval = setInterval(forceUpdate, 1000);
|
|
return () => clearInterval(interval);
|
|
}
|
|
}, [jobs, forceUpdate]);
|
|
|
|
return elapsedTimeText === 'Took NaN years' ? null : elapsedTimeText;
|
|
}
|