Skip to content

Commit

Permalink
paginate encounters on the backend
Browse files Browse the repository at this point in the history
  • Loading branch information
hadijahkyampeire committed Sep 19, 2024
1 parent 6bea80e commit 0175a3f
Show file tree
Hide file tree
Showing 5 changed files with 1,618 additions and 1,292 deletions.
2 changes: 1 addition & 1 deletion packages/esm-commons-lib/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export interface Location {

export interface OpenmrsEncounter extends OpenmrsResource {
encounterDatetime: Date;
encounterType: string;
encounterType: { name: string; uuid: string };
patient: string;
location: string;
encounterProviders?: Array<{ encounterRole: string; provider: string }>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { EmptyState } from '../empty-state/empty-state.component';
import { FormLauncherWithIntent } from '../ohri-form-launcher/ohri-form-launcher.component';
import styles from './encounter-list.scss';
import { OTable } from '../data-table/o-table.component';
import { Button, Link, OverflowMenu, OverflowMenuItem, Pagination, DataTableSkeleton } from '@carbon/react';
import { Add } from '@carbon/react/icons';
Expand All @@ -14,6 +13,8 @@ import { OpenmrsEncounter } from '../../api/types';
import { useFormsJson } from '../../hooks/useFormsJson';
import { usePatientDeathStatus } from '../../hooks/usePatientDeathStatus';

import styles from './encounter-list.scss';

export interface EncounterListColumn {
key: string;
header: string;
Expand Down Expand Up @@ -64,12 +65,15 @@ export const EncounterList: React.FC<EncounterListProps> = ({
const { isDead } = usePatientDeathStatus(patientUuid);
const formNames = useMemo(() => formList.map((form) => form.name), []);
const { formsJson, isLoading: isLoadingFormsJson } = useFormsJson(formNames);
const { encounters, isLoading, onFormSave } = useEncounterRows(
const { encounters, total, isLoading, onFormSave } = useEncounterRows(
patientUuid,
encounterType,
filter,
afterFormSaveAction,
pageSize,
currentPage,
);

const { moduleName, workspaceWindowSize, displayText, hideFormLauncher } = launchOptions;

const defaultActions = useMemo(
Expand Down Expand Up @@ -102,38 +106,41 @@ export const EncounterList: React.FC<EncounterListProps> = ({
[forms, t],
);

const handleDeleteEncounter = useCallback((encounterUuid, encounterTypeName) => {
const close = showModal('delete-encounter-modal', {
close: () => close(),
encounterTypeName: encounterTypeName || '',
onConfirmation: () => {
const abortController = new AbortController();
deleteEncounter(encounterUuid, abortController)
.then(() => {
onFormSave();
showSnackbar({
isLowContrast: true,
title: t('encounterDeleted', 'Encounter deleted'),
subtitle: `Encounter ${t('successfullyDeleted', 'successfully deleted')}`,
kind: 'success',
});
})
.catch(() => {
showSnackbar({
isLowContrast: false,
title: t('error', 'Error'),
subtitle: `Encounter ${t('failedDeleting', "couldn't be deleted")}`,
kind: 'error',
const handleDeleteEncounter = useCallback(
(encounterUuid, encounterTypeName) => {
const close = showModal('delete-encounter-modal', {
close: () => close(),
encounterTypeName: encounterTypeName || '',
onConfirmation: () => {
const abortController = new AbortController();
deleteEncounter(encounterUuid, abortController)
.then(() => {
onFormSave();
showSnackbar({
isLowContrast: true,
title: t('encounterDeleted', 'Encounter deleted'),
subtitle: `Encounter ${t('successfullyDeleted', 'successfully deleted')}`,
kind: 'success',
});
})
.catch(() => {
showSnackbar({
isLowContrast: false,
title: t('error', 'Error'),
subtitle: `Encounter ${t('failedDeleting', "couldn't be deleted")}`,
kind: 'error',
});
});
});

// Update encounters after deletion
const updatedEncounters = encounters.filter((enc) => enc.uuid !== encounterUuid);
constructPaginatedTableRows(updatedEncounters, currentPage, pageSize);
close();
},
});
}, []);
// Update encounters after deletion
const updatedEncounters = encounters.filter((enc) => enc.uuid !== encounterUuid);
constructTableRows(updatedEncounters);
close();
},
});
},
[t, onFormSave, encounters],
);

useEffect(() => {
if (!isLoadingFormsJson) {
Expand Down Expand Up @@ -167,16 +174,9 @@ export const EncounterList: React.FC<EncounterListProps> = ({
return [];
}, [columns]);

const constructPaginatedTableRows = useCallback(
(encounters: OpenmrsEncounter[], currentPage: number, pageSize: number) => {
const startIndex = (currentPage - 1) * pageSize;
const paginatedEncounters = [];
for (let i = startIndex; i < startIndex + pageSize; i++) {
if (i < encounters.length) {
paginatedEncounters.push(encounters[i]);
}
}
const rows = paginatedEncounters.map((encounter) => {
const constructTableRows = useCallback(
(encounters: OpenmrsEncounter[]) => {
const rows = encounters.map((encounter) => {
const tableRow: { id: string; actions: any } = { id: encounter.uuid, actions: null };
// inject launch actions
encounter['launchFormActions'] = {
Expand Down Expand Up @@ -262,9 +262,9 @@ export const EncounterList: React.FC<EncounterListProps> = ({

useEffect(() => {
if (encounters?.length) {
constructPaginatedTableRows(encounters, currentPage, pageSize);
constructTableRows(encounters);
}
}, [encounters, pageSize, constructPaginatedTableRows, currentPage]);
}, [encounters, pageSize, constructTableRows, currentPage]);

const formLauncher = useMemo(() => {
if (forms.length == 1 && !forms[0]['availableIntents']?.length) {
Expand Down Expand Up @@ -317,7 +317,7 @@ export const EncounterList: React.FC<EncounterListProps> = ({
}, [forms, hideFormLauncher, isDead, displayText, moduleName, workspaceWindowSize, onFormSave, patientUuid]);

if (isLoading === true || isLoadingForms === true || isLoadingFormsJson === true) {
return <DataTableSkeleton rowCount={5} />;
return <DataTableSkeleton rowCount={10} />;
}

return (
Expand All @@ -335,7 +335,7 @@ export const EncounterList: React.FC<EncounterListProps> = ({
page={currentPage}
pageSize={pageSize}
pageSizes={[10, 20, 30, 40, 50]}
totalItems={encounters.length}
totalItems={total}
onChange={({ page, pageSize }) => {
setCurrentPage(page);
setPageSize(pageSize);
Expand Down
26 changes: 15 additions & 11 deletions packages/esm-commons-lib/src/hooks/useEncounterRows.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
import useSWR from 'swr';
import { OpenmrsEncounter } from '../api/types';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { openmrsFetch } from '@openmrs/esm-framework';
import { useCallback, useEffect, useState } from 'react';
import { openmrsFetch, OpenmrsResource } from '@openmrs/esm-framework';
import { encounterRepresentation } from '../constants';

interface EncounterResponse {
results: OpenmrsEncounter[];
totalCount?: number;
}

export function useEncounterRows(
patientUuid: string,
encounterType: string,
encounterFilter: (encounter) => boolean,
afterFormSaveAction: () => void,
pageSize?: number,
pageNumber?: number,
) {
const [encounters, setEncounters] = useState([]);
const url = `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}`;
const startIndex = (pageNumber - 1) * pageSize;

const {
data: response,
error,
isLoading,
mutate,
} = useSWR<{ data: { results: OpenmrsEncounter[] } }, Error>(url, openmrsFetch);
const url = `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}&totalCount=true&limit=${pageSize}&startIndex=${startIndex}`;

const { data: response, error, isLoading, mutate } = useSWR<{ data: EncounterResponse }, Error>(url, openmrsFetch);

useEffect(() => {
if (response) {
// sort the encounters
response.data.results.sort(
(a, b) => new Date(b.encounterDatetime).getTime() - new Date(a.encounterDatetime).getTime(),
);
// apply filter

if (encounterFilter) {
setEncounters(response.data.results.filter((encounter) => encounterFilter(encounter)));
} else {
Expand All @@ -42,6 +45,7 @@ export function useEncounterRows(

return {
encounters,
total: response?.data?.totalCount,
isLoading,
error,
onFormSave,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const HtsOverviewList: React.FC<HtsOverviewListProps> = ({ patientUuid }) => {
key: 'location',
header: t('location', 'Location'),
getValue: (encounter) => {
return encounter.location.name;
return encounter?.location?.name;
},
},
{
Expand Down
Loading

0 comments on commit 0175a3f

Please sign in to comment.