Skip to content

Commit

Permalink
Merge pull request #105 from sainingo/main
Browse files Browse the repository at this point in the history
Add multi-locations select functionality
  • Loading branch information
Rugute authored Jul 1, 2024
2 parents 415436a + a543885 commit 3a6c507
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 50 deletions.
31 changes: 31 additions & 0 deletions packages/esm-report-app/src/hooks/useSelectedLocations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import React, { createContext, useContext, useState, ReactNode, FC } from 'react';

interface SelectedLocationsContextType {
selectedLocations: any;
setSelectedLocations: React.Dispatch<React.SetStateAction<any>>;
}

const SelectedLocationsContext = createContext<SelectedLocationsContextType | undefined>(undefined);

export const useSelectedLocations = (): SelectedLocationsContextType => {
const context = useContext(SelectedLocationsContext);
if (!context) {
throw new Error('useSelectedLocations must be used within a SelectedLocationsProvider');
}
return context;
};

interface SelectedLocationsProviderProps {
children: ReactNode;
}

export const SelectedLocationsProvider: FC<SelectedLocationsProviderProps> = ({ children }) => {
const [selectedLocations, setSelectedLocations] = useState<any>();

return (
<SelectedLocationsContext.Provider value={{ selectedLocations, setSelectedLocations }}>
{children}
</SelectedLocationsContext.Provider>
);
};
14 changes: 13 additions & 1 deletion packages/esm-report-app/src/location/location.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import styles from './location.scss';
import IptTableComponent from '../clinical-dashboard/ipt-report/ipt-table-component';
import { getFacilityLocations, getLocations } from '../api/api';
import { useSession } from '@openmrs/esm-framework';
import { useSelectedLocations } from '../hooks/useSelectedLocations';

