import { useCallback, useEffect, useState } from "react"; import { useHttpService } from "../services/HttpService.tsx"; import { environment } from "../environments/environment.ts"; import { relayServerFailure } from "../utils/fetchFailureMessage"; /** * The studies that could answer one imaging order. * * IT ASKS ABOUT AN ORDER, NEVER ABOUT A PATIENT, and that is the whole reason the route exists. * `GET /R4/ImagingStudy` admits practitioners, patients and related persons and is gated on patient * access -- an imaging tech is none of those. The lab queue also withholds the patient id on purpose, * carrying a display name because whoever works the row has to know who it is for. So this client * cannot search a patient's studies, and must not be able to: the server resolves the patient from * the order and never returns it. * * THE LIST GRANTS NOTHING. Choosing from it does not attach anything; the result route reads the * study again and refuses one whose subject is not the order's patient. This is an affordance, not a * permission. * * On the base API, where 02-fhir-base.yaml declares the diagnostic-order routes. */ export interface DiagnosticOrderStudy { id?: string; description?: string; started?: string; modalities?: string[]; numberOfSeries?: number; numberOfInstances?: number; /** Filed against the order being reported, rather than another of the patient's studies. */ forThisOrder?: boolean; } interface StudiesResponse { studies?: DiagnosticOrderStudy[]; } export const useDiagnosticOrderStudies = (orderId?: string, enabled = true) => { const { get } = useHttpService(); const [studies, setStudies] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(); const load = useCallback(async () => { if (!orderId || !enabled) return; setLoading(true); setError(undefined); try { const response = await get( `${environment.fhirBaseApi}/diagnostic-order/${orderId}/imaging-studies`, ); setStudies(response?.studies ?? []); } catch (failure: unknown) { // STATED, NOT SHOWN AS AN EMPTY LIST. "No studies have been imported" and "we could not ask" // look identical on screen and mean opposite things to somebody deciding whether to file a // result without one. setError(relayServerFailure(failure, "We could not load this order's studies just now.")); setStudies(null); } finally { setLoading(false); } }, [get, orderId, enabled]); useEffect(() => { void load(); }, [load]); return { studies, loading, error, reload: load }; };