Skip to content

Commit

Permalink
Merge branch 'main' into (fix)O3-O3-2662
Browse files Browse the repository at this point in the history
  • Loading branch information
jwnasambu authored Jan 16, 2024
2 parents dd7ad3c + dbb9f66 commit 6ee1e5a
Show file tree
Hide file tree
Showing 52 changed files with 1,356 additions and 768 deletions.
8 changes: 8 additions & 0 deletions packages/esm-form-engine-app/translations/zh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"closeThisPanel": "Close this panel",
"errorTitle": "There was an error with this form",
"loading": "Loading",
"or": "or",
"thisList": "this list",
"tryAgainMessage": "Try opening another form from"
}
8 changes: 8 additions & 0 deletions packages/esm-form-engine-app/translations/zh_CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"closeThisPanel": "Close this panel",
"errorTitle": "There was an error with this form",
"loading": "Loading",
"or": "or",
"thisList": "this list",
"tryAgainMessage": "Try opening another form from"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Button } from '@carbon/react';
import { showModal, toOmrsIsoString } from '@openmrs/esm-framework';
import placeholder from '../assets/placeholder.svg';
import { type UploadedFile } from '../attachments-types';
import styles from './capture-photo.scss';

export interface CapturePhotoProps {
onCapturePhoto(dataUri: string, photoDateTime: string): void;
Expand Down Expand Up @@ -31,9 +32,9 @@ const CapturePhoto: React.FC<CapturePhotoProps> = ({ initialState, onCapturePhot

return (
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{ maxWidth: '64px' }}>
<button type="button" onClick={showCam} className={styles.buttonCssReset}>
<img src={dataUri || initialState || placeholder} alt="Preview" style={{ width: '100%' }} />
</div>
</button>
<Button kind="ghost" onClick={showCam} style={{ flex: 1 }}>
{initialState ? t('changeImage', 'Change image') : t('addImage', 'Add image +')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.buttonCssReset {
max-width: 64px;
padding: 0;
margin: 0;
border: none;
background: none;
cursor: pointer;
}
18 changes: 7 additions & 11 deletions packages/esm-patient-banner-app/src/banner/patient-banner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from 'react';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { useConnectedExtensions } from '@openmrs/esm-framework';
import { mockPatient } from 'tools';
import PatientBanner from './patient-banner.component';
import { mockPatient } from 'tools';
import { defineConfigSchema, useConnectedExtensions } from '@openmrs/esm-framework';
import { configSchema } from '../config-schema';

defineConfigSchema('@openmrs/esm-patient-banner-app', configSchema);

class ResizeObserverMock {
callback: any;
Expand All @@ -27,17 +30,10 @@ const testProps = {
const mockNavigateTo = jest.fn();
const mockUseConnectedExtensions = useConnectedExtensions as jest.Mock;

jest.mock('@openmrs/esm-framework', () => ({
...(jest.requireActual('@openmrs/esm-framework') as any),
useVisit: jest.fn(),
age: jest.fn(),
Breakpoint: { TABLET_MAX: 1023 },
useConnectedExtensions: jest.fn(() => [{}, {}]),
}));

describe('PatientBanner: ', () => {
it('renders information about a patient in a banner above the patient chart', () => {
window.ResizeObserver = ResizeObserverMock;
mockUseConnectedExtensions.mockReturnValue([{ id: 'Some action extension' }]);

renderPatientBanner();

Expand All @@ -53,7 +49,7 @@ describe('PatientBanner: ', () => {
expect(screen.getByRole('button', { name: /^Show details$/i })).toBeInTheDocument();
});

it('shoulld not render actions menu if no actions connected', () => {
it('should not render actions menu if no actions connected', () => {
window.ResizeObserver = ResizeObserverMock;
mockUseConnectedExtensions.mockReturnValue([]); // override the default mock to one that returns an empty array

Expand Down
37 changes: 14 additions & 23 deletions packages/esm-patient-banner-app/src/config-schema.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
import { Type } from '@openmrs/esm-framework';

export const configSchema = {
contactAttributeType: {
_type: Type.UUID,
_description:
'The Uuids of person attribute-type that captures contact information `e.g Next of kin contact details`',
contactAttributeTypes: {
_type: Type.Array,
_description: 'The UUIDs of person attribute types that capture contact information',
_default: [],
_elements: {
_type: Type.UUID,
},
},
excludePatientIdentifierCodeTypes: {
uuids: {
_type: Type.Array,
_description: 'The Uuids of patient identifier types that should be excluded from patient banner.',
_description: 'The UUIDs of patient identifier types that should be excluded from patient banner.',
_default: [],
},
},
useCustomAddressLabel: {
enabled: {
_type: Type.Boolean,
_description: 'whether to enable using custom address labels',
_default: false,
},
customAddressLabel: {
_type: Type.Object,
_description: 'custom labels for addresses',
_default: {},
_elements: {
_type: Type.UUID,
},
},
},
useRelationshipNameLink: {
_type: Type.Boolean,
_description: 'Enable the use of a link to the patient chart in relationship names',
_description: "Whether to use the relationship name as a link to the person's patient chart",
_default: false,
},
};

export interface ConfigObject {
contactAttributeType: Array<string>;
useCustomAddressLabel: {
enabled: boolean;
customAddressLabel: Object;
};
contactAttributeTypes: Array<string>;
excludePatientIdentifierCodeTypes: Array<String>;
customAddressLabels: Object;
useRelationshipNameLink: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { InlineLoading } from '@carbon/react';
import { ConfigurableLink, parseDate, useConfig } from '@openmrs/esm-framework';
import { type ConfigObject } from '../config-schema';
import { useRelationships } from './relationships.resource';
import { usePatientContactAttributes } from '../hooks/usePatientAttributes';
import { usePatientListsForPatient } from '../hooks/usePatientListsForPatient';
import styles from './contact-details.scss';
import { type ConfigObject } from '../config-schema';

interface ContactDetailsProps {
address: Array<fhir.Address>;
Expand Down Expand Up @@ -62,10 +62,6 @@ const PatientLists: React.FC<{ patientUuid: string }> = ({ patientUuid }) => {

const Address: React.FC<{ address?: fhir.Address }> = ({ address }) => {
const { t } = useTranslation();
const { useCustomAddressLabel } = useConfig<ConfigObject>();
const useCustomAddressLabelEnabled = useCustomAddressLabel?.enabled;
const customAddressLabel = useCustomAddressLabel?.customAddressLabel;

const getAddressKey = (url) => url.split('#')[1];
/*
DO NOT REMOVE THIS COMMENT UNLESS YOU UNDERSTAND WHY IT IS HERE
Expand All @@ -90,20 +86,19 @@ const Address: React.FC<{ address?: fhir.Address }> = ({ address }) => {
{address ? (
<React.Fragment>
{Object.entries(address)
.filter(([key]) => !['use', 'id'].some((k) => k === key))
.filter(([key]) => !['use', 'id'].includes(key))
.map(([key, value]) =>
key === 'extension' ? (
address?.extension[0]?.extension.map((add, i) => (
<li key={`address-${key}-${i}`}>
{useCustomAddressLabelEnabled
? t(customAddressLabel[getAddressKey(add.url)])
: t(getAddressKey(add.url))}
: {add.valueString}
</li>
))
address?.extension[0]?.extension.map((add, i) => {
return (
<li key={`address-${key}-${i}`}>
{t(getAddressKey(add.url), getAddressKey(add.url))}: {add.valueString}
</li>
);
})
) : (
<li key={`address-${key}`}>
{useCustomAddressLabelEnabled ? t(customAddressLabel[key]) : t(key)}: {value}
{t(key, key)}: {value}
</li>
),
)}
Expand All @@ -121,26 +116,32 @@ const Contact: React.FC<{ telecom: Array<fhir.ContactPoint>; patientUuid: string
patientUuid,
}) => {
const { t } = useTranslation();
const value = telecom?.length ? telecom[0].value : '--';
const { isLoading, contactAttributes } = usePatientContactAttributes(patientUuid);

const contacts = useMemo(
() => [
...telecom?.map((contact) => [t(contact.system, contact.system), contact.value]),
...contactAttributes?.map((contact) => [
t(contact.attributeType.display, contact.attributeType.display),
contact.value,
]),
],
[telecom, contactAttributes],
);

return (
<>
<p className={styles.heading}>{t('contactDetails', 'Contact Details')}</p>
{isLoading ? (
<InlineLoading description={`${t('loading', 'Loading')} ...`} role="progressbar" />
) : (
<ul>
{value ? (
<React.Fragment>
<li>{value}</li>
{contactAttributes?.length > 0 &&
contactAttributes.map(({ attributeType, value, uuid }) => (
<li key={uuid}>
{attributeType.display}: {value}
</li>
))}
</React.Fragment>
{contacts.length ? (
contacts.map(([label, value], index) => (
<li key={`${label}-${value}-${index}`}>
{label}: {value}
</li>
))
) : (
<li>--</li>
)}
Expand All @@ -153,16 +154,7 @@ const Contact: React.FC<{ telecom: Array<fhir.ContactPoint>; patientUuid: string
const Relationships: React.FC<{ patientId: string }> = ({ patientId }) => {
const { t } = useTranslation();
const { data: relationships, isLoading } = useRelationships(patientId);
const config = useConfig();

const extractName = (display: string) => {
const pattern = /-\s*(.*)$/;
const match = display.match(pattern);
if (match && match.length > 1) {
return match[1].trim();
}
return display.trim();
};
const config = useConfig<ConfigObject>();

return (
<>
Expand All @@ -183,7 +175,7 @@ const Relationships: React.FC<{ patientId: string }> = ({ patientId }) => {
{r.display}
</ConfigurableLink>
) : (
<div>{extractName(r.display)}</div>
<div>{r.name}</div>
)}

<div>{r.relationshipType}</div>
Expand Down
Loading

0 comments on commit 6ee1e5a

Please sign in to comment.