export const LocationsComponent = ({ facilitylocations }) => {
const { t } = useTranslation();
const [currentLocation, setCurrentLocation] = useState(null);
const { facilityLocations } = getFacilityLocations();
const locationUuid = useSession()?.sessionLocation?.uuid;
const [currentLocations, setCurrentLocations] = useState([]);
const { setSelectedLocations } = useSelectedLocations();

useEffect(() => {
const fetchLocations = async () => {
Expand All @@ -36,13 +38,23 @@ export const LocationsComponent = ({ facilitylocations }) => {
fetchLocations();
}, [locationUuid]);

const handleLocationChange = (selectedItems) => {
if (Array.isArray(selectedItems)) {
const selectedValues = selectedItems.map((item) => item.value);
setCurrentLocation(selectedValues);
} else {
setSelectedLocations(selectedItems);
}
};

return (
<div className={styles.container}>
<MultiSelect
label="Locations"
items={currentLocations}
placeholder="Select locations"
onChange={(selectedItems) => setCurrentLocation(selectedItems)}
onChange={handleLocationChange}
// onChange={(selectedItems) => setCurrentLocation(selectedItems)}
/>
{/* <IptTableComponent locationUuid={'18c343eb-b353-462a-9139-b16606e6b6c2'} endDate={'2024-02-29'} /> */}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,15 @@ p {
}

th.vertical_text {
writing-mode: vertical-lr;
text-orientation: mixed;
white-space: nowrap;
transform: rotate(180deg);
writing-mode: vertical-lr;
text-orientation: mixed;
white-space: nowrap;
transform: rotate(180deg);

vertical-align: bottom;
vertical-align: bottom;
}

td {



font-weight: normal;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ import styles from './ReportSummary.css';
import reportMapping from '../report-loader/reportMapping.json';
import { generateReportData, getSPReports } from '../../api/api';
import { useSession } from '@openmrs/esm-framework';
import { useSelectedLocations } from '../../hooks/useSelectedLocations';

const ReportSummary: React.FC<any> = ({ rows = [] }) => {
const [loading, setLoading] = useState(false);
const [refreshLoading, setRefreshLoading] = useState(false);
const [currentRows, setCurrentRows] = useState([]);
const [selectedLocationUuids, setSelectedLocationUuids] = useState([]);
const navigate = useNavigate();
const locationUuid = useSession()?.sessionLocation?.uuid;
const { selectedLocations } = useSelectedLocations();
const [multipleLocations, setMultipleLocations] = useState([]);

const headers = [
{ key: 'status', header: 'Status' },
Expand All @@ -38,6 +40,7 @@ const ReportSummary: React.FC<any> = ({ rows = [] }) => {
];

useEffect(() => {
setMultipleLocations(selectedLocations);
if (rows && Array.isArray(rows)) {
const rowsWithButtons = rows.map((row) => {
const reportMappingEntry = reportMapping.find((entry) => entry.report_uuid === row.uuid);
Expand All @@ -47,7 +50,7 @@ const ReportSummary: React.FC<any> = ({ rows = [] }) => {
view: reportMappingEntry ? (
<button
className={styles.view_button}
onClick={() => handleViewClick(reportMappingEntry.report_uuid, Number(row.log_id))}>
onClick={() => handleViewClick(selectedLocations, reportMappingEntry.report_uuid, Number(row.log_id))}>
View
</button>
) : null,
Expand All @@ -56,52 +59,56 @@ const ReportSummary: React.FC<any> = ({ rows = [] }) => {
});
setCurrentRows(rowsWithButtons);
}
}, [rows]);

const handleViewClick = async (report_uuid, report_id) => {
}, [selectedLocations]);
const handleViewClick = async (locations, report_uuid, report_id) => {
setLoading(true);
try {
if (selectedLocationUuids.length === 0) {
const formattedLocationUuid = `'${locationUuid}'`;
const response = await generateReportData(report_id, formattedLocationUuid);
const data = response.results;
let formattedLocationUuid = null;

navigate(`/reports/${report_uuid}`, { state: { reportData: data } });
if (locations && locations?.selectedItems.length > 0) {
formattedLocationUuid = locations?.selectedItems.map((item) => `'${item.value}'`).join(',');
} else {
formattedLocationUuid = `'${locationUuid}'`;
}

const response = await generateReportData(report_id, formattedLocationUuid);
const data = response.results;

navigate(`/reports/${report_uuid}`, { state: { reportData: data } });
} catch (error) {
console.error('Error fetching report data:', error);
} finally {
setLoading(false);
}
};

const handleRefresh = () => {
setRefreshLoading(true);
try {
if (rows && Array.isArray(rows)) {
const rowsWithButtons = rows.map((row) => {
const reportMappingEntry = reportMapping.find((entry) => entry.report_uuid === row.uuid);
return {
...row,
id: row.log_id,
view: reportMappingEntry ? (
<button
className={styles.view_button}
onClick={() => handleViewClick(reportMappingEntry.report_uuid, Number(row.log_id))}>
View
</button>
) : null,
download: <button className={styles.download_button}>Download</button>,
};
});
setCurrentRows(rowsWithButtons);
}
} catch (error) {
console.error('Error refreshing data:', error);
} finally {
setRefreshLoading(false);
}
};
// const handleRefresh = () => {
// setRefreshLoading(true);
// try {
// if (rows && Array.isArray(rows)) {
// const rowsWithButtons = rows.map((row) => {
// const reportMappingEntry = reportMapping.find((entry) => entry.report_uuid === row.uuid);
// return {
// ...row,
// id: row.log_id,
// view: reportMappingEntry ? (
// <button
// className={styles.view_button}
// onClick={() => handleViewClick(reportMappingEntry.report_uuid, Number(row.log_id))}>
// View
// </button>
// ) : null,
// download: <button className={styles.download_button}>Download</button>,
// };
// });
// setCurrentRows(rowsWithButtons);
// }
// } catch (error) {
// console.error('Error refreshing data:', error);
// } finally {
// setRefreshLoading(false);
// }
// };

return (
<div className={styles.wrapper_container}>
Expand Down
7 changes: 5 additions & 2 deletions packages/esm-report-app/src/root.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ import ClinicalDashboardComponent from './clinical-dashboard/clinical-dashboard.
import IptReportComponent from './clinical-dashboard/ipt-report/ipt-report.component';
import { ReportHeader } from './headers/report-header-component';
import ReportDashboard from './reports-dashboard/report-dashboard-component';
import { SelectedLocationsProvider } from '../src/hooks/useSelectedLocations';

const Root: React.FC = () => {
return (
<div>
<div className={styles.container}>
<ReportHeader />
<ReportDashboard />
<SelectedLocationsProvider>
<ReportHeader />
<ReportDashboard />
</SelectedLocationsProvider>
</div>
</div>
);
Expand Down
13 changes: 11 additions & 2 deletions packages/esm-report-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
"extends": "../../tsconfig.json",
"include": ["src/**/*"],
"exclude": ["src/**/*.test.tsx"]
"compilerOptions": {
"jsx": "react",
"esModuleInterop": true,
"skipLibCheck": true
},
"include": [
"src/**/*"
],
"exclude": [
"src/**/*.test.tsx"
]
}

0 comments on commit 3a6c507

Please sign in to comment.