-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(feat) - O3-3222 - ward app - add patient card element to include ris…
…k factor obs within the current visi (#1211) * O3-3475 - ward app - update to use latest backend bed-management module * (feat) - O3-3222 - ward app - add patient card element to include risk factor obs within the current visit * wording changes in schema config * rename codedObs to codedObsTags * styling of bed divider and row divider lines in patient card
- Loading branch information
Showing
9 changed files
with
257 additions
and
20 deletions.
There are no files selected for viewing
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 |
---|---|---|
|
@@ -19,6 +19,6 @@ | |
|
||
.bedDividerLine { | ||
height: 1px; | ||
background-color: vars.$ui-03; | ||
background-color: vars.$ui-05; | ||
width: 30%; | ||
} |
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
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,11 @@ | ||
import { type Concept, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; | ||
import useSWRImmutable from 'swr/immutable'; | ||
|
||
export function useConcepts(uuids: string[], rep = 'default') { | ||
const apiUrl = `${restBaseUrl}/concept?references=${uuids.join()}&v=${rep}`; | ||
const { data, ...rest } = useSWRImmutable<{ data: { results: Array<Concept> } }, Error>(apiUrl, openmrsFetch); | ||
return { | ||
concepts: data?.data?.results, | ||
...rest, | ||
}; | ||
} |
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
80 changes: 80 additions & 0 deletions
80
packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-coded-obs-tags.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,80 @@ | ||
import { SkeletonText, Tag } from '@carbon/react'; | ||
import { translateFrom, type OpenmrsResource } from '@openmrs/esm-framework'; | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { type PatientCodedObsTagsElementConfig } from '../../config-schema'; | ||
import { moduleName } from '../../constant'; | ||
import { useObs } from '../../hooks/useObs'; | ||
import { type WardPatientCardElement } from '../../types'; | ||
import styles from '../ward-patient-card.scss'; | ||
import { obsCustomRepresentation, useConceptToTagColorMap } from './ward-patient-obs.resource'; | ||
|
||
/** | ||
* The WardPatientCodedObsTags displays observations of coded values of a particular concept in the active visit as tags. | ||
* Typically, these are taken from checkbox fields from a form. Each answer value can either be configured | ||
* to show as its own tag, or collapsed into a summary tag show the number of these values present. | ||
* | ||
* This is a rather specialized element; | ||
* for a more general display of obs value, use WardPatientObs instead. | ||
* @param config | ||
* @returns | ||
*/ | ||
const wardPatientCodedObsTags = (config: PatientCodedObsTagsElementConfig) => { | ||
const WardPatientCodedObsTags: WardPatientCardElement = ({ patient, visit }) => { | ||
const { conceptUuid, summaryLabel, summaryLabelColor, summaryLabelI18nModule } = config; | ||
const { data, isLoading } = useObs({ patient: patient.uuid, concept: conceptUuid }, obsCustomRepresentation); | ||
const { t } = useTranslation(); | ||
const { data: conceptToTagColorMap } = useConceptToTagColorMap(config); | ||
|
||
if (isLoading) { | ||
return <SkeletonText />; | ||
} else { | ||
const obsToDisplay = data?.data?.results?.filter((o) => { | ||
const matchVisit = o.encounter.visit?.uuid == visit?.uuid; | ||
return matchVisit || visit == null; // TODO: remove visit == null hack when server API supports returning visit | ||
}); | ||
|
||
const summaryLabelToDisplay = | ||
summaryLabel != null | ||
? translateFrom(summaryLabelI18nModule ?? moduleName, summaryLabel) | ||
: obsToDisplay?.[0]?.concept?.display; | ||
|
||
const obsNodes = obsToDisplay?.map((o) => { | ||
const { display, uuid } = o.value as OpenmrsResource; | ||
|
||
const color = conceptToTagColorMap?.get(uuid); | ||
if (color) { | ||
return ( | ||
<Tag type={color} key={uuid}> | ||
{display} | ||
</Tag> | ||
); | ||
} else { | ||
return null; | ||
} | ||
}); | ||
|
||
const obsWithNoTagCount = obsNodes.filter((o) => o == null).length; | ||
if (obsNodes?.length > 0 || obsWithNoTagCount > 0) { | ||
return ( | ||
<div> | ||
<span className={styles.wardPatientObsLabel}> | ||
{obsNodes} | ||
{obsWithNoTagCount > 0 ? ( | ||
<Tag type={summaryLabelColor}> | ||
{t('countItems', '{{count}} {{item}}', { count: obsWithNoTagCount, item: summaryLabelToDisplay })} | ||
</Tag> | ||
) : null} | ||
</span> | ||
</div> | ||
); | ||
} else { | ||
return null; | ||
} | ||
} | ||
}; | ||
|
||
return WardPatientCodedObsTags; | ||
}; | ||
|
||
export default wardPatientCodedObsTags; |
52 changes: 52 additions & 0 deletions
52
packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-obs.resource.ts
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,52 @@ | ||
import { openmrsFetch, restBaseUrl, type Concept } from '@openmrs/esm-framework'; | ||
import useSWRImmutable from 'swr/immutable'; | ||
import { type PatientCodedObsTagsElementConfig } from '../../config-schema'; | ||
|
||
// prettier-ignore | ||
export const obsCustomRepresentation = | ||
'custom:(uuid,display,obsDatetime,value,' + | ||
'concept:(uuid,display),' + | ||
'encounter:(uuid,display,' + | ||
'visit:(uuid,display)))'; | ||
|
||
// get the setMembers of a concept set | ||
const conceptSetCustomRepresentation = 'custom:(uuid,setMembers:(uuid))'; | ||
|
||
export function useConceptToTagColorMap(codedObsTagsConfig: PatientCodedObsTagsElementConfig) { | ||
// fetch the members of the concept sets and process the data | ||
// to return conceptToTagColorMap (wrapped in a promise). | ||
// Let swr cache the result of this function. | ||
const fetchAndMap = (url: string) => { | ||
const conceptSetToTagColorMap = new Map<string, string>(); | ||
for (const tag of codedObsTagsConfig.tags) { | ||
const { color, appliedToConceptSets } = tag; | ||
for (const answer of appliedToConceptSets ?? []) { | ||
if (!conceptSetToTagColorMap.has(answer)) { | ||
conceptSetToTagColorMap.set(answer, color); | ||
} | ||
} | ||
} | ||
|
||
return openmrsFetch<{ results: Array<Concept> }>(url).then((data) => { | ||
const conceptSets = data.data.results; | ||
const conceptToTagColorMap = new Map<string, string>(); | ||
if (conceptSets) { | ||
for (const conceptSet of conceptSets) { | ||
for (const concept of conceptSet.setMembers) { | ||
if (!conceptToTagColorMap.has(concept.uuid)) { | ||
conceptToTagColorMap.set(concept.uuid, conceptSetToTagColorMap.get(conceptSet.uuid)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return conceptToTagColorMap; | ||
}); | ||
}; | ||
|
||
const conceptSetUuids = codedObsTagsConfig.tags.flatMap((tag) => tag.appliedToConceptSets); | ||
const apiUrl = `${restBaseUrl}/concept?references=${conceptSetUuids.join()}&v=${conceptSetCustomRepresentation}`; | ||
const conceptToTagColorMap = useSWRImmutable(apiUrl, fetchAndMap); | ||
|
||
return conceptToTagColorMap; | ||
} |
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
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
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