Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/medication-request/medication-request.resource.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Medication Request Resource Test', () => {
test('usePrescriptionsTable should call active endpoint and proper date based on expiration period if status parameter is active', () => {
// @ts-ignore
useSWR.mockImplementation(() => ({ data: { data: 'mockedReturnData' } }));
usePrescriptionsTable(5, 5, 'bob', null, 'ACTIVE', 10, 10000);
usePrescriptionsTable(true, 5, 5, 'bob', null, 'ACTIVE', 10, 10000);
expect(useSWR).toHaveBeenCalledWith(
`/ws/fhir2/R4/Encounter?_query=encountersWithMedicationRequests&_getpagesoffset=5&_count=5&date=ge${dayjs()
.startOf('day')
Expand All @@ -32,7 +32,7 @@ describe('Medication Request Resource Test', () => {
test('usePrescriptionsTable should call all endpoint if status parameter is not active', () => {
// @ts-ignore
useSWR.mockImplementation(() => ({ data: { data: 'mockedReturnData' } }));
usePrescriptionsTable(5, 5, 'bob', null, null, 10, 10000);
usePrescriptionsTable(true, 5, 5, 'bob', null, null, 10, 10000);
expect(useSWR).toHaveBeenCalledWith(
`/ws/fhir2/R4/Encounter?_query=encountersWithMedicationRequests&_getpagesoffset=5&_count=5&patientSearchTerm=bob`,
openmrsFetch,
Expand Down Expand Up @@ -587,7 +587,7 @@ describe('Medication Request Resource Test', () => {

// @ts-ignore
useSWR.mockImplementation(() => ({ data: { data: queryResultsBundle } }));
const { prescriptionsTableRows, totalOrders } = usePrescriptionsTable(2, 0, 'bob', 'ACTIVE', null, 90, 10000);
const { prescriptionsTableRows, totalOrders } = usePrescriptionsTable(true, 2, 0, 'bob', 'ACTIVE', null, 90, 10000);
expect(totalOrders).toBe(26);
expect(prescriptionsTableRows.length).toBe(2);
expect(prescriptionsTableRows[0].id).toBe('7aee7123-9e50-4f72-a636-895d77a63e98');
Expand Down
21 changes: 12 additions & 9 deletions src/medication-request/medication-request.resource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import dayjs from 'dayjs';
import { JSON_MERGE_PATH_MIME_TYPE, OPENMRS_FHIR_EXT_REQUEST_FULFILLER_STATUS } from '../constants';

export function usePrescriptionsTable(
loadData: boolean,
pageSize: number = 10,
pageOffset: number = 0,
patientSearchTerm: string = '',
Expand All @@ -34,15 +35,17 @@ export function usePrescriptionsTable(
refreshInterval: number,
) {
const { data, error } = useSWR<{ data: EncounterResponse }, Error>(
status === 'ACTIVE'
? getPrescriptionTableActiveMedicationRequestsEndpoint(
pageOffset,
pageSize,
dayjs(new Date()).startOf('day').subtract(medicationRequestExpirationPeriodInDays, 'day').toISOString(),
patientSearchTerm,
location,
)
: getPrescriptionTableAllMedicationRequestsEndpoint(pageOffset, pageSize, patientSearchTerm, location),
loadData
? status === 'ACTIVE'
? getPrescriptionTableActiveMedicationRequestsEndpoint(
pageOffset,
pageSize,
dayjs(new Date()).startOf('day').subtract(medicationRequestExpirationPeriodInDays, 'day').toISOString(),
patientSearchTerm,
location,
)
: getPrescriptionTableAllMedicationRequestsEndpoint(pageOffset, pageSize, patientSearchTerm, location)
: null,
openmrsFetch,
{ refreshInterval: refreshInterval },
);
Expand Down
58 changes: 58 additions & 0 deletions src/prescriptions/patient-search-tab-panel.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState } from 'react';
import { Button, Search, TabPanel } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { AppointmentsPictogram } from '@openmrs/esm-framework';
import PrescriptionsTable from './prescriptions-table.component';
import styles from './patient-search-tab-panel.scss';

const PatientSearchTabPanel: React.FC = () => {
const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState('');
const [submittedSearchTerm, setSubmittedSearchTerm] = useState('');

return (
<TabPanel>
<div className={styles.searchTabPanel}>
<form
className={styles.searchBar}
onSubmit={(e) => {
e.preventDefault();
setSubmittedSearchTerm(searchTerm);
}}>
<Search
closeButtonLabelText={t('clearSearchInput', 'Clear search input')}
defaultValue={searchTerm}
placeholder={t('searchForPatient', 'Search for a patient by name or identifier number')}
labelText={t('searchForPatient', 'Search for a patient by name or identifier number')}
onChange={(e) => {
setSearchTerm(e.target.value);
}}
onClear={() => setSubmittedSearchTerm('')}
size="lg"
/>
<Button kind="secondary" type="submit">
{t('search', 'Search')}
</Button>
</form>
{submittedSearchTerm ? (
<PrescriptionsTable
loadData={true}
status={'ACTIVE'}
debouncedSearchTerm={submittedSearchTerm}
location={''}
/>
) : (
<div className={styles.searchForPatientPlaceholder}>
<div>
<AppointmentsPictogram />
<h5>Search for a patient</h5>
<div>Search for a patient by name or identifier number</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot to include the translation strings for these

</div>
</div>
)}
</div>
</TabPanel>
);
};

export default PatientSearchTabPanel;
26 changes: 26 additions & 0 deletions src/prescriptions/patient-search-tab-panel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@use '@carbon/layout';
@use '~@openmrs/esm-styleguide/src/vars' as *;

.searchTabPanel {
display: flex;
flex-direction: column;
margin: layout.$spacing-05 layout.$spacing-04;
gap: layout.$spacing-05;
}

.searchForPatientPlaceholder {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
min-height: 400px;
flex: 1;
border: solid 1px $grey-2;
}

.searchBar {
input {
background-color: $ui-02;
}
display: flex;
}
73 changes: 9 additions & 64 deletions src/prescriptions/prescription-tab-lists.component.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import React, { useEffect, useState } from 'react';
import { ComboBox, Search, Tab, Tabs, TabList, TabPanels } from '@carbon/react';
import React, { useState } from 'react';
import { Tab, Tabs, TabList, TabPanels } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { useConfig } from '@openmrs/esm-framework';
import { useLocationForFiltering } from '../location/location.resource';
import { type SimpleLocation } from '../types';
import { type PharmacyConfig } from '../config-schema';
import PrescriptionTabPanel from './prescription-tab-panel.component';
import styles from './prescriptions.scss';
import PatientSearchTabPanel from './patient-search-tab-panel.component';

const PrescriptionTabLists: React.FC = () => {
const { t } = useTranslation();
const config = useConfig<PharmacyConfig>();
const { filterLocations, isLoading: isFilterLocationsLoading } = useLocationForFiltering(config);
const [searchTermUserInput, setSearchTermUserInput] = useState(''); // we have a separate "searchTermUserInput" and "searchTerm" in order to debounce
const [searchTerm, setSearchTerm] = useState('');
const [location, setLocation] = useState('');
const [selectedTab, setSelectedTab] = useState(0);

const tabs = [
Expand All @@ -30,16 +22,6 @@ const PrescriptionTabLists: React.FC = () => {
},
];

// debounce: delay the search term update so that a search isn't triggered on every single keystroke
useEffect(() => {
const debounceFn = setTimeout(() => {
setSearchTerm(searchTermUserInput);
}, 500);

return () => clearTimeout(debounceFn);
}, [searchTermUserInput]);

// we use this to only render the tab panel that is currently selected, see O3-2777
const handleTabChange = (event) => {
setSelectedTab(event.selectedIndex);
};
Expand All @@ -49,6 +31,9 @@ const PrescriptionTabLists: React.FC = () => {
<section className={styles.prescriptionTabsContainer}>
<Tabs onChange={handleTabChange}>
<TabList aria-label={t('tabList', 'Tab List')} contained className={styles.tabsContainer}>
<Tab title={t('search', 'Search')} id={'tab-search'} className={styles.tab}>
{t('search', 'Search')}
</Tab>
{tabs.map((tab, index) => {
return (
<Tab title={t(tab.key)} key={index} id={'tab-' + index} className={styles.tab}>
Expand All @@ -57,50 +42,10 @@ const PrescriptionTabLists: React.FC = () => {
);
})}
</TabList>
<div className={styles.searchContainer}>
{/* <Button
kind="primary"
renderIcon={(props) => <Add size={24} />}
className={styles.addPrescriptionBtn}
size="sm"
>
{t("fillPrescription", "Fill prescription")}
</Button>*/}
<Search
closeButtonLabelText={t('clearSearchInput', 'Clear search input')}
defaultValue={searchTermUserInput}
placeholder={t('searchByPatientIdOrName', 'Search by patient ID or name')}
labelText={t('searchByPatientIdOrName', 'Search by patient ID or name')}
onChange={(e) => {
e.preventDefault();
setSearchTermUserInput(e.target.value);
}}
size="md"
className={styles.patientSearch}
/>
{config.locationBehavior?.locationFilter?.enabled &&
!isFilterLocationsLoading &&
filterLocations?.length > 1 && (
<ComboBox
id="locationFilter"
placeholder={t('filterByLocation', 'Filter by location')}
items={isFilterLocationsLoading ? [] : filterLocations}
itemToString={(item: SimpleLocation) => item?.name}
onChange={({ selectedItem }) => {
setLocation(selectedItem?.id);
}}
className={styles.locationFilter}
/>
)}
</div>
<TabPanels>
{tabs.map((tab, index) => {
return index === selectedTab ? (
<PrescriptionTabPanel location={location} searchTerm={searchTerm} status={tab.status} />
) : (
<></>
);
})}
<PatientSearchTabPanel />
<PrescriptionTabPanel isTabActive={selectedTab === 1} status={'ACTIVE'} />
<PrescriptionTabPanel isTabActive={selectedTab === 2} status={''} />
</TabPanels>
</Tabs>
</section>
Expand Down
Loading
Loading