diff --git a/src/data-visualizer/data-visualizer.component.tsx b/src/data-visualizer/data-visualizer.component.tsx index 42631c2..8a8d4a0 100644 --- a/src/data-visualizer/data-visualizer.component.tsx +++ b/src/data-visualizer/data-visualizer.component.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import PivotTableUI from "react-pivottable/PivotTableUI"; import TableRenderers from "react-pivottable/TableRenderers"; import Plot from "react-plotly.js"; @@ -66,20 +66,19 @@ import { getCohortCategory, getDateRange, getReport, - getReportFromRegistry, mapDataElements, mapOrderDataElements, saveReport, sendReportToDHIS2, useGetEncounterType, useGetOrderTypes, - useGetReportingRegistry, + useGetReportCategories, + useGetReportLibrary, } from "./data-visualizer.resource"; import dayjs from "dayjs"; import { showModal, showNotification, showToast } from "@openmrs/esm-framework"; import ModifierComponent from "../components/popover/modifier-panel"; -import { Simulate } from "react-dom/test-utils"; -import error = Simulate.error; + type ChartType = "list" | "pivot" | "aggregate"; type ReportingDuration = "fixed" | "relative"; export type CQIReportingCohort = @@ -90,80 +89,129 @@ type DynamicReportType = | "cohort" | "patientSearch" | "reportDefinition"; + +type ReportLibraryItem = { + uuid: string; + name: string; + description?: string; + code?: string; + sourceType?: string; + reportDefinitionUuid?: string; + reportBuilderReportUuid?: string; + reportType?: string; + migrated?: boolean; + retired?: boolean; + category?: { + uuid?: string; + name?: string; + display?: string; + description?: string; + }; +}; + const DataVisualizer: React.FC = () => { const PlotlyRenderers = createPlotlyRenderers(Plot); + const [tableHeaders, setTableHeaders] = useState([]); const [data, setData] = useState([]); - const [pivotTableData, setPivotTableData] = useState(data); + const [pivotTableData, setPivotTableData] = useState([]); const [chartType, setChartType] = useState("list"); const [reportType, setReportType] = useState("fixed"); const [reportCategory, setReportCategory] = useState<{ - category: ReportCategory; + category?: ReportCategory; renderType?: RenderType; - }>({ category: "facility", renderType: "list" }); + categoryUuid?: string; + categoryName?: string; + }>({ + category: undefined, + renderType: undefined, + categoryUuid: undefined, + categoryName: undefined, + }); const [reportingDuration, setReportingDuration] = useState("fixed"); - const { reportingRegistry } = useGetReportingRegistry(); - const reportTypes = reportingRegistry?.reportTypes ?? []; - const reportPeriod = reportingRegistry?.reportPeriods ?? []; - const facilityReports = - getReportFromRegistry(reportingRegistry, "facility") ?? []; - const donorReports = getReportFromRegistry(reportingRegistry, "donor") ?? []; - const nationalReports = - getReportFromRegistry(reportingRegistry, "national") ?? []; - const cqiReports = getReportFromRegistry(reportingRegistry, "cqi") ?? []; - const integrationDataExports = - getReportFromRegistry(reportingRegistry, "integration") ?? []; - const [reportingPeriod, setReportingPeriod] = useState(reportPeriod[0]); - const [selectedIndicators, setSelectedIndicators] = useState(null); - const [selectedReport, setSelectedReport] = useState( - facilityReports?.reports?.[0] + + const { reportLibrary } = useGetReportLibrary(); + const { reportCategories } = useGetReportCategories(); + + const reportTypes = useMemo( + () => + (reportCategories ?? []).map((category) => ({ + id: category?.uuid, + key: category?.uuid, + label: category?.name, + name: category?.name, + uuid: category?.uuid, + })), + [reportCategories] ); - const [cqiReportingCohort, setCQIReportingCohort] = - useState("Patients with encounters"); - useEffect(() => { - let initialSelectedReport; - - if (reportType === "fixed") { - switch (reportCategory.category) { - case "facility": - initialSelectedReport = facilityReports?.reports?.[0]; - break; - case "donor": - initialSelectedReport = donorReports.reports?.[0]; - break; - case "national": - initialSelectedReport = nationalReports.reports?.[0]; - break; - case "cqi": - initialSelectedReport = cqiReports.reports?.[0]; - break; - case "integration": - initialSelectedReport = integrationDataExports.reports?.[0]; - break; - default: - initialSelectedReport = facilityReports?.reports?.[0]; - } - } else { - initialSelectedReport = facilityReports?.reports?.[0]; - setChartType("list"); - } + const reportPeriod = [ + { id: "today", label: "Today" }, + { id: "week", label: "This Week" }, + { id: "month", label: "This Month" }, + { id: "quarter", label: "This Quarter" }, + { id: "lastQuarter", label: "Last Quarter" }, + ]; + + const toReportOption = (report: ReportLibraryItem) => ({ + id: + report?.reportDefinitionUuid || + report?.reportBuilderReportUuid || + report?.uuid, + uuid: report?.uuid, + label: report?.name, + name: report?.name, + sourceType: report?.sourceType, + reportType: report?.reportType, + code: report?.code, + category: report?.category?.name, + }); + + const getReportsByCategoryName = useCallback( + (categoryName: string) => { + return (reportLibrary ?? []) + .filter( + (report: ReportLibraryItem) => + report?.category?.name?.toLowerCase() === categoryName?.toLowerCase() + ) + .map(toReportOption); + }, + [reportLibrary] + ); - setSelectedReport(initialSelectedReport); - }, [ - reportCategory, - reportType, - facilityReports.reports, - donorReports.reports, - nationalReports.reports, - cqiReports.reports, - integrationDataExports.reports, - ]); + const facilityReports = useMemo( + () => getReportsByCategoryName("FACILITY REPORTS"), + [getReportsByCategoryName] + ); + + const donorReports = useMemo( + () => getReportsByCategoryName("MER INDICATOR REPORTS"), + [getReportsByCategoryName] + ); + + const nationalReports = useMemo( + () => getReportsByCategoryName("NATIONAL REPORTS"), + [getReportsByCategoryName] + ); + + const cqiReports = useMemo( + () => getReportsByCategoryName("CQI REPORTS"), + [getReportsByCategoryName] + ); + + const integrationDataExports = useMemo( + () => getReportsByCategoryName("Integration Data Exports"), + [getReportsByCategoryName] + ); + + const [reportingPeriod, setReportingPeriod] = useState(null); + const [selectedIndicators, setSelectedIndicators] = + useState(null); + const [selectedReport, setSelectedReport] = useState(null); + const [cqiReportingCohort, setCQIReportingCohort] = + useState("Patients with encounters"); - const handleSelectedReport = ({ selectedItem }) => { - setSelectedReport(selectedItem); - }; const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(new Date()); const [loading, setLoading] = useState(true); @@ -183,12 +231,25 @@ const DataVisualizer: React.FC = () => { const [isDownloading, setIsDownloading] = useState(false); const [isSendingReport, setIsSendingReport] = useState(false); const [dhisJson, setDhisJson] = useState({}); - const [selectedDynamicReportType, setSelectedDynamicReportType] = useState( - dynamicReportOptions[3] - ); - const [dynamicReportTypes, setDynamicReportTypes] = useState( - facilityReports?.reports - ); + + const [selectedDynamicReportType, setSelectedDynamicReportType] = + useState(null); + const [dynamicReportTypes, setDynamicReportTypes] = useState([]); + + const hasFixedCategory = !!reportCategory.categoryUuid; + const hasDynamicCategory = !!selectedDynamicReportType; + + useEffect(() => { + setSelectedReport(null); + setData([]); + setPivotTableData([]); + setHTML(""); + setShowLineList(false); + }, [reportCategory, reportType]); + + const handleSelectedReport = ({ selectedItem }) => { + setSelectedReport(selectedItem ?? null); + }; const handleChartTypeChange = ({ name }) => { setChartType(name); @@ -196,6 +257,23 @@ const DataVisualizer: React.FC = () => { const handleReportTypeChange = ({ name }) => { setReportType(name); + setSelectedReport(null); + setSelectedIndicators(null); + setAvailableParameters([]); + setSelectedParameters([]); + setData([]); + setPivotTableData([]); + setHTML(""); + setShowLineList(false); + setReportCategory({ + category: undefined, + renderType: undefined, + categoryUuid: undefined, + categoryName: undefined, + }); + setSelectedDynamicReportType(null); + setDynamicReportTypes([]); + setChartType("list"); }; const handleReportingDurationChange = (period) => { @@ -215,6 +293,8 @@ const DataVisualizer: React.FC = () => { }; const confirmSendReport = () => { + if (!selectedReport) return; + const dispose = showModal("confirm-modal", { close: () => dispose(), submit: () => { @@ -226,6 +306,8 @@ const DataVisualizer: React.FC = () => { }; const handleSendToDHIS2 = useCallback(() => { + if (!selectedReport) return; + setIsSendingReport(true); sendReportToDHIS2(selectedReport.id, dhisJson).then( @@ -237,8 +319,7 @@ const DataVisualizer: React.FC = () => { kind: "success", description: `Report ${selectedReport.label} sent Successfully`, }); - } - { + } else { showNotification({ title: "Error sending report to DHIS2", kind: "error", @@ -246,6 +327,7 @@ const DataVisualizer: React.FC = () => { description: `Failed with error code ${response.status}, Contact System Administrator`, }); } + setIsSendingReport(false); }, (error) => { @@ -261,6 +343,8 @@ const DataVisualizer: React.FC = () => { }, [selectedReport, dhisJson]); const handleDownloadReport = useCallback(() => { + if (!selectedReport) return; + setIsDownloading(true); downloadReport({ @@ -276,12 +360,13 @@ const DataVisualizer: React.FC = () => { const url = window.URL.createObjectURL(blob); const filename = response?.headers ?.get("Content-Disposition") - ?.match(/filename=(.+)/)[1]; + ?.match(/filename=(.+)/)?.[1]; + const a = document.createElement("a"); a.href = url; - a.download = filename; + a.download = filename ?? `${selectedReport.label}.csv`; a.click(); - window.URL.revokeObjectURL(response?.url); + window.URL.revokeObjectURL(url); } catch (error) { showNotification({ title: "Error downloading Report", @@ -348,7 +433,6 @@ const DataVisualizer: React.FC = () => { (parameter) => parameter !== selectedParameter ); setAvailableParameters(updatedAvailableParameters); - setSelectedParameters([...selectedParameters, selectedParameter]); }; @@ -360,7 +444,7 @@ const DataVisualizer: React.FC = () => { let updatedAvailableParameters = [...availableParameters]; - selectedIndicators.attributes.filter((parameter) => { + selectedIndicators?.attributes?.filter((parameter) => { if (parameter === selectedParameter) { updatedAvailableParameters = [ ...updatedAvailableParameters, @@ -368,11 +452,12 @@ const DataVisualizer: React.FC = () => { ]; } }); + setAvailableParameters(updatedAvailableParameters); }; const moveAllParametersLeft = () => { - setAvailableParameters(selectedIndicators.attributes); + setAvailableParameters(selectedIndicators?.attributes ?? []); setSelectedParameters([]); }; @@ -384,9 +469,17 @@ const DataVisualizer: React.FC = () => { const handleIndicatorChange = useCallback( ({ selectedItem }) => { const indicator = selectedItem; + + if (!selectedItem) { + setSelectedIndicators(null); + setAvailableParameters([]); + return; + } + getCategoryIndicator(selectedItem?.id, selectedItem?.type).then( (response) => { let results; + switch (selectedItem.type) { case "PersonName": results = personNames; @@ -419,12 +512,14 @@ const DataVisualizer: React.FC = () => { } setSelectedIndicators(indicator); + const filteredArray = results?.filter( (resultParameter) => !selectedParameters?.some( (parameter) => parameter.id === resultParameter.id ) ); + indicator.attributes = filteredArray; setAvailableParameters(indicator.attributes ?? []); }, @@ -442,35 +537,38 @@ const DataVisualizer: React.FC = () => { ); const handleSelectedReportDefinition = ({ selectedItem }) => { - setSelectedReport(selectedItem); + setSelectedReport(selectedItem ?? null); }; const handleSelectedDynamicReportType = ({ selectedItem }) => { - let reports = []; + setSelectedDynamicReportType(selectedItem ?? null); + setSelectedReport(null); + setDynamicReportTypes([]); + + if (!selectedItem) { + return; + } if (selectedItem.id === "reportDefinition") { - setDynamicReportTypes(facilityReports?.reports); - setSelectedReport(facilityReports?.reports?.[0]); + setDynamicReportTypes(facilityReports ?? []); } else { getCohortCategory(selectedItem.id).then((response) => { const responseResults = selectedItem.id === "patientSearch" ? response : response?.results; - responseResults?.map((responseItem) => { - reports.push({ + + const reports = + responseResults?.map((responseItem) => ({ id: responseItem?.uuid, label: responseItem?.name, - }); - }); + })) ?? []; + setDynamicReportTypes(reports); - setSelectedReport(reports[0] ?? null); }); } - - setSelectedDynamicReportType(selectedItem); }; const handleFiltersToggle = () => { - showFilters === true ? setShowFilters(false) : setShowFilters(true); + setShowFilters((prev) => !prev); }; const handleStartDateChange = (selectedDate) => { @@ -481,34 +579,74 @@ const DataVisualizer: React.FC = () => { setEndDate(selectedDate[0]); }; - const handleReportCategoryChange = (selectedItem) => { - const typeOfReport = selectedItem.selectedItem.id; - if (typeOfReport === "national") { + const handleReportCategoryChange = ({ selectedItem }) => { + if (!selectedItem) { + setReportCategory({ + category: undefined, + renderType: undefined, + categoryUuid: undefined, + categoryName: undefined, + }); + setSelectedReport(null); + setChartType("list"); + return; + } + + const categoryName = selectedItem?.name || selectedItem?.label || ""; + const categoryUuid = selectedItem?.uuid || selectedItem?.id; + + setSelectedReport(null); + + if (categoryName === "NATIONAL REPORTS") { setReportCategory({ category: "national", renderType: "html", + categoryUuid, + categoryName, }); setChartType("aggregate"); - } else if (typeOfReport === "cqi") { - setReportCategory({ category: "cqi" }); + } else if (categoryName === "CQI REPORTS") { + setReportCategory({ + category: "cqi", + renderType: undefined, + categoryUuid, + categoryName, + }); setChartType("list"); - } else if (typeOfReport === "donor") { + } else if (categoryName === "MER INDICATOR REPORTS") { setReportCategory({ category: "donor", renderType: "html", + categoryUuid, + categoryName, }); setChartType("aggregate"); - } else if (typeOfReport === "integration") { - setReportCategory({ category: "integration" }); + } else if (categoryName === "Integration Data Exports") { + setReportCategory({ + category: "integration", + renderType: undefined, + categoryUuid, + categoryName, + }); setChartType("list"); } else { - setReportCategory({ category: "facility" }); + setReportCategory({ + category: "facility", + renderType: "list", + categoryUuid, + categoryName, + }); setChartType("list"); } }; const handleReportingPeriod = (selectedPeriod) => { - setReportingPeriod(selectedPeriod?.selectedItem); + setReportingPeriod(selectedPeriod?.selectedItem ?? null); + + if (!selectedPeriod?.selectedItem?.id) { + return; + } + const dateRange = getDateRange(selectedPeriod?.selectedItem?.id); setStartDate(dateRange.start); setEndDate(dateRange.end); @@ -519,9 +657,9 @@ const DataVisualizer: React.FC = () => { selectedParameters.map((parameter) => parameter.id === selectedParameter.id ? { - ...parameter, - modifier: addORSubtract(selectedParameter?.modifier, type), - } + ...parameter, + modifier: addORSubtract(selectedParameter?.modifier, type), + } : parameter ) ); @@ -542,9 +680,9 @@ const DataVisualizer: React.FC = () => { selectedParameters.map((parameter) => parameter.id === selectedParameter.id ? { - ...parameter, - showModifierPanel: !selectedParameter?.showModifierPanel, - } + ...parameter, + showModifierPanel: !selectedParameter?.showModifierPanel, + } : parameter ) ); @@ -556,9 +694,9 @@ const DataVisualizer: React.FC = () => { selectedParameters.map((parameter) => parameter.id === selectedParameter.id ? { - ...parameter, - extras: [...parameter?.extras, event?.target?.value], - } + ...parameter, + extras: [...parameter?.extras, event?.target?.value], + } : parameter ) ); @@ -567,11 +705,11 @@ const DataVisualizer: React.FC = () => { selectedParameters.map((parameter) => parameter.id === selectedParameter.id ? { - ...parameter, - extras: parameter?.extras.filter( - (modifier) => modifier !== event?.target?.value - ), - } + ...parameter, + extras: parameter?.extras.filter( + (modifier) => modifier !== event?.target?.value + ), + } : parameter ) ); @@ -579,6 +717,8 @@ const DataVisualizer: React.FC = () => { }; const handleUpdateReport = useCallback(() => { + if (!selectedReport) return; + setHTML(""); setShowLineList(true); setLoading(true); @@ -588,7 +728,10 @@ const DataVisualizer: React.FC = () => { uuid: selectedReport.id, startDate: formatDate(startDate), endDate: formatDate(endDate), - reportCategory: reportCategory, + reportCategory: reportCategory as { + category: ReportCategory; + renderType?: RenderType; + }, reportIndicators: selectedParameters, reportType: reportType, reportingCohort: cqiReportingCohort, @@ -599,55 +742,52 @@ const DataVisualizer: React.FC = () => { let headers = []; let dataForReport: any = []; const reportData = response?.data; + if (reportType === "fixed") { if (reportCategory.category === "cqi") { dataForReport = response?.data?.A; headers = CQIReportHeaders; + } else if (reportCategory.renderType === "html") { + setHTML(reportData?.html ?? ""); + setDhisJson(reportData?.json ?? {}); } else { - if (reportCategory.renderType === "html") { - setHTML(reportData?.html ?? ""); - setDhisJson(reportData?.json ?? {}); - } else { - const responseReportName = Object.keys(reportData)[0]; + const responseReportName = Object.keys(reportData)[0]; + + if ( + reportData[responseReportName] && + reportData[responseReportName][0] + ) { + let columnNames = Object.keys(reportData[responseReportName][0]); + if ( - reportData[responseReportName] && - reportData[responseReportName][0] + selectedReport.id === "bf79f017-8591-4eaf-88c9-1cde33226517" ) { - let columnNames = Object.keys( - reportData[responseReportName][0] - ); - if ( - selectedReport.id === "bf79f017-8591-4eaf-88c9-1cde33226517" - ) { - columnNames = columnNames - .reverse() - .filter( - (column) => column !== "EDD" && column !== "Names" - ); - headers = createColumns(columnNames); - dataForReport = reportData[responseReportName] - .filter((row) => row.PhoneNumber) - .map((row) => { - const formattedDate = extractDate(row.LastVisitDate); - if ( - row.PhoneNumber && - row.PhoneNumber.startsWith("0") - ) { - return { - ...row, - PhoneNumber: "256" + row.PhoneNumber.substring(1), - LastVisitDate: formattedDate, - }; - } - return row; - }); - } else { - headers = createColumns(columnNames); - dataForReport = reportData[responseReportName]; - } + columnNames = columnNames + .reverse() + .filter((column) => column !== "EDD" && column !== "Names"); + + headers = createColumns(columnNames); + dataForReport = reportData[responseReportName] + .filter((row) => row.PhoneNumber) + .map((row) => { + const formattedDate = extractDate(row.LastVisitDate); + + if (row.PhoneNumber && row.PhoneNumber.startsWith("0")) { + return { + ...row, + PhoneNumber: "256" + row.PhoneNumber.substring(1), + LastVisitDate: formattedDate, + }; + } + + return row; + }); } else { - setShowLineList(false); + headers = createColumns(columnNames); + dataForReport = reportData[responseReportName]; } + } else { + setShowLineList(false); } } } else { @@ -700,6 +840,9 @@ const DataVisualizer: React.FC = () => { }; }, []); + const selectedReportTypeItem = + reportTypes?.find((item) => item.uuid === reportCategory.categoryUuid) ?? null; + return ( <> } /> @@ -722,7 +865,7 @@ const DataVisualizer: React.FC = () => { @@ -741,11 +884,9 @@ const DataVisualizer: React.FC = () => { id="ReportTypeCombobox" items={reportTypes} onChange={handleReportCategoryChange} - selectedItem={ - reportTypes?.filter( - (item) => item.id === reportCategory.category - )[0] - } + selectedItem={selectedReportTypeItem} + itemToString={(item) => item?.label ?? ""} + placeholder="Select report type" /> @@ -757,9 +898,12 @@ const DataVisualizer: React.FC = () => { item?.label ?? ""} + placeholder="Select facility report" + disabled={!hasFixedCategory} /> )} @@ -772,9 +916,12 @@ const DataVisualizer: React.FC = () => { item?.label ?? ""} + placeholder="Select national report" + disabled={!hasFixedCategory} /> )} @@ -787,9 +934,12 @@ const DataVisualizer: React.FC = () => { item?.label ?? ""} + placeholder="Select donor report" + disabled={!hasFixedCategory} /> )} @@ -802,9 +952,12 @@ const DataVisualizer: React.FC = () => { item?.label ?? ""} + placeholder="Select CQI report" + disabled={!hasFixedCategory} /> )} @@ -817,9 +970,12 @@ const DataVisualizer: React.FC = () => { item?.label ?? ""} + placeholder="Select integration export" + disabled={!hasFixedCategory} /> )} @@ -864,27 +1020,35 @@ const DataVisualizer: React.FC = () => { items={dynamicReportOptions} onChange={handleSelectedDynamicReportType} selectedItem={selectedDynamicReportType} + itemToString={(item) => item?.label ?? ""} + placeholder="Select dynamic report type" /> - - - {selectedDynamicReportType?.label} - + {selectedDynamicReportType && ( + + + {selectedDynamicReportType?.label ?? "Report"} + - - + item?.label ?? ""} + placeholder="Select report" + disabled={!hasDynamicCategory} + /> + + )} )} +
@@ -911,6 +1075,7 @@ const DataVisualizer: React.FC = () => { /> + {reportingDuration === "fixed" && ( { )} + {reportingDuration === "relative" && ( @@ -953,6 +1119,7 @@ const DataVisualizer: React.FC = () => { placeholder="Choose the reporting period" onChange={handleReportingPeriod} selectedItem={reportingPeriod} + itemToString={(item) => item?.label ?? ""} /> )} @@ -960,6 +1127,7 @@ const DataVisualizer: React.FC = () => {
+
{reportType === "dynamic" && ( @@ -978,6 +1146,7 @@ const DataVisualizer: React.FC = () => { placeholder="Choose the indicators" onChange={handleIndicatorChange} selectedItem={selectedIndicators} + itemToString={(item) => item?.label ?? ""} /> @@ -996,6 +1165,7 @@ const DataVisualizer: React.FC = () => { ))} +
+
    {selectedParameters.map((parameter) => ( - <> +
  • @@ -1073,6 +1243,7 @@ const DataVisualizer: React.FC = () => { ) : null}
  • +
    { onChangeExtraValue={handleOnChnageExtras} />
    - +
    ))}
@@ -1103,7 +1274,9 @@ const DataVisualizer: React.FC = () => {
@@ -1126,6 +1299,7 @@ const DataVisualizer: React.FC = () => {
+
- {data.length > 0 || htmlContent != "" ? ( + + {data.length > 0 || htmlContent !== "" ? ( <> {chartType === "pivot" ? (
@@ -1216,19 +1399,17 @@ const DataVisualizer: React.FC = () => { {chartType === "list" && !loading && - selectedReport.id === "bf79f017-8591-4eaf-88c9-1cde33226517" && ( - <> -
- -
- + selectedReport?.id === "bf79f017-8591-4eaf-88c9-1cde33226517" && ( +
+ +
)} {chartType === "pivot" && ( diff --git a/src/data-visualizer/data-visualizer.resource.ts b/src/data-visualizer/data-visualizer.resource.ts index 76c3ec0..dac6288 100644 --- a/src/data-visualizer/data-visualizer.resource.ts +++ b/src/data-visualizer/data-visualizer.resource.ts @@ -35,18 +35,58 @@ type ReportDownloadParams = { reportingCohort?: CQIReportingCohort; }; +type ReportLibraryCategoryRef = { + uuid: string; + display?: string; + name?: string; + description?: string; +}; + +type ReportLibraryItem = { + uuid: string; + display?: string; + name: string; + description?: string; + code?: string; + sourceType?: string; + reportDefinitionUuid?: string; + reportBuilderReportUuid?: string; + reportType?: string; + migrated?: boolean; + retired?: boolean; + category?: ReportLibraryCategoryRef; +}; + +type ReportLibraryResponse = { + data: { + results: ReportLibraryItem[]; + }; +}; + +type ReportCategoryItem = { + uuid: string; + display?: string; + name: string; + description?: string; + retired?: boolean; +}; + +type ReportCategoryResponse = { + data: { + results: ReportCategoryItem[]; + }; +}; + export async function getReport(params: ReportRequest) { const abortController = new AbortController(); let apiUrl = `${restBaseUrl}/ugandaemrreports/reportingDefinition`; let fixedReportUrl = `${apiUrl}?startDate=${params.startDate}&endDate=${params.endDate}&uuid=${params.uuid}`; if (params.reportType === "fixed") { - if (params.reportCategory.category === "cqi") { + if (params.reportCategory?.category === "cqi") { fixedReportUrl += `&cohortList=${params.reportingCohort}`; - } else { - if (params.reportCategory.renderType === "html") { - fixedReportUrl += `&renderType=${params.reportCategory.renderType}`; - } + } else if (params.reportCategory?.renderType === "html") { + fixedReportUrl += `&renderType=${params.reportCategory.renderType}`; } return openmrsFetch(fixedReportUrl, { @@ -54,7 +94,7 @@ export async function getReport(params: ReportRequest) { }); } else { const parameters = - params.reportIndicators.length > 0 + params.reportIndicators && params.reportIndicators.length > 0 ? formatReportArray(params.reportIndicators) : []; @@ -132,6 +172,7 @@ export function useGetEncounterType() { isLoadingEncounterTypes: isLoading, }; } + export function useGetOrderTypes() { const apiUrl = `${restBaseUrl}/ordertype?v=custom:(uuid,display,name)`; const { data, error, isLoading } = useSWR<{ data: { results: any } }, Error>( @@ -195,20 +236,51 @@ export async function getCohortCategory(type: string) { return data; } -export function useGetReportingRegistry() { - const apiUrl = `${restBaseUrl}/systemsetting/f4544de3-001c-4cbf-b939-75a2884edafa`; - const { data, error, isLoading } = useSWR<{ data: { results: any } }, Error>( +/* report library */ + +export function useGetReportLibrary() { + const apiUrl = `${restBaseUrl}/reportlibrary?v=full`; + + const { data, error, isLoading, mutate } = useSWR( + apiUrl, + openmrsFetch + ); + + return { + reportLibrary: data?.data?.results ?? [], + isError: error, + isLoadingReportLibrary: isLoading, + mutate, + }; +} + +export function useGetReportCategories() { + const apiUrl = `${restBaseUrl}/reportcategory?v=full`; + + const { data, error, isLoading, mutate } = useSWR( apiUrl, openmrsFetch ); return { - reportingRegistry: data ? parseReportingString(data?.data) : [], + reportCategories: data?.data?.results ?? [], isError: error, - isLoadingRegistry: isLoading, + isLoadingReportCategories: isLoading, + mutate, }; } +export const getReportFromRegistry = ( + reportLibrary: ReportLibraryItem[], + type: string +) => { + return reportLibrary?.filter( + (report) => + report?.category?.name?.toLowerCase() === type?.toLowerCase() || + report?.category?.display?.toLowerCase() === type?.toLowerCase() + ); +}; + export const createColumns = (columns: Array) => { let dataColumn: Array> = []; columns.map((column: string, index) => { @@ -418,13 +490,3 @@ export const extractDate = (timestamp: string): string => { export const formatDate = (date: Date): string => { return dayjs(date).format("YYYY-MM-DD"); }; - -const parseReportingString = (dataResponse) => { - const valueString = dataResponse?.value; - - return JSON.parse(valueString); -}; - -export const getReportFromRegistry = (registry, type) => { - return registry?.categories?.find((category) => category?.id === type); -};