From 1045d03b369ac88b4eda330380f89d33e1eacc90 Mon Sep 17 00:00:00 2001
From: TrevorAntony <61781670+TrevorAntony@users.noreply.github.com>
Date: Thu, 25 Jul 2024 13:50:11 +0300
Subject: [PATCH] Reporting Demo Changes (#1912)
---
.../components/reports/home.component.scss | 143 ++++++++++++++++
.../src/components/reports/reportfilters.tsx | 75 +++++++++
.../reports/reports-home.component.tsx | 153 +++++++++++++++++-
.../reports/reports-root.component.tsx | 4 +-
packages/esm-commons-lib/src/config-schema.ts | 16 ++
5 files changed, 382 insertions(+), 9 deletions(-)
create mode 100644 packages/esm-commons-lib/src/components/reports/home.component.scss
create mode 100644 packages/esm-commons-lib/src/components/reports/reportfilters.tsx
diff --git a/packages/esm-commons-lib/src/components/reports/home.component.scss b/packages/esm-commons-lib/src/components/reports/home.component.scss
new file mode 100644
index 000000000..5f252fe23
--- /dev/null
+++ b/packages/esm-commons-lib/src/components/reports/home.component.scss
@@ -0,0 +1,143 @@
+.centeredTextContainer {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 50px;
+ text-align: center;
+ }
+
+ .container {
+ padding: 2rem;
+ }
+
+ .homeContainer {
+ padding: 1rem;
+ }
+
+ .dropdownItem {
+ display: flex;
+ align-items: center;
+ }
+
+ .layer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 300px;
+ }
+
+ .tile {
+ padding: 2rem;
+ text-align: center;
+ }
+
+ .content {
+ font-size: 1.25rem;
+ color: #5a5a5a;
+ }
+
+ .explainer {
+ color: #777;
+ }
+
+ .form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ }
+
+ .formContainer {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .datePickerContainer {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ }
+
+ .datePickerContainer > * {
+ flex: 1;
+ min-width: 150px;
+ }
+
+ .fetchButtonContainer {
+ margin-left: 16px;
+ display: flex;
+ align-items: center;
+ }
+
+ .datePickerInput {
+ min-width: 120px;
+ }
+
+ .button {
+ max-height: 40px;
+ line-height: 40px;
+ font-size: 14px;
+ padding: 0 16px;
+ margin-top: 1rem;
+ max-width: 120px;
+ align-items: center;
+ }
+
+ .dataTableContainer {
+ margin-top: 2rem;
+ padding: 1rem;
+ border: solid 1px #e0e0e0;
+ max-height: calc(100vh - 200px);
+ overflow: auto;
+ height: 100vh;
+ }
+
+ .dataTableFullContainer {
+ margin-top: 2rem;
+ padding: 1rem;
+ max-height: calc(100vh - 200px);
+ overflow: auto;
+ }
+
+
+ .tableContainer {
+ margin-top: 1rem;
+ }
+
+ .toolbarWrapper {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .toolbarContent {
+ display: flex;
+ gap: 1rem;
+ }
+
+ .searchbox {
+ flex-grow: 1;
+ }
+
+ .tileContainer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ }
+
+ .tileContent {
+ text-align: center;
+ }
+
+ .content {
+ font-size: 1.25rem;
+ color: #5a5a5a;
+ }
+
+ .pagination {
+ margin-top: 1rem;
+ }
+
\ No newline at end of file
diff --git a/packages/esm-commons-lib/src/components/reports/reportfilters.tsx b/packages/esm-commons-lib/src/components/reports/reportfilters.tsx
new file mode 100644
index 000000000..8af4a8eb3
--- /dev/null
+++ b/packages/esm-commons-lib/src/components/reports/reportfilters.tsx
@@ -0,0 +1,75 @@
+import React from 'react';
+import { ComboBox, Button, DatePicker, DatePickerInput } from '@carbon/react';
+import styles from './home.component.scss';
+
+const ReportFilters = ({
+ config,
+ uuid,
+ reportId,
+ setReportId,
+ ptrackerId,
+ setPtrackerId,
+ personUuid,
+ setPersonUuid,
+ startDate,
+ setStartDate,
+ endDate,
+ setEndDate,
+ handleSubmit,
+ setReportRequested,
+}) => {
+ const handleDateChange = (setter) => (event) => {
+ const date = event[0] ? event[0].toISOString().split('T')[0] : '';
+ setter(date);
+ };
+
+ return (
+ <>
+
+
Report Filters
+
+
+ >
+ );
+};
+
+export default ReportFilters;
diff --git a/packages/esm-commons-lib/src/components/reports/reports-home.component.tsx b/packages/esm-commons-lib/src/components/reports/reports-home.component.tsx
index bad9ba041..9ddc878b1 100644
--- a/packages/esm-commons-lib/src/components/reports/reports-home.component.tsx
+++ b/packages/esm-commons-lib/src/components/reports/reports-home.component.tsx
@@ -1,14 +1,153 @@
-import React from 'react';
+import React, { useState, useMemo, useEffect } from 'react';
+import useSWR from 'swr';
+import {
+ DataTable,
+ Table,
+ TableHead,
+ TableRow,
+ TableHeader,
+ TableBody,
+ TableCell,
+ Layer,
+ Tile,
+ DataTableSkeleton,
+} from '@carbon/react';
import { OHRIWelcomeSection } from '@ohri/openmrs-esm-ohri-commons-lib';
-import { Reports } from './reports';
+import { openmrsFetch, useConfig, restBaseUrl } from '@openmrs/esm-framework';
+import styles from './home.component.scss';
+import capitalize from 'lodash/capitalize';
+import { EmptyDataIllustration } from '@openmrs/esm-patient-common-lib';
+import ReportFilters from './reportfilters';
+import { useTranslation } from 'react-i18next';
+
+const snakeCaseToCapitalizedWords = (snakeCaseString) =>
+ snakeCaseString
+ .split('_')
+ .map((word) => capitalize(word))
+ .join(' ');
+
+const fetcher = (url) => openmrsFetch(url).then((res) => res.json());
+
+const ReportComponent = () => {
+ const config = useConfig();
+ const { t } = useTranslation();
+ const [reportId, setReportId] = useState('');
+ const [uuid, setUuid] = useState('');
+ const [ptrackerId, setPtrackerId] = useState('');
+ const [personUuid, setPersonUuid] = useState('');
+ const [startDate, setStartDate] = useState('');
+ const [endDate, setEndDate] = useState('');
+ const [reportRequested, setReportRequested] = useState(false);
+
+ const url = useMemo(() => {
+ if (!startDate || !endDate || !reportId) return null;
+ return `${restBaseUrl}/reportingrest/reportdata/${reportId}?startDate=${startDate}&endDate=${endDate}`;
+ }, [reportId, startDate, endDate]);
+
+ const { data, error, mutate } = useSWR(url, fetcher, { revalidateOnFocus: false });
+
+ useEffect(() => {
+ if (error) {
+ console.error('Error fetching report data:', error);
+ }
+ }, [error]);
+
+ const headers = useMemo(() => {
+ if (!data || !data.dataSets || !data.dataSets.length || !data.dataSets[0].metadata) return [];
+ return data.dataSets[0].metadata.columns.map((column) => ({
+ key: column.name,
+ header: column.label,
+ }));
+ }, [data]);
+
+ const rows = useMemo(() => {
+ if (!data || !data.dataSets || !data.dataSets.length || !data.dataSets[0].rows) return [];
+ return data.dataSets[0].rows.map((result, idx) => ({
+ id: idx.toString(),
+ ...result,
+ }));
+ }, [data]);
+
+ const loading = !data && !error && reportRequested;
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ setReportRequested(true);
+ mutate();
+ };
-const ReportsHomecomponent = () => {
return (
-
-
-
+
+
+
+ {loading ? (
+
+ ) : error ? (
+
+
+
+ {t('errorLoadingData', 'Error loading data')}
+ {t('pleaseTryAgain', 'Please try again later')}
+
+
+
+ ) : rows.length === 0 || !reportRequested ? (
+
+
+
+
+ {t('noDataToDisplay', 'No data to display')}
+
+ {t('useReportsAboveToBuild', 'Use the report filters above to build your reports')}
+
+
+
+
+ ) : (
+
+
+ {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => (
+
+
+
+ {headers.map((header) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {rows.map((row) => (
+
+ {headers.map((header) => (
+ {row[header.key] || '-'}
+ ))}
+
+ ))}
+
+
+ )}
+
+
+ )}
);
};
-export default ReportsHomecomponent;
+export default ReportComponent;
diff --git a/packages/esm-commons-lib/src/components/reports/reports-root.component.tsx b/packages/esm-commons-lib/src/components/reports/reports-root.component.tsx
index 19d31230b..01e8545fb 100644
--- a/packages/esm-commons-lib/src/components/reports/reports-root.component.tsx
+++ b/packages/esm-commons-lib/src/components/reports/reports-root.component.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { SWRConfig } from 'swr';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
-import ReportsHome from './reports-home.component';
+import ReportComponent from './reports-home.component';
const swrConfiguration = {
errorRetryCount: 3,
@@ -15,7 +15,7 @@ const RootComponent: React.FC = () => {
- } />
+ } />
diff --git a/packages/esm-commons-lib/src/config-schema.ts b/packages/esm-commons-lib/src/config-schema.ts
index 44609ea53..9efd64323 100644
--- a/packages/esm-commons-lib/src/config-schema.ts
+++ b/packages/esm-commons-lib/src/config-schema.ts
@@ -6,6 +6,22 @@ export const configSchema = {
_description: 'Show mamba reports',
_default: false,
},
+ reports: {
+ _type: Type.Array,
+ _description: 'Reports and their associated UUIDs.',
+ _default: [
+ { name: 'Covid-19 Report', uuid: 'ecabd559-14f6-4c65-87af-1254dfdf1304' },
+ { name: 'HTS Report', uuid: '3ffa5a53-fc65-4a1e-a434-46dbcf1c2de2' },
+ { name: 'ADX-HIV Report', uuid: '12f236b1-b0b5-4ecc-9037-681c23fb45bd' },
+ { name: 'Mamba HTS Line List', uuid: '6a6ae4ce-8427-45a6-9835-bbd6ade7a670' },
+ {
+ name: 'Mother HIV Status Report',
+ uuid: 'mother_hiv_status',
+ ptrackerId: '12345A232567',
+ personUuid: 'bd49d697-b1de-49b9-95c2-6031fb1375fd',
+ },
+ ],
+ },
};
export interface ConfigObject {