37 lines
1.5 KiB
TypeScript
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();
|
|
}
|