Skip to content

Commit

Permalink
(feat) O3-3861 - ward app - add tooltip to obs to show encounter date (
Browse files Browse the repository at this point in the history
…#1312)

* (feat) O3-3861 - ward app - add tooltip to obs to show encounter date

* address PR comments
  • Loading branch information
chibongho authored Sep 18, 2024
1 parent 3a0f42b commit 6822458
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 209 deletions.
10 changes: 2 additions & 8 deletions packages/esm-ward-app/src/hooks/useMotherAndChildren.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
makeUrl,
restBaseUrl,
useOpenmrsFetchAll,
useOpenmrsInfinite,
useOpenmrsPagination,
} from '@openmrs/esm-framework';
import { makeUrl, restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
import { type MotherAndChildren } from '../types';

export interface MothersAndChildrenSearchCriteria {
Expand Down Expand Up @@ -44,7 +38,7 @@ export function useMotherAndChildren(
requireChildBornDuringMothersActiveVisit?.toString() ?? 'false',
);
rep && url.searchParams.append('v', rep);
return useOpenmrsPagination<MotherAndChildren>(fetch ? url : null, 50);
return useOpenmrsFetchAll<MotherAndChildren>(fetch ? url : null);
}

function makeUrlUrl(path: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const MotherChildRowExtension: WardPatientCard = ({ patient }) => {

if (isLoadingChildrenData || isLoadingMotherData) {
return (
<div className={wardPatientCardStyles.wardPatientCardRow}>
<div className={classNames(styles.motherOrBabyRow, wardPatientCardStyles.wardPatientCardRow)}>
<WardPatientSkeletonText />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
.motherOrBabyIcon {
padding: layout.$spacing-02;
border-radius: 50%;
fill: $ui-03;
background-color: $grey-2;
margin-right: layout.$spacing-03;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Tag } from '@carbon/react';
import { type OpenmrsResource, type Patient, type Visit } from '@openmrs/esm-framework';
import React from 'react';
import React, { type ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import { type ColoredObsTagsCardRowConfigObject } from '../../config-schema-extension-colored-obs-tags';
import { useObs } from '../../hooks/useObs';
import styles from '../ward-patient-card.scss';
import WardPatientSkeletonText from './ward-pateint-skeleton-text';
import { obsCustomRepresentation, useConceptToTagColorMap } from './ward-patient-obs.resource';
import { getObsEncounterString, obsCustomRepresentation, useConceptToTagColorMap } from './ward-patient-obs.resource';
import WardPatientResponsiveTooltip from './ward-patient-responsive-tooltip';

interface WardPatientCodedObsTagsProps {
config: ColoredObsTagsCardRowConfigObject;
Expand Down Expand Up @@ -44,31 +45,47 @@ const WardPatientCodedObsTags: React.FC<WardPatientCodedObsTagsProps> = ({ confi

const summaryLabelToDisplay = summaryLabel != null ? t(summaryLabel) : obsToDisplay?.[0]?.concept?.display;

const obsNodes = obsToDisplay?.map((o) => {
const { display, uuid } = o.value as OpenmrsResource;
// for each obs configured to be displayed with a color, we create a tag for it
// for other obs not configured, we create a single summary tag for all of them.
const summaryTagTooltipText: ReactNode[] = [];
const coloredOpsTags = obsToDisplay
?.map((o) => {
const { display, uuid } = o.value as OpenmrsResource;

const color = conceptToTagColorMap?.get(uuid);
if (color) {
return (
<Tag type={color} key={`ward-coded-obs-tag-${o.uuid}`}>
{display}
</Tag>
);
} else {
return null;
}
});
const color = conceptToTagColorMap?.get(uuid);
if (color) {
return (
<WardPatientResponsiveTooltip tooltipContent={getObsEncounterString(o, t)}>
<Tag type={color} key={`ward-coded-obs-tag-${o.uuid}`}>
{display}
</Tag>
</WardPatientResponsiveTooltip>
);
} else {
summaryTagTooltipText.push(
<div key={uuid}>
{display} ({getObsEncounterString(o, t)})
</div>,
);
return null;
}
})
.filter((o) => o != null);

const obsWithNoTagCount = obsNodes.filter((o) => o == null).length;
if (obsNodes?.length > 0 || obsWithNoTagCount > 0) {
if (coloredOpsTags?.length > 0 || summaryTagTooltipText.length > 0) {
return (
<div className={styles.wardPatientCardRow}>
<span className={styles.wardPatientObsLabel}>
{obsNodes}
{obsWithNoTagCount > 0 ? (
<Tag type={summaryLabelColor}>
{t('countItems', '{{count}} {{item}}', { count: obsWithNoTagCount, item: summaryLabelToDisplay })}
</Tag>
{coloredOpsTags}
{summaryTagTooltipText.length > 0 ? (
<WardPatientResponsiveTooltip tooltipContent={summaryTagTooltipText}>
<Tag type={summaryLabelColor}>
{t('countItems', '{{count}} {{item}}', {
count: summaryTagTooltipText.length,
item: summaryLabelToDisplay,
})}
</Tag>
</WardPatientResponsiveTooltip>
) : null}
</span>
</div>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { restBaseUrl, useOpenmrsFetchAll, type Concept } from '@openmrs/esm-framework';
import { type TagConfigObject } from '../../config-schema-extension-colored-obs-tags';
import { type Observation } from '../../types';
import { type TFunction } from 'i18next';

// prettier-ignore
export const obsCustomRepresentation =
'custom:(uuid,display,obsDatetime,value,' +
'concept:(uuid,display),' +
'encounter:(uuid,display,' +
'encounter:(uuid,display,encounterType,encounterDatetime,' +
'visit:(uuid,display)))';

// get the setMembers of a concept set
Expand Down Expand Up @@ -44,3 +46,11 @@ export function useConceptToTagColorMap(tags: Array<TagConfigObject>) {

return conceptToTagColorMap;
}

export function getObsEncounterString(obs: Observation, t: TFunction) {
return t('encounterDisplay', '{{encounterType}} {{encounterDate}}', {
encounterType: obs.encounter.encounterType.display,
encounterDate: new Date(obs.encounter.encounterDatetime).toLocaleDateString(),
interpolation: { escapeValue: false },
});
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { SkeletonText } from '@carbon/react';
import { type OpenmrsResource, type Patient, translateFrom, type Visit } from '@openmrs/esm-framework';
import { SkeletonText, Toggletip, ToggletipButton, ToggletipContent } from '@carbon/react';
import { Information } from '@carbon/react/icons';
import { type OpenmrsResource, type Patient, type Visit } from '@openmrs/esm-framework';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { type ObsElementDefinition } from '../../config-schema';
import { useObs } from '../../hooks/useObs';
import styles from '../ward-patient-card.scss';
import { moduleName } from '../../constant';
import { obsCustomRepresentation } from './ward-patient-obs.resource';
import { getObsEncounterString, obsCustomRepresentation } from './ward-patient-obs.resource';
import WardPatientResponsiveTooltip from './ward-patient-responsive-tooltip';

export interface WardPatientObsProps {
config: ObsElementDefinition;
Expand Down Expand Up @@ -37,7 +38,13 @@ const WardPatientObs: React.FC<WardPatientObsProps> = ({ config, patient, visit
const obsNodes = obsToDisplay?.map((o) => {
const { value } = o;
const display: any = (value as OpenmrsResource)?.display ?? o.value;
return <span key={o.uuid}> {display} </span>;

const tooltipContent = getObsEncounterString(o, t);
return (
<WardPatientResponsiveTooltip key={o.uuid} tooltipContent={tooltipContent}>
<span title={tooltipContent}>{display} </span>
</WardPatientResponsiveTooltip>
);
});

if (obsNodes?.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Toggletip, ToggletipButton, ToggletipContent, Tooltip } from '@carbon/react';
import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
import React, { type ReactNode } from 'react';
import styles from '../ward-patient-card.scss';

interface WardPatientResponsiveTooltipProps {
children: ReactNode;
tooltipContent: ReactNode;
}

/**
* This component acts as a Tooltip on desktop and a Toggletip on mobile.
*/
const WardPatientResponsiveTooltip: React.FC<WardPatientResponsiveTooltipProps> = ({ children, tooltipContent }) => {
const layout = useLayoutType();
if (isDesktop(layout)) {
return (
<Tooltip description={tooltipContent} className={styles.responsiveTooltip}>
{children}
</Tooltip>
);
} else {
return (
<Toggletip className={styles.responsiveTooltip}>
<ToggletipButton>{children}</ToggletipButton>
<ToggletipContent>{tooltipContent}</ToggletipContent>
</Toggletip>
);
}
};

export default WardPatientResponsiveTooltip;
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@

.wardPatientCardExtensionSlot {
display: none;
width: 100%;

&:has(div:not(:empty)) {
display: block;
Expand Down Expand Up @@ -157,6 +158,13 @@
padding-right: layout.$spacing-02;
}

.responsiveTooltip {
z-index: 2;
& :global(.cds--tag) {
border: 0;
}
}

.dotSeparatedChildren {
display: flex;
flex-wrap: wrap;
Expand Down
1 change: 1 addition & 0 deletions packages/esm-ward-app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"empty": "Empty",
"emptyBed": "Empty bed",
"emptyText": "Empty",
"encounterDisplay": "{{encounterType}} {{encounterDate}}",
"errorAssigningBedToPatient": "Error assigning bed to patient",
"errorCreatingEncounter": "Failed to admit patient",
"errorCreatingTransferRequest": "Error creating transfer request",
Expand Down
Loading

0 comments on commit 6822458

Please sign in to comment.