Skip to content

Commit

Permalink
(feat) O3-3243: Ward App - add configurable extension to include pati…
Browse files Browse the repository at this point in the history
…ent identifier (#1197)

* configure patient identifier

* correct config syntax

* fix test

---------

Co-authored-by: chibongho <[email protected]>
  • Loading branch information
kb019 and chibongho authored Jul 24, 2024
1 parent 7f7fe3c commit 80ef84c
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('QueueTable', () => {
renderWithSwr(<QueueTable queueEntries={mockQueueEntries} statusUuid={null} queueUuid={null} />);

for (const entry of mockQueueEntries) {
const patientName = entry.patient.display;
const patientName = entry.patient.person.display;
const row = screen.getByText(patientName).closest('tr');

expect(within(row).getByText(entry.status.display)).toBeInTheDocument();
Expand Down
45 changes: 43 additions & 2 deletions packages/esm-ward-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ const defaultWardPatientCard: WardPatientCardDefinition = {
rows: [
{
rowType: 'header',
elements: ['bed-number', 'patient-name', 'patient-age', 'patient-address'],
elements: ['bed-number', 'patient-name', 'patient-age', 'patient-address', 'patient-identifier'],
},
],
appliedTo: null,
};

const defaultPatientAddressFields: Array<keyof PersonAddress> = ['cityVillage', 'country'];

const defaultIdentifierTypeUuid = null;
const defaultLabel = null;
export const defaultPatientCardElementConfig: PatientCardElementConfig = {
address: {
addressFields: defaultPatientAddressFields,
},
obs: null,
identifier: {
identifierTypeUuid: defaultIdentifierTypeUuid,
},
codedObsTags: null,
};

Expand All @@ -27,6 +31,7 @@ export const builtInPatientCardElements: PatientCardElementType[] = [
'patient-name',
'patient-age',
'patient-address',
'patient-identifier',
];

export const configSchema: ConfigSchema = {
Expand Down Expand Up @@ -91,6 +96,25 @@ export const configSchema: ConfigSchema = {
_default: false,
},
},
identifier: {
_description: 'Config for the patientCardElementType "patient-identifier"',
identifierTypeUuid: {
_type: Type.UUID,
_description: 'The UUID of the identifier type to display',
_default: defaultIdentifierTypeUuid,
},
label: {
_type: Type.String,
_description:
'the custom label or i18n key to the translated label to display for patient identifier. If not provided, defaults to the patient-identifier name.',
_default: defaultLabel,
},
labelI18nModule: {
_type: Type.String,
_description: 'Optional. The custom module to use for translation of the label',
_default: null,
},
},
codedObsTags: {
_description: 'Config for the patientCardElementType "patient-coded-obs-tags"',
conceptUuid: {
Expand Down Expand Up @@ -251,6 +275,22 @@ export interface PatientObsElementConfig {
onlyWithinCurrentVisit?: boolean;
}

export interface PatientIdentifierElementConfig {
/**
* By default the preferred patient identifier is chosen,but
* if uuid is given the identifier corresponding to uuid is displayed
*/
identifierTypeUuid: string | null;
/**
* Optional. The custom label or i18n key to the translated label to display for patient identifier. If not provided, defaults to the patient-identifier name.
* (Note that this can be set to an empty string to not show a label)
*/
label?: string;
/**
* Optional. The custom module to use for translation of the label
*/
labelI18nModule?: string;
}
export interface PatientCodedObsTagsElementConfig {
/**
* Required. Identifies the concept to use to identify the desired observations.
Expand Down Expand Up @@ -298,5 +338,6 @@ export interface PatientCodedObsTagsElementConfig {
export type PatientCardElementConfig = {
address: PatientAddressElementConfig;
obs: PatientObsElementConfig;
identifier: PatientIdentifierElementConfig;
codedObsTags: PatientCodedObsTagsElementConfig;
};
1 change: 1 addition & 0 deletions packages/esm-ward-app/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const patientCardElementTypes = [
'patient-obs',
'patient-coded-obs-tags',
'admission-time',
'patient-identifier',
] as const;
export type PatientCardElementType = (typeof patientCardElementTypes)[number];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { type WardPatientCardElement } from '../../types';
import { type PatientCardElementConfig } from '../../config-schema';
import { Tag } from '@carbon/react';
import { translateFrom, type PatientIdentifier } from '@openmrs/esm-framework';
import { moduleName } from '../../constant';
import { useTranslation } from 'react-i18next';

//sort the identifiers by preferred first.The identifier with value of true
//takes precedence over false. if both identifiers have same preferred value
//sort them by (dateChanged or dateCreated) in descending order
const identifierCompareFunction = (pi1: PatientIdentifier, pi2: PatientIdentifier) => {
let comp = (pi2.preferred ? 1 : 0) - (pi1.preferred ? 1 : 0);

if (comp == 0) {
const date1 = pi1.auditInfo.dateChanged ?? pi1.auditInfo.dateCreated;
const date2 = pi2.auditInfo.dateChanged ?? pi2.auditInfo.dateCreated;
comp = date2.localeCompare(date1);
}
return comp;
};

const wardPatientIdentifier = (config: PatientCardElementConfig) => {
const WardPatientIdentifier: WardPatientCardElement = ({ patient }) => {
const { t } = useTranslation();
const { identifier } = config;
const { identifierTypeUuid, labelI18nModule: labelModule, label } = identifier;
const patientIdentifiers = patient.identifiers.filter(
(patientIdentifier: PatientIdentifier) =>
identifierTypeUuid == null || patientIdentifier.identifierType?.uuid === identifierTypeUuid,
);
patientIdentifiers.sort(identifierCompareFunction);
const patientIdentifier = patientIdentifiers[0];
const labelToDisplay =
label != null ? translateFrom(labelModule ?? moduleName, label) : patientIdentifier?.identifierType?.name;
return (
<div>
{labelToDisplay ? <Tag>{t('identifierTypelabel', '{{label}}:', { label: labelToDisplay })}</Tag> : <></>}
<span>{patientIdentifier?.identifier}</span>
</div>
);
};
return WardPatientIdentifier;
};

export default wardPatientIdentifier;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import styles from './ward-patient-card.scss';
import wardPatientObs from './row-elements/ward-patient-obs';
import wardPatientCodedObsTags from './row-elements/ward-patient-coded-obs-tags';

import wardPatientIdentifier from './row-elements/ward-patient-identifier';

export function usePatientCardRows(location: string) {
const { wardPatientCards } = useConfig<WardConfigObject>();
const patientCardRows = useMemo(() => {
Expand Down Expand Up @@ -85,6 +87,8 @@ function getPatientCardElementFromDefinition(
case 'patient-obs': {
return wardPatientObs(config.obs);
}
case 'patient-identifier':
return wardPatientIdentifier(config);
case 'patient-coded-obs-tags': {
return wardPatientCodedObsTags(config.codedObsTags);
}
Expand Down

0 comments on commit 80ef84c

Please sign in to comment.