diff --git a/public/locale/en.json b/public/locale/en.json
index 88fbb919d3a..f085ef58ff6 100644
--- a/public/locale/en.json
+++ b/public/locale/en.json
@@ -693,6 +693,7 @@
"and_more_medications": "+{{count}} more medication(s)",
"and_more_service_requests": "+{{count}} more service request(s)",
"and_the_status_of_request_is": "and the status of request is",
+ "another_diagnostic_report": "Another Diagnostic Report",
"answer": "Answer",
"answer_options": "Answer options",
"answer_options_description": "Define possible answers for this question",
@@ -2537,6 +2538,7 @@
"failed_to_add_service_request": "Failed to add service request",
"failed_to_add_to_template": "Failed to add medication to template",
"failed_to_apply_template": "Failed to apply template",
+ "failed_to_approve_diagnostic_report": "Failed to approve diagnostic report: {{error}}",
"failed_to_archive_child_tag": "Failed to archive child tag",
"failed_to_cancel_invoice": "Failed to cancel invoice",
"failed_to_cancel_payment": "Failed to cancel payment",
@@ -2544,6 +2546,7 @@
"failed_to_check_appointments": "Failed to check appointments",
"failed_to_create_appointment": "Failed to create an appointment",
"failed_to_create_category": "Failed to create category",
+ "failed_to_create_diagnostic_report": "Failed to create diagnostic report: {{error}}",
"failed_to_create_invoice": "Failed to create invoice",
"failed_to_create_questionnaire": "Failed to create Questionnaire",
"failed_to_create_queue": "Failed to create queue",
@@ -2566,6 +2569,7 @@
"failed_to_remove_tags": "Failed to remove the tag",
"failed_to_restart_encounter": "Failed to restart encounter",
"failed_to_revoke_token": "Failed to revoke token",
+ "failed_to_save_test_results": "Failed to save test results: {{error}}",
"failed_to_send_message": "Failed to send message",
"failed_to_stop_camera": "Failed to stop camera",
"failed_to_unlock_invoice": "Failed to unlock invoice",
@@ -5030,7 +5034,7 @@
"result_date": "Result Date",
"result_details": "Result details",
"result_on": "Result on",
- "result_review": "Result Review",
+ "result_review": "Result Review of {{name}}",
"result_value": "Result value",
"resume": "Resume",
"retake": "Retake",
@@ -5062,6 +5066,7 @@
"review_and_finalise_request_description": "Add more items if needed, or approve to mark this delivery as requested.",
"review_before": "Review Before",
"review_missed": "Review Missed",
+ "review_test_results": "Review Test Result",
"revisit_days_non_negative": "Re-visit allowed days cannot be negative",
"revoke": "Revoke",
"revoke_token": "Revoke Token",
@@ -5527,6 +5532,7 @@
"select_register_patient": "Select/Register Patient",
"select_report": "Select Report",
"select_report_type": "Select Report Type",
+ "select_report_type_to_create": "Select a diagnostic report type to create a new report",
"select_requester": "Select requester",
"select_resource": "Select the resource",
"select_resource_category": "Select resource category",
@@ -6062,6 +6068,7 @@
"test_results": "Test Results",
"test_results_actions": "Test Results actions",
"test_results_entry": "Test Results Entry",
+ "test_results_saved_successfully": "Test results saved successfully",
"test_type": "Type of test done",
"tested_on": "Tested on",
"tests": "Tests",
diff --git a/src/hooks/useFileUpload.tsx b/src/hooks/useFileUpload.tsx
index 89074727668..ad18399b71e 100644
--- a/src/hooks/useFileUpload.tsx
+++ b/src/hooks/useFileUpload.tsx
@@ -29,6 +29,7 @@ import fileApi from "@/types/files/fileApi";
export type FileUploadOptions = {
multiple?: boolean;
type: FileType;
+ inputId?: string;
category?: FileCategory;
onUpload?: (file: FileReadMinimal) => void;
// if allowed, will fallback to the name of the file if a seperate filename is not defined.
@@ -80,6 +81,7 @@ export default function useFileUpload(
category = FileCategory.UNSPECIFIED,
multiple,
allowNameFallback = true,
+ inputId,
} = options;
const { t } = useTranslation();
@@ -355,7 +357,7 @@ export default function useFileUpload(
const Input = (props: FileInputProps) => (
report.status !== DiagnosticReportStatus.final,
+ );
+
const assignedSpecimenIds = new Set();
const preparePrintAllQRCodes = async () => {
@@ -596,22 +600,18 @@ export default function ServiceRequestShow({
)}
- {(!diagnosticReports.length ||
- diagnosticReports[0]?.status !==
- DiagnosticReportStatus.final) && (
-
- )}
-
+
+
{diagnosticReports.length > 0 && (
;
+
+ facilityId?: string;
}
// New interface to handle multiple observations per definition
@@ -119,56 +122,24 @@ export function DiagnosticReportForm({
activityDefinition,
specimens,
disableEdit,
+ facilityId,
}: DiagnosticReportFormProps) {
const { t } = useTranslation();
- const [observations, setObservations] = useState(
- {},
- );
- const [isExpanded, setIsExpanded] = useState(true);
+ const queryClient = useQueryClient();
+
+ const [showReportTypeSelect, setShowReportTypeSelect] = useState(false);
const [selectedReportCode, setSelectedReportCode] = useState(
null,
);
- const [openUploadDialog, setOpenUploadDialog] = useState(false);
- const [conclusion, setConclusion] = useState("");
- const queryClient = useQueryClient();
-
- // Get the latest report if any exists
- const latestReport =
- diagnosticReports.length > 0 ? diagnosticReports[0] : null;
- const hasReport = !!latestReport;
// Check if all required specimens are collected
const hasCollectedSpecimens =
activityDefinition?.specimen_requirements?.length === 0 ||
specimens.some((specimen) => specimen.status === SpecimenStatus.available);
- // Fetch the full diagnostic report to get observations
- const { data: fullReport, isLoading: isLoadingReport } = useQuery({
- queryKey: ["diagnosticReport", latestReport?.id],
- queryFn: query(diagnosticReportApi.retrieveDiagnosticReport, {
- pathParams: {
- patient_external_id: patientId,
- external_id: latestReport?.id || "",
- },
- }),
- enabled: !!latestReport?.id,
- });
-
- // Query to fetch files for the diagnostic report
- const { data: files = { results: [], count: 0 } } = useQuery<
- PaginatedResponse
- >({
- queryKey: ["files", "diagnostic_report", fullReport?.id],
- queryFn: query(fileApi.list, {
- queryParams: {
- file_type: "diagnostic_report",
- associating_id: fullReport?.id,
- limit: 100,
- offset: 0,
- },
- }),
- enabled: !!fullReport?.id,
- });
+ const isMultipleDiagnosticReport =
+ !!activityDefinition?.diagnostic_report_codes &&
+ activityDefinition.diagnostic_report_codes.length > 0;
// Creating a new diagnostic report
const { mutate: createDiagnosticReport, isPending: isCreatingReport } =
@@ -183,35 +154,183 @@ export function DiagnosticReportForm({
queryClient.invalidateQueries({
queryKey: ["serviceRequest"],
});
- // Fetch the newly created report
queryClient.invalidateQueries({
queryKey: ["diagnosticReport"],
});
},
- onError: (err: any) => {
+ onError: (err: Error) => {
toast.error(
- `Failed to create diagnostic report: ${err.message || "Unknown error"}`,
+ t("failed_to_create_diagnostic_report", {
+ error: err.message || "Unknown error",
+ }),
);
},
});
- // Effect to handle diagnostic reports changes
- useEffect(() => {
- const latestReport = diagnosticReports[0];
- if (latestReport) {
- // If we have a new report, update the UI accordingly
- setSelectedReportCode(latestReport.code || null);
- setIsExpanded(true);
+ function handleCreateReport(code?: Code) {
+ if (!hasCollectedSpecimens) {
+ toast.error(t("specimen_collection_required"));
+ return;
}
- }, [diagnosticReports]);
- // Effect to handle fullReport changes
- useEffect(() => {
- if (fullReport) {
- // When we get the full report details, ensure UI is in correct state
- setSelectedReportCode(fullReport.code || null);
- }
- }, [fullReport]);
+ const category: Code = {
+ code: "LAB",
+ display: "Laboratory",
+ system: "http://terminology.hl7.org/CodeSystem/v2-0074",
+ };
+
+ createDiagnosticReport({
+ status: DiagnosticReportStatus.preliminary,
+ category,
+ service_request: serviceRequestId,
+ code: code || undefined,
+ });
+ }
+
+ return (
+ <>
+ {diagnosticReports.length > 0 && (
+
+
+ {diagnosticReports.map((report) => (
+
+ ))}
+
+ {isMultipleDiagnosticReport && (
+
+ {showReportTypeSelect ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+ )}
+ {diagnosticReports.length === 0 && (
+
+ )}
+ >
+ );
+}
+
+function DiagnosticReportItem({
+ report,
+ patientId,
+ serviceRequestId,
+ observationDefinitions,
+ disableEdit,
+ facilityId,
+ isMultipleDiagnosticReport,
+}: {
+ report: DiagnosticReportRead;
+ patientId: string;
+ serviceRequestId: string;
+ observationDefinitions: ObservationDefinitionReadSpec[];
+ disableEdit: boolean;
+ facilityId?: string;
+ isMultipleDiagnosticReport: boolean;
+}) {
+ const { t } = useTranslation();
+ const queryClient = useQueryClient();
+ const [observations, setObservations] = useState(
+ {},
+ );
+ const [isExpanded, setIsExpanded] = useState(true);
+ const [openUploadDialog, setOpenUploadDialog] = useState(false);
+ const [conclusion, setConclusion] = useState(report.conclusion || "");
+
+ const { data: fullReport } = useQuery({
+ queryKey: ["diagnosticReport", report.id],
+ queryFn: query(diagnosticReportApi.retrieveDiagnosticReport, {
+ pathParams: {
+ patient_external_id: patientId,
+ external_id: report.id,
+ },
+ }),
+ enabled: !!report.id,
+ });
+
+ // Query to fetch files for the diagnostic report
+ const { data: files = { results: [], count: 0 } } = useQuery<
+ PaginatedResponse
+ >({
+ queryKey: ["files", "diagnostic_report", report.id],
+ queryFn: query(fileApi.list, {
+ queryParams: {
+ file_type: "diagnostic_report",
+ associating_id: report.id,
+ limit: 100,
+ offset: 0,
+ },
+ }),
+ enabled: !!report.id,
+ });
// Upserting observations for a diagnostic report
const { mutate: upsertObservations, isPending: isUpsertingObservations } =
@@ -219,21 +338,23 @@ export function DiagnosticReportForm({
mutationFn: mutate(observationApi.upsertObservations, {
pathParams: {
patient_external_id: patientId,
- external_id: latestReport?.id || "",
+ external_id: report.id,
},
}),
onSuccess: () => {
- toast.success("Test results saved successfully");
+ toast.success(t("test_results_saved_successfully"));
queryClient.invalidateQueries({
- queryKey: ["serviceRequest", serviceRequestId],
+ queryKey: ["serviceRequest", facilityId, serviceRequestId],
});
queryClient.invalidateQueries({
- queryKey: ["diagnosticReport", latestReport?.id],
+ queryKey: ["diagnosticReport", report.id],
});
},
- onError: (err: any) => {
+ onError: (err: Error) => {
toast.error(
- `Failed to save test results: ${err.message || "Unknown error"}`,
+ t("failed_to_save_test_results", {
+ error: err.message || "Unknown error",
+ }),
);
},
});
@@ -243,13 +364,13 @@ export function DiagnosticReportForm({
mutationFn: mutate(diagnosticReportApi.updateDiagnosticReport, {
pathParams: {
patient_external_id: patientId,
- external_id: latestReport?.id || "",
+ external_id: report.id,
},
}),
onSuccess: () => {
toast.success(t("conclusion_updated_successfully"));
queryClient.invalidateQueries({
- queryKey: ["diagnosticReport", latestReport?.id],
+ queryKey: ["diagnosticReport", report.id],
});
setIsExpanded(false);
},
@@ -259,14 +380,16 @@ export function DiagnosticReportForm({
});
// Initialize file upload hook
+ const inputId = `file_upload_diagnostic_report_${report.id}`;
const fileUpload = useFileUpload({
- type: "diagnostic_report" as any,
+ type: "diagnostic_report" as FileType,
+ inputId,
multiple: true,
allowedExtensions: BACKEND_ALLOWED_EXTENSIONS,
allowNameFallback: false,
onUpload: () => {
queryClient.invalidateQueries({
- queryKey: ["diagnosticReport", latestReport?.id],
+ queryKey: ["diagnosticReport", report.id],
});
},
compress: false,
@@ -289,9 +412,10 @@ export function DiagnosticReportForm({
if (!openUploadDialog) {
fileUpload.clearFiles();
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [openUploadDialog]);
- // Initialize form with existing observations from the full report
+ // Initialize form with existing observations from the report
useEffect(() => {
if (fullReport?.observations && fullReport.observations.length > 0) {
const initialObservations: ObservationsByDefinition = {};
@@ -333,10 +457,10 @@ export function DiagnosticReportForm({
});
setObservations(initialObservations);
+ }
- if (fullReport.conclusion) {
- setConclusion(fullReport.conclusion);
- }
+ if (fullReport?.conclusion) {
+ setConclusion(fullReport.conclusion);
}
}, [fullReport]);
@@ -467,36 +591,7 @@ export function DiagnosticReportForm({
});
}
- function handleCreateReport() {
- // Only create a new report if no reports exist
- if (!hasReport) {
- if (!hasCollectedSpecimens) {
- toast.error(t("specimen_collection_required"));
- return;
- }
-
- const category: Code = {
- code: "LAB",
- display: "Laboratory",
- system: "http://terminology.hl7.org/CodeSystem/v2-0074",
- };
-
- createDiagnosticReport({
- status: DiagnosticReportStatus.preliminary,
- category,
- service_request: serviceRequestId,
- code: selectedReportCode || undefined,
- });
- }
- }
-
function handleSubmit() {
- if (!hasReport) {
- // First create a report if none exists
- handleCreateReport();
- return;
- }
-
try {
// Check if all observations have values
const hasObservationValue = Object.values(observations).some((obsList) =>
@@ -645,23 +740,21 @@ export function DiagnosticReportForm({
)
.filter((obs): obs is ObservationUpsertRequest => obs !== null);
- if (fullReport) {
- // Upsert observations
- if (formattedObservations.length > 0) {
- upsertObservations({
- observations: formattedObservations,
- });
- }
-
- updateDiagnosticReport({
- id: fullReport.id,
- status: fullReport.status,
- category: fullReport.category,
- code: fullReport.code,
- note: fullReport.note,
- conclusion,
+ // Upsert observations
+ if (formattedObservations.length > 0) {
+ upsertObservations({
+ observations: formattedObservations,
});
}
+
+ updateDiagnosticReport({
+ id: report.id,
+ status: report.status,
+ category: report.category,
+ code: report.code,
+ note: report.note,
+ conclusion,
+ });
} catch (_error) {
toast.error(t("error_validating_form"));
}
@@ -808,23 +901,7 @@ export function DiagnosticReportForm({
);
}
- const isSubmitting =
- isCreatingReport || isUpsertingObservations || isUpdatingReport;
-
- // Show loading state while fetching the report
- if (hasReport && isLoadingReport) {
- return (
-
-
-
-
-
-
-
-
-
- );
- }
+ const isSubmitting = isUpsertingObservations || isUpdatingReport;
return (
{" "}
- {t("test_results_entry")}
+ {isMultipleDiagnosticReport
+ ? report.code?.display
+ : report.service_request?.title}
- {hasReport && fullReport?.created_by && (
-
+
+ {report.created_by && (
-
- {formatName(fullReport.created_by)}
-
-
- )}
-
- {hasReport && fullReport && (
-
- {t(fullReport.status)}
-
)}
+
+ {formatName(report.created_by)}
+
+
+
+
+ {t(report.status)}
+
- {hasReport && fullReport ? (
-
- {fullReport.status !== DiagnosticReportStatus.final && (
-
- )}
- {fullReport.status !== DiagnosticReportStatus.final &&
- observationDefinitions.map((definition) => {
- const observationsList = observations[definition.id] || [
- {
- id: "",
- value: "",
- unit: definition.permitted_unit?.code || "",
- interpretation: "",
- status: ObservationStatus.AMENDED,
- components: {},
- },
- ];
-
- return (
-
-
-
-
-
-
+
+ {report.status !== DiagnosticReportStatus.final && (
+
+ )}
+ {report.status !== DiagnosticReportStatus.final &&
+ observationDefinitions.map((definition) => {
+ const observationsList = observations[definition.id] || [
+ {
+ id: "",
+ value: "",
+ unit: definition.permitted_unit?.code || "",
+ interpretation: "",
+ status: ObservationStatus.AMENDED,
+ components: {},
+ },
+ ];
+
+ return (
+
+
+
+
+
+
- {observationsList.map((observationData, index) => {
- const hasComponents =
- definition.component &&
- definition.component.length > 0;
- const isErrored =
- observationData.status ===
- ObservationStatus.ENTERED_IN_ERROR;
- return (
-
{
+ const hasComponents =
+ definition.component &&
+ definition.component.length > 0;
+ const isErrored =
+ observationData.status ===
+ ObservationStatus.ENTERED_IN_ERROR;
+ return (
+
+
+
+ {isErrored ? (
+
+ {t("marked_for_deletion")}
+
+ ) : (
+ !disableEdit && (
+
+ )
)}
- >
-
-
- {isErrored ? (
-
- {t("marked_for_deletion")}
-
- ) : (
- !disableEdit && (
-
- )
- )}
-
+
- {/* For blood pressure and similar observations with components, we may or may not need to show the main value field */}
- {!hasComponents && (
-
- {definition.permitted_unit && (
-
-
-
-
- )}
-
-
+ {/* For blood pressure and similar observations with components, we may or may not need to show the main value field */}
+ {!hasComponents && (
+
+ )}
+
+ {/* Render component inputs for multi-component observations */}
+ {hasComponents &&
+ renderComponentInputs(
+ definition,
+ observationData,
+ index,
)}
+
+ );
+ })}
+
+ {/* Add button for multiple observations */}
+
+
+
+
+ );
+ })}
+
+
+ {files?.results && files.results.length > 0 && (
+
+
+ {t("uploaded_files")}
+
+
+
+ )}
- {/* Render component inputs for multi-component observations */}
- {hasComponents &&
- renderComponentInputs(
- definition,
- observationData,
- index,
- )}
-
- );
+ {report?.status === DiagnosticReportStatus.preliminary && (
+
+
+
+
+
+
+
+ {t("allowed_formats_are", {
+ formats:
+ BACKEND_ALLOWED_EXTENSIONS.slice(0, 5).join(
+ ", ",
+ ) +
+ ", " +
+ t("etc"),
})}
-
- {/* Add button for multiple observations */}
-
-
-
- );
- })}
+
+
- {fullReport.status !== DiagnosticReportStatus.final && (
+ {fileUpload.files.length > 0 && (
+
+ )}
+
+
+
+ )}
+ {report.status !== DiagnosticReportStatus.final && (
)}
+ {report?.status === DiagnosticReportStatus.preliminary && (
+
+
+
+ )}
+
+
+
+
+
-
- {fullReport?.status ===
- DiagnosticReportStatus.preliminary && (
-
-
-
- )}
+ {fileUpload.Dialogues}
+
+
+ );
+}
- {files?.results && files.results.length > 0 && (
-
-
- {t("uploaded_files")}
-
-
-
- )}
+const CreateDiagnosticReportForm = ({
+ activityDefinition,
+ isCreatingReport,
+ disableEdit,
+ serviceRequestId,
+ handleCreateReport,
+ hasCollectedSpecimens,
+ isMultipleDiagnosticReport,
+}: {
+ activityDefinition?: {
+ diagnostic_report_codes?: Code[];
+ classification?: string;
+ specimen_requirements?: SpecimenDefinitionRead[];
+ };
+ specimens: SpecimenRead[];
+ isCreatingReport: boolean;
+ disableEdit: boolean;
+ serviceRequestId: string;
+ handleCreateReport: (code?: Code) => void;
+ hasCollectedSpecimens: boolean;
+ isMultipleDiagnosticReport: boolean;
+}) => {
+ const [isExpanded, setIsExpanded] = useState(false);
+ const { t } = useTranslation();
- {fullReport?.status ===
- DiagnosticReportStatus.preliminary && (
-
-
-
-
-
-
-
- {t("allowed_formats_are", {
- formats:
- BACKEND_ALLOWED_EXTENSIONS.slice(0, 5).join(
- ", ",
- ) +
- ", " +
- t("etc"),
- })}
-
-
-
+ const [selectedReportCode, setSelectedReportCode] = useState
(
+ null,
+ );
- {fileUpload.files.length > 0 && (
-
- )}
-
-
-
- )}
+ return (
+
+
+
+
+
+
+
+
+ {" "}
+
+ {t("test_results_entry")}
+
+
+
+
+
+
+
- ) : (
-
-
-
- {!hasCollectedSpecimens
- ? t("collect_specimen_before_report")
- : t("no_test_results_recorded")}
+
+
+
+
+
+
+
+
+
+
+
+ {!hasCollectedSpecimens
+ ? t("collect_specimen_before_report")
+ : t("no_test_results_recorded")}
+
+ {isMultipleDiagnosticReport && (
+
+ {t("select_report_type_to_create")}
-
-
- {activityDefinition?.diagnostic_report_codes &&
- activityDefinition.diagnostic_report_codes.length > 0 && (
-
-
-
- )}
+ )}
+ {!isMultipleDiagnosticReport && (
-
+ )}
- )}
+ {isMultipleDiagnosticReport && (
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
-
- {fileUpload.Dialogues}
-
);
-}
+};
diff --git a/src/pages/Facility/services/serviceRequests/components/DiagnosticReportReview.tsx b/src/pages/Facility/services/serviceRequests/components/DiagnosticReportReview.tsx
index 475213daf45..418c922ddeb 100644
--- a/src/pages/Facility/services/serviceRequests/components/DiagnosticReportReview.tsx
+++ b/src/pages/Facility/services/serviceRequests/components/DiagnosticReportReview.tsx
@@ -7,7 +7,7 @@ import {
FileCheck2,
} from "lucide-react";
import { Link } from "raviger";
-import { useEffect, useState } from "react";
+import { useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
@@ -22,7 +22,6 @@ import {
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Label } from "@/components/ui/label";
-import { Skeleton } from "@/components/ui/skeleton";
import { Avatar } from "@/components/Common/Avatar";
import ConfirmActionDialog from "@/components/Common/ConfirmActionDialog";
@@ -32,6 +31,7 @@ import mutate from "@/Utils/request/mutate";
import query from "@/Utils/request/query";
import { PaginatedResponse } from "@/Utils/request/types";
import { formatName } from "@/Utils/utils";
+import { Textarea } from "@/components/ui/textarea";
import { DiagnosticReportResultsTable } from "@/pages/Facility/services/diagnosticReports/components/DiagnosticReportResultsTable";
import {
DIAGNOSTIC_REPORT_STATUS_COLORS,
@@ -58,43 +58,68 @@ export function DiagnosticReportReview({
disableEdit,
}: DiagnosticReportReviewProps) {
const { t } = useTranslation();
+ return (
+
+ {diagnosticReports.some(
+ (report) => report.status !== DiagnosticReportStatus.final,
+ ) && (
+
{t("review_test_results")}
+ )}
+
+ {diagnosticReports.map((report) => (
+
+ ))}
+
+ );
+}
+
+function DiagnosticReportReviewItem({
+ report,
+ facilityId,
+ patientId,
+ disableEdit,
+}: {
+ report: DiagnosticReportRead;
+ facilityId: string;
+ patientId: string;
+ disableEdit: boolean;
+}) {
+ const { t } = useTranslation();
+ const queryClient = useQueryClient();
const [isExpanded, setIsExpanded] = useState(true);
- const [conclusion, setConclusion] = useState
("");
+ const [conclusion, setConclusion] = useState(report.conclusion || "");
const [showApproveDialog, setShowApproveDialog] = useState(false);
- const queryClient = useQueryClient();
- const latestReport = diagnosticReports[0];
- // Fetch the full diagnostic report to get observations
- const { data: fullReport, isLoading: isLoadingReport } = useQuery({
- queryKey: ["diagnosticReport", latestReport?.id],
+ const { data: fullReport } = useQuery({
+ queryKey: ["diagnosticReport", report.id],
queryFn: query(diagnosticReportApi.retrieveDiagnosticReport, {
pathParams: {
patient_external_id: patientId,
- external_id: latestReport?.id || "",
+ external_id: report.id,
},
}),
- enabled: !!latestReport?.id,
+ enabled: !!report.id,
});
- useEffect(() => {
- if (fullReport?.conclusion) {
- setConclusion(fullReport.conclusion);
- }
- }, [fullReport]);
-
const { data: files = { results: [], count: 0 } } = useQuery<
PaginatedResponse
>({
- queryKey: ["files", "diagnostic_report", fullReport?.id],
+ queryKey: ["files", "diagnostic_report", report.id],
queryFn: query(fileApi.list, {
queryParams: {
file_type: "diagnostic_report",
- associating_id: fullReport?.id,
+ associating_id: report.id,
limit: 100,
offset: 0,
},
}),
- enabled: !!fullReport?.id,
+ enabled: !!report.id,
});
const { mutate: updateDiagnosticReport, isPending: isUpdatingReport } =
@@ -102,7 +127,7 @@ export function DiagnosticReportReview({
mutationFn: mutate(diagnosticReportApi.updateDiagnosticReport, {
pathParams: {
patient_external_id: patientId,
- external_id: latestReport?.id || "",
+ external_id: report.id,
},
}),
onSuccess: () => {
@@ -118,56 +143,39 @@ export function DiagnosticReportReview({
queryKey: ["files"],
});
},
- onError: (err: any) => {
+ onError: (err: Error) => {
toast.error(
- `Failed to approve diagnostic report: ${err.message || "Unknown error"}`,
+ t("failed_to_approve_diagnostic_report", { error: err.message }),
);
},
});
+ // Prefer the full detail (with observations); fall back to the list report
+ // while the detail request is still loading.
+ const reportDetail = fullReport ?? report;
+
const handleApprove = () => {
- if (latestReport) {
- updateDiagnosticReport({
- ...latestReport,
- status: DiagnosticReportStatus.final,
- conclusion,
- });
- }
+ updateDiagnosticReport({
+ id: reportDetail.id,
+ status: DiagnosticReportStatus.final,
+ category: reportDetail.category,
+ code: reportDetail.code,
+ note: reportDetail.note,
+ conclusion: conclusion || reportDetail.conclusion,
+ });
};
- if (!latestReport) {
- return null;
- }
-
- // Show loading state while fetching the report
- if (isLoadingReport) {
- return (
-
-
-
-
-
-
-
-
-
- );
- }
-
- // Don't show the report review if there are no observations and no files and no conclusion
- if (
- (!fullReport?.observations || fullReport.observations.length === 0) &&
+ const isReportNotReviewable =
+ (!reportDetail.observations || reportDetail.observations.length === 0) &&
(!files?.results || files.results.length === 0) &&
- !fullReport?.conclusion
- ) {
- return null;
- }
+ !reportDetail.conclusion;
return (
@@ -175,35 +183,41 @@ export function DiagnosticReportReview({
-
-
- {" "}
-
- {t("result_review")}
+
+
+ {" "}
+
+ {report.code?.display ?? report.service_request?.title}
- {fullReport?.created_by && (
+ {isReportNotReviewable && (
+
+ {t("no_observations_entered")}
+
+ )}
+ {report.created_by && (
- {formatName(fullReport.created_by)}
+ {formatName(report.created_by)}
)}
- {fullReport && (
-
- {t(fullReport.status)}
-
- )}
+
+ {t(report.status)}
+