Assessor_2.0/src/compliance/ui/use-backend-work-activity.ts

37 lines
1.5 KiB
TypeScript

import { useEffect, useRef } from 'react';
import { beginActivity } from '../../platform/activity-store';
/** What a view currently observes of a backend job; `idle` means it no longer observes one. */
export type BackendWorkState = 'idle' | 'queued' | 'running' | 'finished' | 'failed';
/**
* Keeps one Compliance Engine activity open while backend work runs, so the activity log is not
* `Ready` between status polls. A view that stops observing the job ends the entry with a note,
* because the backend work itself is not cancelled.
*/
export function useBackendWorkActivity(label: string, state: BackendWorkState): void {
const activity = useRef<ReturnType<typeof beginActivity> | undefined>(undefined);
useEffect(() => {
if (state === 'queued' || state === 'running') {
activity.current ??= beginActivity('Compliance Engine', label);
if (state === 'queued') activity.current.queue(); else activity.current.run();
return;
}
const current = activity.current;
if (!current) return;
activity.current = undefined;
if (state === 'failed') current.fail();
else if (state === 'finished') current.complete();
else detach(current, label);
}, [label, state]);
useEffect(() => () => {
if (activity.current) detach(activity.current, label);
activity.current = undefined;
}, [label]);
}
function detach(activity: ReturnType<typeof beginActivity>, label: string) {
activity.update(`${label} continues in the backend`);
activity.complete();
}