-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from FelixKiprotich350/main
(feat) intial UI design and population of prescribed medical supplies which are non drugs
- Loading branch information
Showing
53 changed files
with
8,191 additions
and
40 deletions.
There are no files selected for viewing
91 changes: 91 additions & 0 deletions
91
packages/esm-medical-supply-dispensing-app/src/components/action-buttons.component.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { render } from '@testing-library/react'; | ||
import React from 'react'; | ||
import ActionButtons from './action-buttons.component'; | ||
import { type MedicationRequest, MedicationRequestStatus, NonDrugMedicationDispense } from '../types'; | ||
import { toDateObjectStrict, useConfig } from '@openmrs/esm-framework'; | ||
import { date } from 'zod'; | ||
|
||
const mockedUseConfig = useConfig as jest.Mock; | ||
const mockPatientUuid = '558494fe-5850-4b34-a3bf-06550334ba4a'; | ||
const mockEncounterUuid = '7aee7123-9e50-4f72-a636-895d77a63e98'; | ||
|
||
describe('Action Buttons Component tests', () => { | ||
beforeEach(() => { | ||
mockedUseConfig.mockReturnValue({ | ||
medicationRequestExpirationPeriodInDays: 90, | ||
actionButtons: { | ||
pauseButton: { | ||
enabled: true, | ||
}, | ||
closeButton: { | ||
enabled: true, | ||
}, | ||
}, | ||
dispenseBehavior: { | ||
allowModifyingPrescription: false, | ||
restrictTotalQuantityDispensed: false, | ||
}, | ||
}); | ||
}); | ||
|
||
test('component should render dispense button if active medication', () => { | ||
// status = active, and validity period start set to current datetime | ||
const medicationRequest: NonDrugMedicationDispense = { | ||
uuid: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
patient: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
encounter: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
dispensingUnit: { uuid: 'd4f69a68-1171-4e47-8693-478df18daf40', display: 'Test' }, | ||
quantity: 2, | ||
display: 'test ', | ||
instrucions: 'test', | ||
status: '', | ||
medicalSupplyOrder: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
concept: '', | ||
dateDispensed: new Date(), | ||
statusReason: '', | ||
location: '', | ||
encounters: '', | ||
dispenser: '', | ||
}; | ||
|
||
const { getByText, container } = render( | ||
<ActionButtons | ||
patientUuid={mockPatientUuid} | ||
encounterUuid={mockEncounterUuid} | ||
medicationDispense={medicationRequest} | ||
/>, | ||
); | ||
expect(getByText('Dispense')).toBeInTheDocument(); | ||
}); | ||
|
||
// status = active, but validity period start time years in the past | ||
test('component should not render dispense button if expired medication', () => { | ||
// status = active, and validity period start set to current datetime | ||
const medicationRequest: NonDrugMedicationDispense = { | ||
uuid: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
patient: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
encounter: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
dispensingUnit: { uuid: 'd4f69a68-1171-4e47-8693-478df18daf40', display: 'Test' }, | ||
quantity: 2, | ||
display: 'test ', | ||
instrucions: 'test', | ||
status: '', | ||
medicalSupplyOrder: 'd4f69a68-1171-4e47-8693-478df18daf40', | ||
concept: '', | ||
dateDispensed: new Date(), | ||
statusReason: '', | ||
location: '', | ||
encounters: '', | ||
dispenser: '', | ||
}; | ||
|
||
const { queryByText, container } = render( | ||
<ActionButtons | ||
patientUuid={mockPatientUuid} | ||
encounterUuid={mockEncounterUuid} | ||
medicationDispense={medicationRequest} | ||
/>, | ||
); | ||
// expect(queryByText('Dispense')).not.toBeInTheDocument(); | ||
}); | ||
}); |
83 changes: 83 additions & 0 deletions
83
packages/esm-medical-supply-dispensing-app/src/components/action-buttons.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react'; | ||
import { Button } from '@carbon/react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { useConfig, useSession } from '@openmrs/esm-framework'; | ||
import { | ||
MedicationDispenseStatus, | ||
type MedicationRequestBundle, | ||
MedicationRequestStatus, | ||
NonDrugMedicationDispense, | ||
} from '../types'; | ||
import { launchOverlay } from '../hooks/useOverlay'; | ||
import { | ||
computeMedicationRequestStatus, | ||
computeQuantityRemaining, | ||
getMostRecentMedicationDispenseStatus, | ||
} from '../utils'; | ||
import { type PharmacyConfig } from '../config-schema'; | ||
import { initiateMedicationDispenseBody, useProviders } from '../medication-dispense/medication-dispense.resource'; | ||
import DispenseForm from '../forms/dispense-form.component'; | ||
import PauseDispenseForm from '../forms/pause-dispense-form.component'; | ||
import CloseDispenseForm from '../forms/close-dispense-form.component'; | ||
import styles from './action-buttons.scss'; | ||
|
||
interface ActionButtonsProps { | ||
patientUuid: string; | ||
encounterUuid: string; | ||
medicationDispense: NonDrugMedicationDispense; | ||
} | ||
|
||
const ActionButtons: React.FC<ActionButtonsProps> = ({ patientUuid, encounterUuid, medicationDispense }) => { | ||
const { t } = useTranslation(); | ||
const config = useConfig<PharmacyConfig>(); | ||
const session = useSession(); | ||
const providers = useProviders(config.dispenserProviderRoles); | ||
|
||
return ( | ||
<div className={styles.actionBtns}> | ||
{medicationDispense.uuid ? ( | ||
<Button | ||
kind="primary" | ||
onClick={() => | ||
launchOverlay( | ||
t('dispensePrescription', 'Dispense prescription'), | ||
<DispenseForm | ||
patientUuid={patientUuid} | ||
encounterUuid={encounterUuid} | ||
medicationDispense={medicationDispense} | ||
mode="enter" | ||
/>, | ||
) | ||
}> | ||
{t('dispense', 'Dispense')} | ||
</Button> | ||
) : null} | ||
{medicationDispense.uuid ? ( | ||
<Button | ||
kind="secondary" | ||
onClick={() => | ||
launchOverlay( | ||
t('pausePrescription', 'Pause prescription'), | ||
<PauseDispenseForm patientUuid={patientUuid} encounterUuid={encounterUuid} mode="enter" />, | ||
) | ||
}> | ||
{t('pause', 'Pause')} | ||
</Button> | ||
) : null} | ||
{medicationDispense.uuid ? ( | ||
<Button | ||
kind="danger" | ||
onClick={() => | ||
launchOverlay( | ||
t('closePrescription', 'Close prescription'), | ||
<CloseDispenseForm patientUuid={patientUuid} encounterUuid={encounterUuid} mode="enter" />, | ||
) | ||
}> | ||
{t('close', 'Close')} | ||
</Button> | ||
) : null} | ||
</div> | ||
); | ||
}; | ||
|
||
export default ActionButtons; |
5 changes: 5 additions & 0 deletions
5
packages/esm-medical-supply-dispensing-app/src/components/action-buttons.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.actionBtns { | ||
float: right; | ||
margin-left: 1rem; | ||
margin-top: 2rem; | ||
} |
36 changes: 36 additions & 0 deletions
36
packages/esm-medical-supply-dispensing-app/src/components/medication-card.component.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
import { type MedicationReferenceOrCodeableConcept } from '../types'; | ||
import MedicationCard from './medication-card.component'; | ||
|
||
describe('Medication Card Component tests', () => { | ||
test('component should render medication card without edit action button', () => { | ||
const medication: MedicationReferenceOrCodeableConcept = { | ||
medicationReference: { | ||
display: 'Some Medication', | ||
reference: '', | ||
type: '', | ||
}, | ||
}; | ||
|
||
const { getByText, container } = render(<MedicationCard medication={medication} />); | ||
expect(getByText('Some Medication')).toBeInTheDocument(); | ||
expect(container.querySelector('svg')).not.toBeInTheDocument(); | ||
}); | ||
|
||
test('component should render medication card with edit action button', () => { | ||
const medication: MedicationReferenceOrCodeableConcept = { | ||
medicationReference: { | ||
display: 'Some Medication', | ||
reference: '', | ||
type: '', | ||
}, | ||
}; | ||
|
||
const action = () => 0; | ||
|
||
const { getByText, container } = render(<MedicationCard medication={medication} editAction={action} />); | ||
expect(getByText('Some Medication')).toBeInTheDocument(); | ||
expect(container.querySelector('svg')).toBeInTheDocument(); | ||
}); | ||
}); |
22 changes: 22 additions & 0 deletions
22
packages/esm-medical-supply-dispensing-app/src/components/medication-card.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React, { ReactSVGElement } from 'react'; | ||
import { Tile } from '@carbon/react'; | ||
import { Edit } from '@carbon/react/icons'; | ||
import { type MedicationReferenceOrCodeableConcept } from '../types/index'; | ||
import styles from './medication-card.scss'; | ||
import { getMedicationDisplay } from '../utils'; | ||
|
||
const MedicationCard: React.FC<{ | ||
medication: MedicationReferenceOrCodeableConcept; | ||
editAction?: Function; | ||
}> = ({ medication, editAction }) => { | ||
return ( | ||
<Tile className={styles.medicationTile}> | ||
<p className={styles.medicationName}> | ||
<strong>{getMedicationDisplay(medication)}</strong> | ||
</p> | ||
{editAction && <Edit onClick={editAction as React.MouseEventHandler<ReactSVGElement>} />} | ||
</Tile> | ||
); | ||
}; | ||
|
||
export default MedicationCard; |
20 changes: 20 additions & 0 deletions
20
packages/esm-medical-supply-dispensing-app/src/components/medication-card.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
@use '@carbon/styles/scss/spacing'; | ||
@use '@carbon/styles/scss/type'; | ||
@import '~@openmrs/esm-styleguide/src/vars'; | ||
|
||
.medicationTile { | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
width: 100%; | ||
margin: 2px 0 8px; | ||
padding: 0 8px 0 8px; | ||
background-color: #fff; | ||
border-left: 4px solid var(--brand-03); | ||
color: $text-02; | ||
margin-bottom: 1rem !important; | ||
} | ||
|
||
.medicationName { | ||
font-size: 15px !important; | ||
} |
95 changes: 95 additions & 0 deletions
95
packages/esm-medical-supply-dispensing-app/src/components/medication-dispense-review.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
@use '@carbon/styles/scss/spacing'; | ||
@use '@carbon/styles/scss/type'; | ||
@import '~@openmrs/esm-styleguide/src/vars'; | ||
|
||
.medicationDispenseReviewContainer { | ||
display: flex; | ||
flex-direction: column; | ||
padding-bottom: 10px; | ||
|
||
:global(.cds--css-grid) { | ||
padding-left: 0 !important; | ||
padding-right: 0 !important; | ||
} | ||
} | ||
|
||
.dispenseDetailsContainer { | ||
display: flex; | ||
flex-direction: row; | ||
flex: 1; | ||
gap: spacing.$spacing-05; | ||
} | ||
|
||
.substitutionReason { | ||
width: 100%; | ||
} | ||
|
||
.substitutionType { | ||
width: 100%; | ||
} | ||
|
||
.productiveHeading02 { | ||
color: $color-gray-70; | ||
@include type.type-style('productive-heading-02'); | ||
} | ||
|
||
:global(.omrs-breakpoint-lt-desktop) .formWrapper { | ||
background-color: $openmrs-background-grey; | ||
} | ||
|
||
:global(.omrs-breakpoint-gt-tablet) .formWrapper { | ||
background-color: $ui-02; | ||
} | ||
|
||
.formGroup { | ||
display: flex; | ||
margin-bottom: spacing.$spacing-02; | ||
padding: spacing.$spacing-05; | ||
} | ||
|
||
:global(.omrs-breakpoint-lt-desktop) .formGroup > span { | ||
flex: 1; | ||
} | ||
|
||
:global(.omrs-breakpoint-lt-desktop) .formGroup > div { | ||
flex: 3; | ||
} | ||
|
||
.formGroup span { | ||
@extend .productiveHeading02; | ||
} | ||
|
||
.patientInfo { | ||
position: sticky; | ||
z-index: 1000; | ||
background-color: $ui-02; | ||
top: 3rem; | ||
overflow-y: auto; | ||
} | ||
|
||
:global(.omrs-breakpoint-lt-desktop) .formGroup { | ||
flex-direction: row; | ||
} | ||
|
||
:global(.omrs-breakpoint-gt-tablet) .formGroup { | ||
flex-direction: column; | ||
} | ||
|
||
.buttonGroup { | ||
display: flex; | ||
position: sticky; | ||
bottom: 0; | ||
width: 100%; | ||
} | ||
|
||
:global(.omrs-breakpoint-lt-desktop) .buttonGroup { | ||
padding: spacing.$spacing-05 spacing.$spacing-06; | ||
background-color: $ui-02; | ||
} | ||
|
||
.buttonGroup button { | ||
max-width: none; | ||
width: 50%; | ||
height: spacing.$spacing-10; | ||
align-items: flex-start; | ||
} |
36 changes: 36 additions & 0 deletions
36
packages/esm-medical-supply-dispensing-app/src/components/medication-event.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react'; | ||
import { | ||
NonDrugDispensingUnit, | ||
NonDrugMedicationDispense, | ||
type DosageInstruction, | ||
type MedicationDispense, | ||
type MedicationRequest, | ||
type Quantity, | ||
} from '../types'; | ||
import styles from './medication-event.scss'; | ||
|
||
import { useTranslation } from 'react-i18next'; | ||
|
||
// can render MedicationRequest or MedicationDispense | ||
const MedicationEvent: React.FC<{ medicationDispense: NonDrugMedicationDispense }> = ({ medicationDispense }) => { | ||
const { t } = useTranslation(); | ||
|
||
return ( | ||
<div> | ||
<p className={styles.medicationName}> | ||
<strong>{medicationDispense.display}</strong> | ||
</p> | ||
|
||
<p className={styles.bodyLong01}> | ||
<span className={styles.label01}>{t('quantity', 'Quantity').toUpperCase()}</span>{' '} | ||
<span className={styles.quantity}> : {String(medicationDispense.quantity)} </span> | ||
</p> | ||
<p className={styles.bodyLong01}> | ||
<span className={styles.label01}>{t('dispenseUnit', 'Dispense Unit').toUpperCase()}</span>{' '} | ||
<span className={styles.quantity}> : {String(medicationDispense.dispensingUnit?.display)}</span> | ||
</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MedicationEvent; |
Oops, something went wrong.