-
+
+
diff --git a/packages/esm-patient-attachments-app/src/camera-media-uploader/capture-photo.scss b/packages/esm-patient-attachments-app/src/camera-media-uploader/capture-photo.scss
new file mode 100644
index 0000000000..c11b1227ea
--- /dev/null
+++ b/packages/esm-patient-attachments-app/src/camera-media-uploader/capture-photo.scss
@@ -0,0 +1,8 @@
+.buttonCssReset {
+ max-width: 64px;
+ padding: 0;
+ margin: 0;
+ border: none;
+ background: none;
+ cursor: pointer;
+}
diff --git a/packages/esm-patient-banner-app/src/banner/patient-banner.test.tsx b/packages/esm-patient-banner-app/src/banner/patient-banner.test.tsx
index bc1ef838e8..ac1220e9e4 100644
--- a/packages/esm-patient-banner-app/src/banner/patient-banner.test.tsx
+++ b/packages/esm-patient-banner-app/src/banner/patient-banner.test.tsx
@@ -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;
@@ -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();
@@ -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
diff --git a/packages/esm-patient-banner-app/src/config-schema.ts b/packages/esm-patient-banner-app/src/config-schema.ts
index 66c69203a9..07e11570ae 100644
--- a/packages/esm-patient-banner-app/src/config-schema.ts
+++ b/packages/esm-patient-banner-app/src/config-schema.ts
@@ -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
;
- useCustomAddressLabel: {
- enabled: boolean;
- customAddressLabel: Object;
- };
+ contactAttributeTypes: Array;
+ excludePatientIdentifierCodeTypes: Array;
+ customAddressLabels: Object;
useRelationshipNameLink: boolean;
}
diff --git a/packages/esm-patient-banner-app/src/contact-details/contact-details.component.tsx b/packages/esm-patient-banner-app/src/contact-details/contact-details.component.tsx
index 7c6891ea39..478606ddd5 100644
--- a/packages/esm-patient-banner-app/src/contact-details/contact-details.component.tsx
+++ b/packages/esm-patient-banner-app/src/contact-details/contact-details.component.tsx
@@ -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;
@@ -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();
- 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
@@ -90,20 +86,19 @@ const Address: React.FC<{ address?: fhir.Address }> = ({ address }) => {
{address ? (
{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) => (
-
- {useCustomAddressLabelEnabled
- ? t(customAddressLabel[getAddressKey(add.url)])
- : t(getAddressKey(add.url))}
- : {add.valueString}
-
- ))
+ address?.extension[0]?.extension.map((add, i) => {
+ return (
+
+ {t(getAddressKey(add.url), getAddressKey(add.url))}: {add.valueString}
+
+ );
+ })
) : (
- {useCustomAddressLabelEnabled ? t(customAddressLabel[key]) : t(key)}: {value}
+ {t(key, key)}: {value}
),
)}
@@ -121,9 +116,19 @@ const Contact: React.FC<{ telecom: Array; 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 (
<>
{t('contactDetails', 'Contact Details')}
@@ -131,16 +136,12 @@ const Contact: React.FC<{ telecom: Array; patientUuid: string
) : (
- {value ? (
-
- - {value}
- {contactAttributes?.length > 0 &&
- contactAttributes.map(({ attributeType, value, uuid }) => (
- -
- {attributeType.display}: {value}
-
- ))}
-
+ {contacts.length ? (
+ contacts.map(([label, value], index) => (
+ -
+ {label}: {value}
+
+ ))
) : (
- --
)}
@@ -153,16 +154,7 @@ const Contact: React.FC<{ telecom: Array; 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();
return (
<>
@@ -183,7 +175,7 @@ const Relationships: React.FC<{ patientId: string }> = ({ patientId }) => {
{r.display}
) : (
- {extractName(r.display)}
+ {r.name}
)}
{r.relationshipType}
diff --git a/packages/esm-patient-banner-app/src/contact-details/contact-details.test.tsx b/packages/esm-patient-banner-app/src/contact-details/contact-details.test.tsx
index 1819102e30..25d6560895 100644
--- a/packages/esm-patient-banner-app/src/contact-details/contact-details.test.tsx
+++ b/packages/esm-patient-banner-app/src/contact-details/contact-details.test.tsx
@@ -1,14 +1,19 @@
import React from 'react';
import { screen } from '@testing-library/react';
-import { openmrsFetch } from '@openmrs/esm-framework';
import { renderWithSwr, waitForLoadingToFinish } from 'tools';
import { usePatientAttributes, usePatientContactAttributes } from '../hooks/usePatientAttributes';
import { usePatientListsForPatient } from '../hooks/usePatientListsForPatient';
+import { useRelationships } from './relationships.resource';
import ContactDetails from './contact-details.component';
+import { defineConfigSchema } from '@openmrs/esm-framework';
+import { configSchema } from '../config-schema';
+
+defineConfigSchema('@openmrs/esm-patient-banner-app', configSchema);
const mockedUsePatientAttributes = usePatientAttributes as jest.Mock;
const mockedUsePatientContactAttributes = usePatientContactAttributes as jest.Mock;
const mockUsePatientListsForPatient = usePatientListsForPatient as jest.Mock;
+const mockUseRelationships = useRelationships as jest.Mock;
const testProps = {
address: [
@@ -21,7 +26,7 @@ const testProps = {
use: 'home',
},
],
- telecom: [{ value: '+0123456789' }],
+ telecom: [{ system: 'Cellular', value: '+0123456789' }],
patientId: '1111',
deceased: false,
isTabletViewport: false,
@@ -29,25 +34,12 @@ const testProps = {
const mockRelationships = [
{
- display: 'Amanda is the Sibling of John',
+ display: '100ADT - Amanda Robinson',
+ name: 'Amanda Robinson',
+ relationshipType: 'Sibling',
+ relativeAge: 24,
+ relativeUuid: '07006bcb-91d4-4c57-a5f7-49751899d9b5',
uuid: '993bc79d-5ca5-4c76-b4b3-adf49e25bd0b',
- personA: {
- uuid: '07006bcb-91d4-4c57-a5f7-49751899d9b5',
- display: '100ADT - Amanda Robinson',
- age: 24,
- },
- personB: {
- uuid: '8673ee4f-e2ab-4077-ba55-4980f408773e',
- display: '100GEJ - John Wilson',
- age: 49,
- },
- relationshipType: {
- uuid: '8d91a01c-c2cc-11de-8d13-0010c6dffd0f',
- display: 'Sibling/Sibling',
- description: 'Relationship between brother/sister, brother/brother, and sister/sister',
- aIsToB: 'Sibling',
- bIsToA: 'Sibling',
- },
},
];
@@ -89,7 +81,6 @@ const mockCohorts = [
endDate: null,
},
];
-const mockOpenmrsFetch = openmrsFetch as jest.Mock;
jest.mock('../hooks/usePatientAttributes', () => ({
usePatientAttributes: jest.fn(),
@@ -100,25 +91,46 @@ jest.mock('../hooks/usePatientListsForPatient', () => ({
usePatientListsForPatient: jest.fn(),
}));
+jest.mock('./relationships.resource', () => ({
+ useRelationships: jest.fn(),
+}));
+
describe('ContactDetails', () => {
- it("renders the patient's address, contact details, patient lists, and relationships when available", async () => {
+ afterEach(() => {
mockedUsePatientAttributes.mockReturnValue({
isLoading: false,
attributes: [],
error: null,
});
+ mockedUsePatientContactAttributes.mockReturnValue({
+ isLoading: false,
+ contactAttributes: [],
+ });
+ mockUsePatientListsForPatient.mockReturnValue({
+ isLoading: false,
+ cohorts: [],
+ });
+ mockUseRelationships.mockReturnValue({
+ isLoading: false,
+ data: [],
+ });
+ });
- mockedUsePatientContactAttributes.mockReturnValueOnce({
+ it("renders the patient's address, contact details, patient lists, and relationships when available", async () => {
+ mockedUsePatientContactAttributes.mockReturnValue({
isLoading: false,
contactAttributes: mockPersonAttributes,
});
- mockUsePatientListsForPatient.mockReturnValueOnce({
+ mockUsePatientListsForPatient.mockReturnValue({
isLoading: false,
cohorts: mockCohorts,
});
- mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockRelationships } });
+ mockUseRelationships.mockReturnValue({
+ isLoading: false,
+ data: mockRelationships,
+ });
renderContactDetails();
@@ -139,18 +151,15 @@ describe('ContactDetails', () => {
});
it('renders the contact details with 2 columns if banner width is small', async () => {
- mockedUsePatientAttributes.mockReturnValue({
- isLoading: false,
- attributes: [],
- error: null,
- });
-
mockedUsePatientContactAttributes.mockReturnValueOnce({
isLoading: false,
contactAttributes: mockPersonAttributes,
});
- mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockRelationships } });
+ mockUseRelationships.mockReturnValue({
+ isLoading: false,
+ data: mockRelationships,
+ });
mockUsePatientListsForPatient.mockReturnValueOnce({
isLoading: false,
@@ -175,12 +184,6 @@ describe('ContactDetails', () => {
});
it('renders the contact details with 4 colummns if banner width is large', async () => {
- mockedUsePatientAttributes.mockReturnValue({
- isLoading: false,
- attributes: [],
- error: null,
- });
-
mockedUsePatientContactAttributes.mockReturnValueOnce({
isLoading: false,
contactAttributes: mockPersonAttributes,
@@ -191,7 +194,11 @@ describe('ContactDetails', () => {
cohorts: mockCohorts,
});
- mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockRelationships } });
+ mockUseRelationships.mockReturnValue({
+ isLoading: false,
+ data: mockRelationships,
+ });
+
const props = { ...testProps, isTabletViewport: false };
const { container } = renderWithSwr();
@@ -210,32 +217,8 @@ describe('ContactDetails', () => {
});
it('renders an empty state view when contact details, relations, patient lists and addresses are not available', async () => {
- mockedUsePatientAttributes.mockReturnValue({
- isLoading: false,
- attributes: [],
- error: null,
- });
-
- mockedUsePatientContactAttributes.mockReturnValueOnce({
- isLoading: false,
- contactAttributes: [],
- });
-
- mockUsePatientListsForPatient.mockReturnValueOnce({
- isLoading: false,
- cohorts: [],
- });
-
- mockOpenmrsFetch.mockReturnValueOnce({ data: { results: [] } });
-
renderWithSwr(
- ,
+ ,
);
await waitForLoadingToFinish();
diff --git a/packages/esm-patient-banner-app/src/contact-details/relationships.resource.tsx b/packages/esm-patient-banner-app/src/contact-details/relationships.resource.tsx
index daee9045f1..d436306d87 100644
--- a/packages/esm-patient-banner-app/src/contact-details/relationships.resource.tsx
+++ b/packages/esm-patient-banner-app/src/contact-details/relationships.resource.tsx
@@ -33,6 +33,7 @@ function extractRelationshipData(
if (patientIdentifier === r.personA.uuid) {
relationshipsData.push({
uuid: r.uuid,
+ name: extractName(r.personB.display),
display: r.personB.display,
relativeAge: r.personB.age,
relativeUuid: r.personB.uuid,
@@ -41,6 +42,7 @@ function extractRelationshipData(
} else {
relationshipsData.push({
uuid: r.uuid,
+ name: extractName(r.personA.display),
display: r.personA.display,
relativeAge: r.personA.age,
relativeUuid: r.personA.uuid,
@@ -51,12 +53,22 @@ function extractRelationshipData(
return relationshipsData;
}
+const extractName = (display: string) => {
+ const pattern = /-\s*(.*)$/;
+ const match = display.match(pattern);
+ if (match && match.length > 1) {
+ return match[1].trim();
+ }
+ return display.trim();
+};
+
interface RelationshipsResponse {
results: Array;
}
interface ExtractedRelationship {
uuid: string;
+ name: string;
display: string;
relativeAge: number;
relativeUuid: string;
diff --git a/packages/esm-patient-banner-app/src/hooks/usePatientAttributes.ts b/packages/esm-patient-banner-app/src/hooks/usePatientAttributes.ts
index 6360c7f62f..8d6ac22096 100644
--- a/packages/esm-patient-banner-app/src/hooks/usePatientAttributes.ts
+++ b/packages/esm-patient-banner-app/src/hooks/usePatientAttributes.ts
@@ -7,13 +7,15 @@ const customRepresentation =
'custom:(uuid,display,identifiers:(identifier,uuid,preferred,location:(uuid,name),identifierType:(uuid,name,format,formatDescription,validator)),person:(uuid,display,gender,birthdate,dead,age,deathDate,birthdateEstimated,causeOfDeath,preferredName:(uuid,preferred,givenName,middleName,familyName),attributes,preferredAddress:(uuid,preferred,address1,address2,cityVillage,longitude,stateProvince,latitude,country,postalCode,countyDistrict,address3,address4,address5,address6,address7)))';
/**
- * React hook that takes patientUuid and return Patient Attributes {@link Attribute}
- * @param patientUuid Unique Patient identifier
- * @returns Object containing `patient-attributes`, `isLoading` loading status, `error`
+ * React hook for obtaining patient attributes for a given patient {@link Attribute}
+ *
+ * If `patientUuid` is null, the hook does nothing.
+ *
+ * @param patientUuid The patient's UUID
*/
-export const usePatientAttributes = (patientUuid: string) => {
+export const usePatientAttributes = (patientUuid: string | null) => {
const { data, error, isLoading } = useSWRImmutable<{ data: Patient }>(
- `/ws/rest/v1/patient/${patientUuid}?v=${customRepresentation}`,
+ patientUuid ? `/ws/rest/v1/patient/${patientUuid}?v=${customRepresentation}` : null,
openmrsFetch,
);
@@ -32,10 +34,10 @@ export const usePatientAttributes = (patientUuid: string) => {
* @returns Object containing `contactAttribute` {@link Attribute} loading status
*/
export const usePatientContactAttributes = (patientUuid: string) => {
- const { contactAttributeType } = useConfig() as ConfigObject;
- const { attributes, isLoading } = usePatientAttributes(patientUuid);
- const contactAttributes = attributes?.filter(
- ({ attributeType }) => contactAttributeType?.some((uuid) => attributeType?.uuid === uuid),
+ const { contactAttributeTypes } = useConfig() as ConfigObject;
+ const { attributes, isLoading } = usePatientAttributes(contactAttributeTypes.length ? patientUuid : null);
+ const contactAttributes = attributes?.filter(({ attributeType }) =>
+ contactAttributeTypes.includes(attributeType?.uuid),
);
return {
contactAttributes: contactAttributes ?? [],
diff --git a/packages/esm-patient-banner-app/translations/zh_CN.json b/packages/esm-patient-banner-app/translations/zh_CN.json
index 5749bafb56..feffc78f8e 100644
--- a/packages/esm-patient-banner-app/translations/zh_CN.json
+++ b/packages/esm-patient-banner-app/translations/zh_CN.json
@@ -19,8 +19,6 @@
"patientLists": "患者列表",
"postalCode": "邮政编码",
"relationships": "关系",
- "seeMoreLists_one": "查看另外 {{count}} 个列表",
- "seeMoreLists_other": "查看另外 {{count}} 个列表",
"showDetails": "显示详情",
"started": "已开始",
"state": "省份",
diff --git a/packages/esm-patient-chart-app/src/config-schema.ts b/packages/esm-patient-chart-app/src/config-schema.ts
index f5de8e3394..5fb927b715 100644
--- a/packages/esm-patient-chart-app/src/config-schema.ts
+++ b/packages/esm-patient-chart-app/src/config-schema.ts
@@ -119,7 +119,6 @@ export const esmPatientChartSchema = {
_default: false,
},
};
-
export interface ChartConfig {
offlineVisitTypeUuid: string;
visitTypeResourceUrl: string;
@@ -142,16 +141,3 @@ export interface ChartConfig {
};
disableChangingVisitLocation: boolean;
}
-
-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`',
- _default: [],
- },
-};
-
-export interface ConfigObject {
- contactAttributeType: Array;
-}
diff --git a/packages/esm-patient-chart-app/src/visit-header/close-button.component.tsx b/packages/esm-patient-chart-app/src/visit-header/close-button.component.tsx
new file mode 100644
index 0000000000..c74d025b8a
--- /dev/null
+++ b/packages/esm-patient-chart-app/src/visit-header/close-button.component.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { HeaderGlobalAction } from '@carbon/react';
+import { CloseFilled } from '@carbon/react/icons';
+import { getHistory, goBackInHistory, navigate, usePatient } from '@openmrs/esm-framework';
+import { useCallback } from 'react';
+import { useTranslation } from 'react-i18next';
+import styles from './close-button.scss';
+
+export function CloseButton() {
+ const { t } = useTranslation();
+ const { patientUuid } = usePatient();
+
+ const onClosePatientChart = useCallback(() => {
+ const history = getHistory();
+ // Get the last page the user was on before opening the patient chart by going backward
+ // through the history until a URL does not include patientUuid
+ let onCloseTarget = '';
+ for (let i = history.length - 1; i >= 0; i--) {
+ if (!history[i].includes(patientUuid)) {
+ onCloseTarget = history[i];
+ break;
+ }
+ }
+ if (onCloseTarget) {
+ goBackInHistory({ toUrl: onCloseTarget });
+ } else {
+ navigate({ to: '${openmrsSpaBase}/home' });
+ }
+ }, [patientUuid]);
+
+ return (
+
+
+
+ );
+}
diff --git a/packages/esm-patient-chart-app/src/visit-header/close-button.scss b/packages/esm-patient-chart-app/src/visit-header/close-button.scss
new file mode 100644
index 0000000000..c283e3ad11
--- /dev/null
+++ b/packages/esm-patient-chart-app/src/visit-header/close-button.scss
@@ -0,0 +1,5 @@
+@import '~@openmrs/esm-styleguide/src/vars';
+
+.headerGlobalBarCloseButton {
+ @include brand-02(background-color);
+}
\ No newline at end of file
diff --git a/packages/esm-patient-chart-app/src/visit-header/visit-header.component.tsx b/packages/esm-patient-chart-app/src/visit-header/visit-header.component.tsx
index cf917acb9f..1cbdef46ab 100644
--- a/packages/esm-patient-chart-app/src/visit-header/visit-header.component.tsx
+++ b/packages/esm-patient-chart-app/src/visit-header/visit-header.component.tsx
@@ -1,7 +1,6 @@
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
-import { Button, Header, HeaderGlobalAction, HeaderGlobalBar, HeaderMenuButton, Tag, Tooltip } from '@carbon/react';
-import { CloseFilled } from '@carbon/react/icons';
+import { Button, Header, HeaderGlobalBar, HeaderMenuButton, Tag, Tooltip } from '@carbon/react';
import {
age,
ConfigurableLink,
@@ -9,7 +8,6 @@ import {
useLayoutType,
usePatient,
useVisit,
- navigate,
useConfig,
showModal,
ExtensionSlot,
@@ -21,6 +19,7 @@ import { EditQueueEntry } from '../visit/queue-entry/edit-queue-entry.component'
import VisitHeaderSideMenu from './visit-header-side-menu.component';
import styles from './visit-header.scss';
import RetrospectiveVisitLabel from './retrospective-visit-label.component';
+import { CloseButton } from './close-button.component';
interface PatientInfoProps {
patient: fhir.Patient;
@@ -139,10 +138,6 @@ const VisitHeader: React.FC = () => {
const toggleSideMenu = useCallback(() => setIsSideMenuExpanded((prevState) => !prevState), []);
- const onClosePatientChart = useCallback(() => {
- document.referrer === '' ? navigate({ to: `${window.spaBase}/home` }) : window.history.back();
- }, []);
-
const openModal = useCallback((patientUuid) => {
const dispose = showModal('end-visit-dialog', {
closeModal: () => dispose(),
@@ -198,13 +193,7 @@ const VisitHeader: React.FC = () => {
)}
>
)}
-
-
-
+
diff --git a/packages/esm-patient-chart-app/src/visit-header/visit-header.scss b/packages/esm-patient-chart-app/src/visit-header/visit-header.scss
index 7397c78cdc..ef20957847 100644
--- a/packages/esm-patient-chart-app/src/visit-header/visit-header.scss
+++ b/packages/esm-patient-chart-app/src/visit-header/visit-header.scss
@@ -8,10 +8,6 @@
@include brand-02(background-color);
}
-.headerGlobalBarCloseButton {
- @include brand-02(background-color);
-}
-
.headerName {
display: flex;
}
diff --git a/packages/esm-patient-chart-app/src/visit-header/visit-header.test.tsx b/packages/esm-patient-chart-app/src/visit-header/visit-header.test.tsx
index b69f43a189..c520095769 100644
--- a/packages/esm-patient-chart-app/src/visit-header/visit-header.test.tsx
+++ b/packages/esm-patient-chart-app/src/visit-header/visit-header.test.tsx
@@ -9,6 +9,9 @@ import {
useVisit,
navigate,
showModal,
+ getHistory,
+ goBackInHistory,
+ age,
} from '@openmrs/esm-framework';
import { registerWorkspace, launchPatientWorkspace } from '@openmrs/esm-patient-common-lib';
import { mockPatient, mockPatientWithLongName, getByTextWithMarkup } from 'tools';
@@ -19,26 +22,21 @@ const mockUseAssignedExtensions = useAssignedExtensions as jest.Mock;
const mockUsePatient = usePatient as jest.Mock;
const mockUseVisit = useVisit as jest.Mock;
const mockUseLayoutType = useLayoutType as jest.Mock;
-const mockExtensionRegistry = {};
const mockShowModal = showModal as jest.Mock;
-const mockNavigateBack = jest.fn();
+const mockGetHistory = getHistory as jest.Mock;
+const mockGoBackInHistory = goBackInHistory as jest.Mock;
jest.mock('@openmrs/esm-framework', () => {
const originalModule = jest.requireActual('@openmrs/esm-framework');
return {
...originalModule,
- usePatient: jest.fn(),
- useAssignedExtensions: jest.fn(),
- age: jest.fn(() => 20),
+ age: jest.fn().mockReturnValue('20'),
+ getHistory: jest.fn(() => []),
+ goBackInHistory: jest.fn(),
LeftNavMenu: jest.fn().mockImplementation(() => Left Nav Menu
),
- useVisit: jest.fn(),
- registerExtension: (ext) => {
- mockExtensionRegistry[ext.name] = ext;
- },
- getExtensionRegistration: (name) => mockExtensionRegistry[name],
translateFrom: (module, key, defaultValue, options) => defaultValue,
+ useAssignedExtensions: jest.fn(),
useOnClickOutside: jest.fn(),
- showModal: jest.fn(),
};
});
@@ -47,20 +45,19 @@ jest.mock('@openmrs/esm-patient-common-lib', () => {
return {
...originalModule,
launchPatientWorkspace: jest.fn(),
- navigate: jest.fn(),
};
});
describe('Visit Header', () => {
beforeEach(() => {
- window.history.back = mockNavigateBack;
+ mockUseAssignedExtensions.mockReturnValue([{ id: 'someId' }]);
+ mockGoBackInHistory.mockClear();
});
test('should display visit header and left nav bar hamburger icon', async () => {
const user = userEvent.setup();
registerWorkspace({ name: 'start-visit-workspace-form', title: 'Start visit', load: jest.fn() });
- mockUseAssignedExtensions.mockReturnValue([{ id: 'someId' }]);
mockUsePatient.mockReturnValue({
patient: mockPatient,
isLoading: false,
@@ -70,7 +67,7 @@ describe('Visit Header', () => {
mockUseVisit.mockReturnValue({ isValidating: null, currentVisit: null });
mockUseLayoutType.mockReturnValue('tablet');
- renderVisitHeader();
+ render();
const headerBanner = screen.getByRole('banner', { name: /OpenMRS/i });
expect(headerBanner).toBeInTheDocument();
@@ -96,25 +93,10 @@ describe('Visit Header', () => {
expect(startVisitButton).toBeInTheDocument();
await user.click(startVisitButton);
- expect(launchPatientWorkspace).toHaveBeenCalled();
expect(launchPatientWorkspace).toHaveBeenCalledWith('start-visit-workspace-form');
-
- const closeButton = screen.getByRole('button', { name: 'Close' });
- expect(closeButton).toBeInTheDocument();
-
- // Should close the visit-header
- await user.click(closeButton);
- expect(navigate).toHaveBeenCalledWith({ to: '/spa/home' });
- expect(window.history.back).not.toHaveBeenCalled();
-
- Object.defineProperty(document, 'referrer', { value: 'some-uuid', configurable: true });
- await user.click(closeButton);
- expect(window.history.back).toHaveBeenCalled();
- expect(mockNavigateBack).toHaveBeenCalled();
});
test('should display a truncated name when the patient name is very long', async () => {
- mockUseAssignedExtensions.mockReturnValue([{ id: 'someId' }]);
mockUsePatient.mockReturnValue({
patient: mockPatientWithLongName,
isLoading: false,
@@ -124,7 +106,7 @@ describe('Visit Header', () => {
mockUseVisit.mockReturnValue({ isValidating: null, currentVisit: null });
mockUseLayoutType.mockReturnValue('desktop');
- renderVisitHeader();
+ render();
const longNameText = screen.getByText(/^Some very long given name...$/i);
expect(longNameText).toBeInTheDocument();
@@ -133,7 +115,6 @@ describe('Visit Header', () => {
it('should be able to show configurable stop visit button and modal to stop current visit', async () => {
const user = userEvent.setup();
- mockUseAssignedExtensions.mockReturnValue([{ id: 'someId' }]);
mockUsePatient.mockReturnValue({
patient: mockPatientWithLongName,
isLoading: false,
@@ -143,7 +124,7 @@ describe('Visit Header', () => {
mockUseVisit.mockReturnValue({ isValidating: false, currentVisit: mockCurrentVisit });
mockUseLayoutType.mockReturnValue('desktop');
- renderVisitHeader();
+ render();
// Should be able to end a visit
const endVisitButton = screen.getByRole('button', { name: /End visit/i });
@@ -154,14 +135,33 @@ describe('Visit Header', () => {
expect(mockShowModal).toHaveBeenCalledTimes(1);
const closeButton = screen.getByRole('button', { name: 'Close' });
- expect(closeButton).toBeInTheDocument();
+ await user.click(closeButton);
+ expect(navigate).toHaveBeenCalled();
+ });
- // Should close the visit-header
+ test('close button should navigate back to before the patient chart', async () => {
+ const user = userEvent.setup();
+ mockGetHistory.mockReturnValue([
+ 'https://o3.openmrs.org/openmrs/spa/home',
+ 'https://o3.openmrs.org/openmrs/spa/patient/1234/chart',
+ `https://o3.openmrs.org/openmrs/spa/patient/${mockPatient.id}/chart`,
+ `https://o3.openmrs.org/openmrs/spa/patient/${mockPatient.id}/chart/labs`,
+ ]);
+ render();
+ const closeButton = screen.getByRole('button', { name: 'Close' });
await user.click(closeButton);
- expect(navigate).toHaveBeenCalledWith({ to: '/spa/home' });
+ expect(goBackInHistory).toHaveBeenCalledWith({ toUrl: 'https://o3.openmrs.org/openmrs/spa/patient/1234/chart' });
});
-});
-function renderVisitHeader() {
- render();
-}
+ test('close button should navigate to home if no such URL exists in history', async () => {
+ const user = userEvent.setup();
+ render();
+ mockGetHistory.mockReturnValue([
+ `https://o3.openmrs.org/openmrs/spa/patient/${mockPatient.id}/chart`,
+ `https://o3.openmrs.org/openmrs/spa/patient/${mockPatient.id}/chart/labs`,
+ ]);
+ const closeButton = screen.getByRole('button', { name: 'Close' });
+ await user.click(closeButton);
+ expect(navigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/home' });
+ });
+});
diff --git a/packages/esm-patient-chart-app/src/workspace/workspace-window.test.tsx b/packages/esm-patient-chart-app/src/workspace/workspace-window.test.tsx
index c2a12092d5..6a4dc1654d 100644
--- a/packages/esm-patient-chart-app/src/workspace/workspace-window.test.tsx
+++ b/packages/esm-patient-chart-app/src/workspace/workspace-window.test.tsx
@@ -19,10 +19,6 @@ jest.mock('@openmrs/esm-framework', () => {
return {
...originalModule,
isDesktop: jest.fn(),
- getExtensionRegistration: (name) => mockExtensionRegistry[name],
- registerExtension: (ext) => {
- mockExtensionRegistry[ext.name] = ext;
- },
translateFrom: (module, key, defaultValue, options) => defaultValue,
useBodyScrollLock: jest.fn(),
};
diff --git a/packages/esm-patient-chart-app/translations/km.json b/packages/esm-patient-chart-app/translations/km.json
index 29ee8d13c4..6659aebee7 100644
--- a/packages/esm-patient-chart-app/translations/km.json
+++ b/packages/esm-patient-chart-app/translations/km.json
@@ -83,7 +83,7 @@
"markAlive": "សម្គាល់ថានៅរស់",
"markAsAlive": "សម្គាល់ថានៅរស់",
"markAsDeceased": "តើអ្នកប្រាកដថាចង់សម្គាល់ថាអ្នកជំងឺបានស្លាប់ហើយ?",
- "markDeceased": "គូសលើអ្នកជាស្លាប់",
+ "markDeceased": "កំណត់ត្រាមរណភាព",
"markingPatientDeceasedInfoText": "ការសម្គាល់អ្នកជំងឺថាបានស្លាប់ រួចបញ្ចប់ការពិនិត្យអ្នកជំងឺនេះ",
"maximize": "អតិបរមា",
"medications": "ឱសថ",
diff --git a/packages/esm-patient-chart-app/translations/zh.json b/packages/esm-patient-chart-app/translations/zh.json
index be1202c4f0..5ee8c27805 100644
--- a/packages/esm-patient-chart-app/translations/zh.json
+++ b/packages/esm-patient-chart-app/translations/zh.json
@@ -1,136 +1,191 @@
{
- "actions": "操作",
- "activeFormWarning": "工作区中有一个正在进行中的表单",
+ "addAPastVisit": "Add a past visit",
"addPastVisit": "添加历史就诊",
"addPastVisitText": "您可以添加或更新一个历史就诊,请选择以下选项之一继续。",
- "address": "地址",
"all": "全部",
"allEncounters": "所有问诊",
+ "Allergies dashboard": "Allergies dashboard",
+ "appointmentEdited": "Appointment edited",
+ "Appointments dashboard": "Appointments dashboard",
+ "appointmentUpdate": "Upcoming appointment updated successfully",
+ "Attachments dashboard": "Attachments dashboard",
"cancel": "取消",
- "cancelActiveVisit": "取消活动就诊",
+ "cancelActiveVisitConfirmation": "Are you sure you want to cancel this active visit?",
+ "cancellingVisit": "Cancelling visit",
"cancelVisit": "取消就诊",
- "cancelVisitError": "取消活动就诊时出现错误",
- "cancelVisitWarningMessage": "取消此次就诊将删除所有相关的问诊记录",
+ "cancelVisitExplainerMessage": "Cancelling this visit will delete its associated encounters",
"causeOfDeath": "死亡原因",
+ "causeOfDeath_title": "Cause of Death",
"checkFilters": "检查上方的筛选条件",
- "chooseService": "选择服务",
- "chooseStatus": "选择状态",
"close": "关闭",
- "configurePriorities": "请配置优先级以继续。",
- "configureServices": "请配置服务以继续。",
- "configureStatuses": "请配置状态以继续。",
+ "Conditions dashboard": "Conditions dashboard",
"confirm": "确认",
"confirmDeceased": "确认已故",
+ "confirmDeletingVisitTextWithStartAndEndDate": "Are you sure you want to delete {{visit}} which started {{visitStartDate}} and ended {{visitEndDate}}?",
"confirmMarkAsAlive": "您确定要将患者标记为存活吗?",
- "contactDetails": "联系方式",
+ "confirmModifyingVisitDateToAccomodateEncounter": "The encounter date falls outside the designated visit date range. Would you like to modify the visit date to accommodate the new encounter date?",
+ "currentVisit": "Current Visit",
"date": "日期",
"dateAndTime": "日期&时间",
- "dateAndTimeOfVisit": "就诊日期和时间",
"dateOfDeath": "死亡日期",
+ "delete": "Delete",
+ "deleteEncounter": "Delete Encounter",
+ "deleteEncounterConfirmationText": "Are you sure you want to delete this encounter? This action can't be undone.",
"deleteThisEncounter": "删除此次问诊",
+ "deleteVisit": "Delete visit",
+ "deleteVisitDialogHeader": "Are you sure you want to delete this visit?",
+ "deletingVisit": "Deleting visit",
+ "deletingVisitWillDeleteEncounters": "Deleting this visit will delete all associated encounters.",
"diagnoses": "诊断",
"discard": "放弃",
"dose": "剂量",
- "edit": "编辑",
- "editEncounter": "编辑这次问诊",
"editPastVisit": "编辑历史就诊",
- "editQueueEntryStatusTooltip": "编辑",
"editThisEncounter": "编辑这次问诊",
+ "editThisVisit": "Edit this visit",
+ "editVisitDetails": "Edit visit details",
+ "emptyStateText": "There are no {{displayText}} to display for this patient",
+ "encounterDeleted": "Encounter deleted",
"encounters": "问诊",
- "Encounters": "问诊",
+ "encounters_title": "Encounters",
"encounterType": "问诊类型",
"end": "End",
- "endActiveVisit": "结束活动就诊",
+ "endActiveVisitConfirmation": "Are you sure you want to end this active visit?",
"endDate": "End date",
+ "endDate_title": "End Date",
"endVisit": "结束就诊",
- "endVisitError": "结束当前就诊时出现错误",
- "endVisitWarningMessage": "结束此次就诊后,您将无法为该患者填写另一个问诊记录表。",
+ "endVisit_title": "End Visit",
+ "endVisitExplainerMessage": "Ending this visit means that you will no longer be able to add encounters to it. If you need to add an encounter, you can create a new visit for this patient or edit a past one.",
+ "error": "Error",
+ "errorCancellingVisit": "Error cancelling active visit",
+ "errorCopy": "Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.",
+ "errorDeletingVisit": "Error deleting visit",
+ "errorEndingVisit": "Error ending visit",
+ "errorOccuredDeletingVisit": "An error occured when deleting visit",
+ "errorUpdatingVisitDetails": "Error updating visit details",
+ "errorWhenRestoringVisit": "Error occured when restoring {{visit}}",
+ "failedDeleting": "couldn't be deleted",
+ "failedToLoadCurrentVisit": "Failed loading current visit",
"female": "女性",
"fieldRequired": "此字段为必填项",
"filterByEncounterType": "按问诊类型筛选",
+ "form": "Form name",
+ "Forms & Notes dashboard": "Forms & Notes dashboard",
"goToThisEncounter": "前往这次问诊",
"hide": "隐藏",
"indication": "Indication",
+ "invalidTimeFormat": "Invalid time format",
+ "invalidVisitStartDate": "Start date needs to be on or before {{firstEncounterDatetime}}",
+ "invalidVisitStopDate": "Visit stop date time cannot be on or before visit start date time",
"loading": "加载中",
- "loadVisitInfo": "加载就诊信息",
+ "loadingVisit": "Loading current visit...",
"location": "地点",
"male": "男性",
"markAlive": "标记存活",
"markAsAlive": "标记为存活",
"markAsDeceased": "您确定要将患者标记为已故吗?",
+ "markDeceased": "Mark deceased",
"markingPatientDeceasedInfoText": "标记患者为已故将结束该患者的所有活动就诊",
"maximize": "最大化",
"medications": "药物清单",
+ "Medications dashboard": "Medications dashboard",
"minimize": "最小化",
"missingVisitType": "就诊类型缺失",
+ "modifyVisitDate": "Modify visit date",
+ "movePatient": "Move patient",
+ "movePatientToNextService": "Move patient to next service",
"name": "Name",
"no": "No",
"noActiveVisit": "当前没有活动的就诊",
+ "noActiveVisitMessage": "active visit",
+ "noActiveVisitNoRDEText": "You can't add data to the patient chart without an active visit. Would you like to start a new visit?",
"noActiveVisitText": "您无法在没有活动就诊的情况下向患者图表添加数据,请选择以下选项之一以继续。",
"noDiagnosesFound": "未找到诊断",
"noEncountersFound": "未找到问诊记录",
"noEncountersToDisplay": "没有可显示的问诊记录",
- "noMedicationsFound": "未找到药物清单",
- "noNotesFound": "No notes found",
"noObservationsFound": "未找到观察记录",
- "noPrioritiesConfigured": "未配置优先级",
- "noServicesConfigured": "未配置服务",
- "noStatusesConfigured": "未配置状态",
"notes": "Notes",
+ "Offline Actions dashboard": "Offline Actions dashboard",
"openAnyway": "Open anyway",
"optional": "可选的",
"orderDurationAndUnit": "for {duration} {durationUnit}",
"orderIndefiniteDuration": "无限期",
"other": "其他",
+ "paginationItemsCount_other": "{{pageItemsCount}} / {{count}} items",
+ "paginationPageText_other": "of {{count}} pages",
+ "partOfFormDidntLoad": "Part of the form did not load",
"pastVisitErrorText": "历史就诊错误",
"pastVisits": "历史就诊",
- "priority": "优先级",
+ "Patient Summary": "Patient Summary",
+ "Patient Summary dashboard": "Patient Summary dashboard",
+ "patientBreadcrumb": "Patient",
"program": "Program",
+ "Programs dashboard": "Programs dashboard",
"provider": "Provider",
"quantity": "数量",
"queueAddedSuccessfully": "患者已成功添加到队列中。",
"queueEntryError": "将患者添加到队列时出现错误",
"recommended": "Recommended",
+ "record": "Record",
"refills": "补充处方",
- "relationships": "关系",
+ "refreshToTryAgain": "Please refresh to try again",
+ "Results Viewer dashboard": "Results Viewer dashboard",
+ "retrospectiveEntry": "Retrospective Entry",
"searchForAVisitType": "搜索就诊类型",
"searchForCauseOfDeath": "搜索死亡原因",
"searchThisList": "搜索此列表",
+ "seeAll": "See all",
"selectAnOption": "选择一个选项",
"selectLocation": "选择地点",
"selectProgramType": "Select program type",
- "selectService": "选择服务",
- "selectStatus": "选择状态",
"selectVisitType": "请选择就诊类型",
- "service": "服务",
"setAliveError": "标记患者为存活时出现错误",
"setAliveSuccessfully": "患者已成功标记为存活",
"setDeceased": "设置为已故",
"setDeceasedError": "标记患者为已故时出现错误",
"setDeceasedSuccessfully": "患者已成功标记为已故",
- "showAllDetails": "展示所有细节",
- "showLess": "展示更少",
"start": "开始",
+ "startAVisit": "Start a visit",
"startDate": "开始日期",
"startNewVisit": "开始新的就诊",
"startVisit": "开始就诊",
"startVisitError": "开始当前就诊时出现错误",
- "status": "状态",
+ "successfullyDeleted": "successfully deleted",
"tests": "Tests",
"time": "时间",
+ "timeFormat ": "Time Format",
"type": "类型",
+ "undo": "Undo",
"unknown": "未知",
+ "unsavedChanges": "You have unsaved changes",
+ "unsavedChangesInForm": "There are unsaved changes in {{formName}}. Please save them before opening another form.",
+ "updateError": "Error updating upcoming appointment",
+ "updateVisitDetails": "Update visit details",
"visit": "就诊",
- "visitCanceled": "成功取消活动就诊",
+ "visitAttributes": "Visit attributes",
+ "visitCancelled": "Visit cancelled",
+ "visitCancelSuccessMessage": "Active {{visit}} cancelled successfully",
+ "visitDeleted": "{{visit}} deleted",
+ "visitDeletedSuccessfully": "{{visit}} deleted successfully",
+ "visitDetailsUpdated": "Visit details updated",
+ "visitDetailsUpdatedSuccessfully": "{{visit}} updated successfully",
"visitEnded": "就诊结束",
"visitEndSuccessfully": "成功结束当前就诊",
"visitLocation": "就诊地点",
+ "visitNotRestored": "Visit couldn't be restored",
+ "visitRestored": "Visit restored",
+ "visitRestoredSuccessfully": "{{visit}} restored successfully",
"visits": "就诊",
"Visits": "就诊",
+ "Visits dashboard": "Visits dashboard",
+ "visitStartDatetime": "Visit start date and time",
"visitStarted": "就诊开始",
"visitStartedSuccessfully": "",
+ "visitStopDateMustBeAfterMostRecentEncounter": "Stop date needs to be on or after {{lastEncounterDatetime}}",
+ "visitStopDatetime": "Visit stop date and time",
"visitSummaries": "就诊总结",
"visitType": "就诊类型",
- "workspaceModalText": "在工作区中启动一个新表单可能会导致您丢失在 {formName} 表单上的未保存的工作。",
+ "visitType_title": "Visit Type",
+ "visitTypeRequired": "Visit type is required",
+ "Vitals & Biometrics dashboard": "Vitals & Biometrics dashboard",
"yes": "是"
}
diff --git a/packages/esm-patient-chart-app/translations/zh_CN.json b/packages/esm-patient-chart-app/translations/zh_CN.json
index be1202c4f0..80d172df57 100644
--- a/packages/esm-patient-chart-app/translations/zh_CN.json
+++ b/packages/esm-patient-chart-app/translations/zh_CN.json
@@ -1,136 +1,189 @@
{
- "actions": "操作",
- "activeFormWarning": "工作区中有一个正在进行中的表单",
+ "addAPastVisit": "Add a past visit",
"addPastVisit": "添加历史就诊",
"addPastVisitText": "您可以添加或更新一个历史就诊,请选择以下选项之一继续。",
- "address": "地址",
"all": "全部",
"allEncounters": "所有问诊",
+ "Allergies dashboard": "Allergies dashboard",
+ "appointmentEdited": "Appointment edited",
+ "Appointments dashboard": "Appointments dashboard",
+ "appointmentUpdate": "Upcoming appointment updated successfully",
+ "Attachments dashboard": "Attachments dashboard",
"cancel": "取消",
- "cancelActiveVisit": "取消活动就诊",
+ "cancelActiveVisitConfirmation": "Are you sure you want to cancel this active visit?",
+ "cancellingVisit": "Cancelling visit",
"cancelVisit": "取消就诊",
- "cancelVisitError": "取消活动就诊时出现错误",
- "cancelVisitWarningMessage": "取消此次就诊将删除所有相关的问诊记录",
+ "cancelVisitExplainerMessage": "Cancelling this visit will delete its associated encounters",
"causeOfDeath": "死亡原因",
+ "causeOfDeath_title": "Cause of Death",
"checkFilters": "检查上方的筛选条件",
- "chooseService": "选择服务",
- "chooseStatus": "选择状态",
"close": "关闭",
- "configurePriorities": "请配置优先级以继续。",
- "configureServices": "请配置服务以继续。",
- "configureStatuses": "请配置状态以继续。",
+ "Conditions dashboard": "Conditions dashboard",
"confirm": "确认",
"confirmDeceased": "确认已故",
+ "confirmDeletingVisitTextWithStartAndEndDate": "Are you sure you want to delete {{visit}} which started {{visitStartDate}} and ended {{visitEndDate}}?",
"confirmMarkAsAlive": "您确定要将患者标记为存活吗?",
- "contactDetails": "联系方式",
+ "confirmModifyingVisitDateToAccomodateEncounter": "The encounter date falls outside the designated visit date range. Would you like to modify the visit date to accommodate the new encounter date?",
+ "currentVisit": "Current Visit",
"date": "日期",
"dateAndTime": "日期&时间",
- "dateAndTimeOfVisit": "就诊日期和时间",
"dateOfDeath": "死亡日期",
+ "delete": "Delete",
+ "deleteEncounter": "Delete Encounter",
+ "deleteEncounterConfirmationText": "Are you sure you want to delete this encounter? This action can't be undone.",
"deleteThisEncounter": "删除此次问诊",
+ "deleteVisit": "Delete visit",
+ "deleteVisitDialogHeader": "Are you sure you want to delete this visit?",
+ "deletingVisit": "Deleting visit",
+ "deletingVisitWillDeleteEncounters": "Deleting this visit will delete all associated encounters.",
"diagnoses": "诊断",
"discard": "放弃",
"dose": "剂量",
- "edit": "编辑",
- "editEncounter": "编辑这次问诊",
"editPastVisit": "编辑历史就诊",
- "editQueueEntryStatusTooltip": "编辑",
"editThisEncounter": "编辑这次问诊",
+ "editThisVisit": "Edit this visit",
+ "editVisitDetails": "Edit visit details",
+ "emptyStateText": "There are no {{displayText}} to display for this patient",
+ "encounterDeleted": "Encounter deleted",
"encounters": "问诊",
- "Encounters": "问诊",
+ "encounters_title": "Encounters",
"encounterType": "问诊类型",
"end": "End",
- "endActiveVisit": "结束活动就诊",
+ "endActiveVisitConfirmation": "Are you sure you want to end this active visit?",
"endDate": "End date",
+ "endDate_title": "End Date",
"endVisit": "结束就诊",
- "endVisitError": "结束当前就诊时出现错误",
- "endVisitWarningMessage": "结束此次就诊后,您将无法为该患者填写另一个问诊记录表。",
+ "endVisit_title": "End Visit",
+ "endVisitExplainerMessage": "Ending this visit means that you will no longer be able to add encounters to it. If you need to add an encounter, you can create a new visit for this patient or edit a past one.",
+ "error": "Error",
+ "errorCancellingVisit": "Error cancelling active visit",
+ "errorCopy": "Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.",
+ "errorDeletingVisit": "Error deleting visit",
+ "errorEndingVisit": "Error ending visit",
+ "errorOccuredDeletingVisit": "An error occured when deleting visit",
+ "errorUpdatingVisitDetails": "Error updating visit details",
+ "errorWhenRestoringVisit": "Error occured when restoring {{visit}}",
+ "failedDeleting": "couldn't be deleted",
+ "failedToLoadCurrentVisit": "Failed loading current visit",
"female": "女性",
"fieldRequired": "此字段为必填项",
"filterByEncounterType": "按问诊类型筛选",
+ "form": "Form name",
+ "Forms & Notes dashboard": "Forms & Notes dashboard",
"goToThisEncounter": "前往这次问诊",
"hide": "隐藏",
"indication": "Indication",
+ "invalidTimeFormat": "Invalid time format",
+ "invalidVisitStartDate": "Start date needs to be on or before {{firstEncounterDatetime}}",
+ "invalidVisitStopDate": "Visit stop date time cannot be on or before visit start date time",
"loading": "加载中",
- "loadVisitInfo": "加载就诊信息",
+ "loadingVisit": "Loading current visit...",
"location": "地点",
"male": "男性",
"markAlive": "标记存活",
"markAsAlive": "标记为存活",
"markAsDeceased": "您确定要将患者标记为已故吗?",
+ "markDeceased": "Mark deceased",
"markingPatientDeceasedInfoText": "标记患者为已故将结束该患者的所有活动就诊",
"maximize": "最大化",
"medications": "药物清单",
+ "Medications dashboard": "Medications dashboard",
"minimize": "最小化",
"missingVisitType": "就诊类型缺失",
+ "modifyVisitDate": "Modify visit date",
+ "movePatient": "Move patient",
+ "movePatientToNextService": "Move patient to next service",
"name": "Name",
"no": "No",
"noActiveVisit": "当前没有活动的就诊",
+ "noActiveVisitMessage": "active visit",
+ "noActiveVisitNoRDEText": "You can't add data to the patient chart without an active visit. Would you like to start a new visit?",
"noActiveVisitText": "您无法在没有活动就诊的情况下向患者图表添加数据,请选择以下选项之一以继续。",
"noDiagnosesFound": "未找到诊断",
"noEncountersFound": "未找到问诊记录",
"noEncountersToDisplay": "没有可显示的问诊记录",
- "noMedicationsFound": "未找到药物清单",
- "noNotesFound": "No notes found",
"noObservationsFound": "未找到观察记录",
- "noPrioritiesConfigured": "未配置优先级",
- "noServicesConfigured": "未配置服务",
- "noStatusesConfigured": "未配置状态",
"notes": "Notes",
+ "Offline Actions dashboard": "Offline Actions dashboard",
"openAnyway": "Open anyway",
"optional": "可选的",
"orderDurationAndUnit": "for {duration} {durationUnit}",
"orderIndefiniteDuration": "无限期",
"other": "其他",
+ "partOfFormDidntLoad": "Part of the form did not load",
"pastVisitErrorText": "历史就诊错误",
"pastVisits": "历史就诊",
- "priority": "优先级",
+ "Patient Summary": "Patient Summary",
+ "Patient Summary dashboard": "Patient Summary dashboard",
+ "patientBreadcrumb": "Patient",
"program": "Program",
+ "Programs dashboard": "Programs dashboard",
"provider": "Provider",
"quantity": "数量",
"queueAddedSuccessfully": "患者已成功添加到队列中。",
"queueEntryError": "将患者添加到队列时出现错误",
"recommended": "Recommended",
+ "record": "Record",
"refills": "补充处方",
- "relationships": "关系",
+ "refreshToTryAgain": "Please refresh to try again",
+ "Results Viewer dashboard": "Results Viewer dashboard",
+ "retrospectiveEntry": "Retrospective Entry",
"searchForAVisitType": "搜索就诊类型",
"searchForCauseOfDeath": "搜索死亡原因",
"searchThisList": "搜索此列表",
+ "seeAll": "See all",
"selectAnOption": "选择一个选项",
"selectLocation": "选择地点",
"selectProgramType": "Select program type",
- "selectService": "选择服务",
- "selectStatus": "选择状态",
"selectVisitType": "请选择就诊类型",
- "service": "服务",
"setAliveError": "标记患者为存活时出现错误",
"setAliveSuccessfully": "患者已成功标记为存活",
"setDeceased": "设置为已故",
"setDeceasedError": "标记患者为已故时出现错误",
"setDeceasedSuccessfully": "患者已成功标记为已故",
- "showAllDetails": "展示所有细节",
- "showLess": "展示更少",
"start": "开始",
+ "startAVisit": "Start a visit",
"startDate": "开始日期",
"startNewVisit": "开始新的就诊",
"startVisit": "开始就诊",
"startVisitError": "开始当前就诊时出现错误",
- "status": "状态",
+ "successfullyDeleted": "successfully deleted",
"tests": "Tests",
"time": "时间",
+ "timeFormat ": "Time Format",
"type": "类型",
+ "undo": "Undo",
"unknown": "未知",
+ "unsavedChanges": "You have unsaved changes",
+ "unsavedChangesInForm": "There are unsaved changes in {{formName}}. Please save them before opening another form.",
+ "updateError": "Error updating upcoming appointment",
+ "updateVisitDetails": "Update visit details",
"visit": "就诊",
- "visitCanceled": "成功取消活动就诊",
+ "visitAttributes": "Visit attributes",
+ "visitCancelled": "Visit cancelled",
+ "visitCancelSuccessMessage": "Active {{visit}} cancelled successfully",
+ "visitDeleted": "{{visit}} deleted",
+ "visitDeletedSuccessfully": "{{visit}} deleted successfully",
+ "visitDetailsUpdated": "Visit details updated",
+ "visitDetailsUpdatedSuccessfully": "{{visit}} updated successfully",
"visitEnded": "就诊结束",
"visitEndSuccessfully": "成功结束当前就诊",
"visitLocation": "就诊地点",
+ "visitNotRestored": "Visit couldn't be restored",
+ "visitRestored": "Visit restored",
+ "visitRestoredSuccessfully": "{{visit}} restored successfully",
"visits": "就诊",
"Visits": "就诊",
+ "Visits dashboard": "Visits dashboard",
+ "visitStartDatetime": "Visit start date and time",
"visitStarted": "就诊开始",
"visitStartedSuccessfully": "",
+ "visitStopDateMustBeAfterMostRecentEncounter": "Stop date needs to be on or after {{lastEncounterDatetime}}",
+ "visitStopDatetime": "Visit stop date and time",
"visitSummaries": "就诊总结",
"visitType": "就诊类型",
- "workspaceModalText": "在工作区中启动一个新表单可能会导致您丢失在 {formName} 表单上的未保存的工作。",
+ "visitType_title": "Visit Type",
+ "visitTypeRequired": "Visit type is required",
+ "Vitals & Biometrics dashboard": "Vitals & Biometrics dashboard",
"yes": "是"
}
diff --git a/packages/esm-patient-common-lib/src/types/workspace.ts b/packages/esm-patient-common-lib/src/types/workspace.ts
index 23eee841aa..4aed8d04f0 100644
--- a/packages/esm-patient-common-lib/src/types/workspace.ts
+++ b/packages/esm-patient-common-lib/src/types/workspace.ts
@@ -3,8 +3,12 @@ export type WorkspaceWindowState = 'maximized' | 'hidden' | 'normal';
/** The default parameters received by all workspaces */
export interface DefaultWorkspaceProps {
- closeWorkspace(ignoreChanges: boolean): void;
- closeWorkspace(): void;
+ /**
+ * Call this function to close the workspace. If ignoreChanges is true, the user will not be
+ * prompted to save changes before closing, even if the `testFcn` passed to `promptBeforeClosing`
+ * returns `true`.
+ */
+ closeWorkspace(ignoreChanges?: boolean): void;
/**
* Call this with a no-args function that returns true if the user should be prompted before
* this workspace is closed; e.g. if there is unsaved data.
diff --git a/packages/esm-patient-common-lib/src/workspaces/workspaces.test.ts b/packages/esm-patient-common-lib/src/workspaces/workspaces.test.ts
index 876ab54fab..2100104a98 100644
--- a/packages/esm-patient-common-lib/src/workspaces/workspaces.test.ts
+++ b/packages/esm-patient-common-lib/src/workspaces/workspaces.test.ts
@@ -361,6 +361,7 @@ describe('workspace system', () => {
});
test('is compatible with workspaces registered as extensions', () => {
+ console.warn = jest.fn();
const store = getWorkspaceStore();
registerExtension({
name: 'lab-results',
@@ -375,6 +376,7 @@ describe('workspace system', () => {
expect(workspace.additionalProps['foo']).toBe(true);
expect(workspace.title).toBe('Lab Results');
expect(workspace.preferredWindowSize).toBe('maximized');
+ expect(console.warn).toHaveBeenCalled();
});
test('launching unregistered workspace throws an error', () => {
diff --git a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts
index ee028ee265..516725394e 100644
--- a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts
+++ b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts
@@ -58,6 +58,7 @@ export function registerWorkspace(workspace: WorkspaceRegistration) {
};
}
+const workspaceExtensionWarningsIssued = new Set();
/**
* This exists for compatibility with the old way of registering
* workspaces (as extensions).
@@ -70,6 +71,12 @@ function getWorkspaceRegistration(name: string): WorkspaceRegistration {
} else {
const workspaceExtension = getExtensionRegistration(name);
if (workspaceExtension) {
+ if (!workspaceExtensionWarningsIssued.has(name)) {
+ console.warn(
+ `The workspace '${name}' is registered as an extension. This is deprecated. Please use the 'registerWorkspace' function instead.`,
+ );
+ workspaceExtensionWarningsIssued.add(name);
+ }
return {
name: workspaceExtension.name,
title: getTitleFromExtension(workspaceExtension),
diff --git a/packages/esm-patient-conditions-app/translations/zh.json b/packages/esm-patient-conditions-app/translations/zh.json
index b4d6c32fe4..a48d39a8a4 100644
--- a/packages/esm-patient-conditions-app/translations/zh.json
+++ b/packages/esm-patient-conditions-app/translations/zh.json
@@ -1,23 +1,32 @@
{
- "active": "Active",
"add": "添加",
- "all": "全部",
"cancel": "取消",
"checkFilters": "检查上方的筛选条件",
"condition": "病情",
+ "conditionDeleted": "Condition deleted",
"conditionNowVisible": "现在在病情页面上可见",
"conditions": "病情",
+ "Conditions": "Conditions",
"conditionSaved": "病情保存成功",
- "conditionSaveError": "保存病情时出现错误",
+ "conditionUpdated": "Condition updated",
"currentStatus": "当前状态",
"dateOfOnset": "发病日期",
+ "delete": "Delete",
+ "deleteCondition": "Delete condition",
+ "deleteModalConfirmationText": "Are you sure you want to delete this condition?",
+ "deleting": "Deleting",
+ "edit": "Edit",
+ "editCondition": "Edit a Condition",
"endDate": "End date",
"enterCondition": "输入病情",
- "inactive": "Inactive",
+ "errorCreatingCondition": "Error creating condition",
+ "errorDeletingCondition": "Error deleting condition",
+ "errorUpdatingCondition": "Error updating condition",
"noConditionsToDisplay": "没有可显示的病情",
"noResultsFor": "No results for",
"onsetDate": "Onset date",
"saveAndClose": "保存并关闭",
+ "saving": "Saving",
"searchConditions": "搜索病情",
"searching": "搜索中",
"seeAll": "查看全部",
diff --git a/packages/esm-patient-conditions-app/translations/zh_CN.json b/packages/esm-patient-conditions-app/translations/zh_CN.json
index b4d6c32fe4..a48d39a8a4 100644
--- a/packages/esm-patient-conditions-app/translations/zh_CN.json
+++ b/packages/esm-patient-conditions-app/translations/zh_CN.json
@@ -1,23 +1,32 @@
{
- "active": "Active",
"add": "添加",
- "all": "全部",
"cancel": "取消",
"checkFilters": "检查上方的筛选条件",
"condition": "病情",
+ "conditionDeleted": "Condition deleted",
"conditionNowVisible": "现在在病情页面上可见",
"conditions": "病情",
+ "Conditions": "Conditions",
"conditionSaved": "病情保存成功",
- "conditionSaveError": "保存病情时出现错误",
+ "conditionUpdated": "Condition updated",
"currentStatus": "当前状态",
"dateOfOnset": "发病日期",
+ "delete": "Delete",
+ "deleteCondition": "Delete condition",
+ "deleteModalConfirmationText": "Are you sure you want to delete this condition?",
+ "deleting": "Deleting",
+ "edit": "Edit",
+ "editCondition": "Edit a Condition",
"endDate": "End date",
"enterCondition": "输入病情",
- "inactive": "Inactive",
+ "errorCreatingCondition": "Error creating condition",
+ "errorDeletingCondition": "Error deleting condition",
+ "errorUpdatingCondition": "Error updating condition",
"noConditionsToDisplay": "没有可显示的病情",
"noResultsFor": "No results for",
"onsetDate": "Onset date",
"saveAndClose": "保存并关闭",
+ "saving": "Saving",
"searchConditions": "搜索病情",
"searching": "搜索中",
"seeAll": "查看全部",
diff --git a/packages/esm-patient-flags-app/translations/zh.json b/packages/esm-patient-flags-app/translations/zh.json
new file mode 100644
index 0000000000..adb3d22fae
--- /dev/null
+++ b/packages/esm-patient-flags-app/translations/zh.json
@@ -0,0 +1,26 @@
+{
+ "activeFirst": "Active first",
+ "alphabetically": "A - Z",
+ "clearSearch": "Clear search",
+ "closeFlagsBar": "Close flags bar",
+ "disableFlagError": "Disable flag error",
+ "disablingFlag": "Disabling flag...",
+ "discard": "Discard",
+ "edit": "Edit",
+ "editFlags": "Edit flags",
+ "enabledFlag": "Enabled flag",
+ "enablingFlag": "Enabling flag...",
+ "flagCount_other": "{{count}} risk flags",
+ "flagDisabled": "Flag disabled",
+ "flagDisabledSuccessfully": "Flag successfully disabled",
+ "flagDisableError": "Error disabling the flag",
+ "flagEnabled": "flag enabled",
+ "flagEnabledSuccessfully": "Flag successfully enabled",
+ "flagEnableError": "Error enabling flag",
+ "loading": "Loading",
+ "matchesForSearchTerm_other": "{{count}} flags",
+ "noFlagsFound": "Sorry, no flags found matching your search",
+ "retiredFirst": "Retired first",
+ "saveAndClose": "Save & close",
+ "searchForAFlag": "Search for a flag"
+}
diff --git a/packages/esm-patient-flags-app/translations/zh_CN.json b/packages/esm-patient-flags-app/translations/zh_CN.json
new file mode 100644
index 0000000000..8170c34d7e
--- /dev/null
+++ b/packages/esm-patient-flags-app/translations/zh_CN.json
@@ -0,0 +1,24 @@
+{
+ "activeFirst": "Active first",
+ "alphabetically": "A - Z",
+ "clearSearch": "Clear search",
+ "closeFlagsBar": "Close flags bar",
+ "disableFlagError": "Disable flag error",
+ "disablingFlag": "Disabling flag...",
+ "discard": "Discard",
+ "edit": "Edit",
+ "editFlags": "Edit flags",
+ "enabledFlag": "Enabled flag",
+ "enablingFlag": "Enabling flag...",
+ "flagDisabled": "Flag disabled",
+ "flagDisabledSuccessfully": "Flag successfully disabled",
+ "flagDisableError": "Error disabling the flag",
+ "flagEnabled": "flag enabled",
+ "flagEnabledSuccessfully": "Flag successfully enabled",
+ "flagEnableError": "Error enabling flag",
+ "loading": "Loading",
+ "noFlagsFound": "Sorry, no flags found matching your search",
+ "retiredFirst": "Retired first",
+ "saveAndClose": "Save & close",
+ "searchForAFlag": "Search for a flag"
+}
diff --git a/packages/esm-patient-forms-app/translations/zh.json b/packages/esm-patient-forms-app/translations/zh.json
index eba7b4abbe..ab1d8daac8 100644
--- a/packages/esm-patient-forms-app/translations/zh.json
+++ b/packages/esm-patient-forms-app/translations/zh.json
@@ -1,18 +1,17 @@
{
- "all": "全部",
- "clinicalForm": "临床表单",
- "completed": "已完成",
- "form": "表单",
+ "clinicalForms": "Clinical forms",
+ "editForm": "Edit form",
"formName": "表单名称(A-Z)",
"forms": "表单",
"formSearchHint": "尝试使用替代名称或关键词搜索表单",
- "goToSummary": "前往摘要",
"homeOverviewCardView": "查看",
"lastCompleted": "Last Completed",
"never": "Never",
- "noFormsAvailable": "该患者没有可显示的表单",
+ "noFormsToDisplay": "There are no forms to display.",
"noMatchingFormsAvailable": "没有可显示的 {formCategory} 表单",
"noMatchingFormsToDisplay": "没有匹配的表单可显示",
+ "offlineForms": "Offline forms",
+ "offlineForms__lower": "offline forms",
"offlineFormsOverviewCardAvailableOffline": "离线可用",
"offlineFormsTableFormAvailableOffline": "离线",
"offlineFormsTableFormNameHeader": "表单名称",
@@ -20,7 +19,6 @@
"offlinePatientsTableSearchLabel": "搜索此列表",
"offlinePatientsTableSearchPlaceholder": "搜索此列表",
"offlineToggle": "离线切换",
- "recommended": "Recommended",
- "searchThisList": "搜索此列表",
- "seeAll": "查看全部"
+ "searchForAForm": "Search for a form",
+ "searchThisList": "搜索此列表"
}
diff --git a/packages/esm-patient-forms-app/translations/zh_CN.json b/packages/esm-patient-forms-app/translations/zh_CN.json
index eba7b4abbe..ab1d8daac8 100644
--- a/packages/esm-patient-forms-app/translations/zh_CN.json
+++ b/packages/esm-patient-forms-app/translations/zh_CN.json
@@ -1,18 +1,17 @@
{
- "all": "全部",
- "clinicalForm": "临床表单",
- "completed": "已完成",
- "form": "表单",
+ "clinicalForms": "Clinical forms",
+ "editForm": "Edit form",
"formName": "表单名称(A-Z)",
"forms": "表单",
"formSearchHint": "尝试使用替代名称或关键词搜索表单",
- "goToSummary": "前往摘要",
"homeOverviewCardView": "查看",
"lastCompleted": "Last Completed",
"never": "Never",
- "noFormsAvailable": "该患者没有可显示的表单",
+ "noFormsToDisplay": "There are no forms to display.",
"noMatchingFormsAvailable": "没有可显示的 {formCategory} 表单",
"noMatchingFormsToDisplay": "没有匹配的表单可显示",
+ "offlineForms": "Offline forms",
+ "offlineForms__lower": "offline forms",
"offlineFormsOverviewCardAvailableOffline": "离线可用",
"offlineFormsTableFormAvailableOffline": "离线",
"offlineFormsTableFormNameHeader": "表单名称",
@@ -20,7 +19,6 @@
"offlinePatientsTableSearchLabel": "搜索此列表",
"offlinePatientsTableSearchPlaceholder": "搜索此列表",
"offlineToggle": "离线切换",
- "recommended": "Recommended",
- "searchThisList": "搜索此列表",
- "seeAll": "查看全部"
+ "searchForAForm": "Search for a form",
+ "searchThisList": "搜索此列表"
}
diff --git a/packages/esm-patient-immunizations-app/translations/zh.json b/packages/esm-patient-immunizations-app/translations/zh.json
index 9e26dfeeb6..a42c9cb9e8 100644
--- a/packages/esm-patient-immunizations-app/translations/zh.json
+++ b/packages/esm-patient-immunizations-app/translations/zh.json
@@ -1 +1,20 @@
-{}
\ No newline at end of file
+{
+ "add": "Add",
+ "cancel": "Cancel",
+ "errorSaving": "Error saving vaccination",
+ "expirationDate": "Expiration Date",
+ "goToSummary": "Go to Summary",
+ "immunizations": "Immunizations",
+ "Immunizations": "Immunizations",
+ "lotNumber": "Lot Number",
+ "manufacturer": "Manufacturer",
+ "pleaseSelect": "Please select",
+ "recentVaccination": "Recent vaccination",
+ "save": "Save",
+ "seeAll": "See all",
+ "sequence": "Sequence",
+ "singleDoseOn": "Single Dose on",
+ "vaccinationDate": "Vaccination date",
+ "vaccinationSaved": "Vaccination saved successfully",
+ "vaccine": "Vaccine"
+}
diff --git a/packages/esm-patient-immunizations-app/translations/zh_CN.json b/packages/esm-patient-immunizations-app/translations/zh_CN.json
index 9e26dfeeb6..a42c9cb9e8 100644
--- a/packages/esm-patient-immunizations-app/translations/zh_CN.json
+++ b/packages/esm-patient-immunizations-app/translations/zh_CN.json
@@ -1 +1,20 @@
-{}
\ No newline at end of file
+{
+ "add": "Add",
+ "cancel": "Cancel",
+ "errorSaving": "Error saving vaccination",
+ "expirationDate": "Expiration Date",
+ "goToSummary": "Go to Summary",
+ "immunizations": "Immunizations",
+ "Immunizations": "Immunizations",
+ "lotNumber": "Lot Number",
+ "manufacturer": "Manufacturer",
+ "pleaseSelect": "Please select",
+ "recentVaccination": "Recent vaccination",
+ "save": "Save",
+ "seeAll": "See all",
+ "sequence": "Sequence",
+ "singleDoseOn": "Single Dose on",
+ "vaccinationDate": "Vaccination date",
+ "vaccinationSaved": "Vaccination saved successfully",
+ "vaccine": "Vaccine"
+}
diff --git a/packages/esm-patient-labs-app/translations/zh.json b/packages/esm-patient-labs-app/translations/zh.json
new file mode 100644
index 0000000000..91ae9389ce
--- /dev/null
+++ b/packages/esm-patient-labs-app/translations/zh.json
@@ -0,0 +1,70 @@
+{
+ "add": "Add",
+ "additionalInstructions": "Additional instructions",
+ "backToOrderBasket": "Back to order basket",
+ "backToTimeline": "Back to timeline",
+ "cancel": "Cancel",
+ "dataLoadError": "Data Load Error",
+ "date": "Date",
+ "dateCollected": "Displaying date collected",
+ "discard": "Discard",
+ "endDate": "End date",
+ "error": "Error",
+ "errorLoadingTestTypes": "Error occured when loading test types",
+ "female": "Female",
+ "full": "Full",
+ "incomplete": "Incomplete",
+ "labOrders": "Lab orders",
+ "labReferenceNumber": "Lab reference number",
+ "loading": "Loading",
+ "male": "Male",
+ "moreResultsAvailable": "More results available",
+ "observationsDisplayText": "observations",
+ "onDate": "on",
+ "orderActionNew": "New",
+ "ordered": "Ordered",
+ "other": "Other",
+ "panel": "Panel",
+ "print": "Print",
+ "printedBy": "Printed by",
+ "printTestResults": "Print test results",
+ "priority": "Priority",
+ "recentResults": "Recent Results",
+ "recentTestResults": "recent test results",
+ "referenceRange": "Reference range",
+ "removeFromBasket": "Remove from basket",
+ "resetTreeText": "Reset tree",
+ "resulted": "Resulted",
+ "results": "Results",
+ "Results Viewer": "Results Viewer",
+ "resultsText": "results",
+ "returnToTimeline": "Return to timeline",
+ "saveOrder": "Save order",
+ "seeAllResults": "See all results",
+ "showTree": "Show tree",
+ "split": "Split",
+ "startDate": "Start date",
+ "testName": "Test name",
+ "testResults": "test results",
+ "testResults_title": "Test Results",
+ "testResultsData": "Test results data",
+ "testType": "Test type",
+ "testTypePlaceholder": "Select one",
+ "thereAreNoTestResultsFound": "There are no test results found within the specified date range",
+ "timeline": "Timeline",
+ "timeOfTest": "Time of Test",
+ "tree": "Tree",
+ "trend": "Trend",
+ "trendline": "Trendline",
+ "trendlineRangeSelector1Day": "1 day",
+ "trendlineRangeSelector1Month": "1 month",
+ "trendlineRangeSelector1Year": "1 year",
+ "trendlineRangeSelector5Days": "5 days",
+ "trendlineRangeSelector5Years": "5 years",
+ "trendlineRangeSelectorAll": "All",
+ "trendlineRangeSelectorMonths": "6 months",
+ "tryReopeningTheForm": "Please try launching the form again",
+ "unknown": "Unknown",
+ "value": "Value",
+ "view": "View"
+}
diff --git a/packages/esm-patient-labs-app/translations/zh_CN.json b/packages/esm-patient-labs-app/translations/zh_CN.json
new file mode 100644
index 0000000000..91ae9389ce
--- /dev/null
+++ b/packages/esm-patient-labs-app/translations/zh_CN.json
@@ -0,0 +1,70 @@
+{
+ "add": "Add",
+ "additionalInstructions": "Additional instructions",
+ "backToOrderBasket": "Back to order basket",
+ "backToTimeline": "Back to timeline",
+ "cancel": "Cancel",
+ "dataLoadError": "Data Load Error",
+ "date": "Date",
+ "dateCollected": "Displaying date collected",
+ "discard": "Discard",
+ "endDate": "End date",
+ "error": "Error",
+ "errorLoadingTestTypes": "Error occured when loading test types",
+ "female": "Female",
+ "full": "Full",
+ "incomplete": "Incomplete",
+ "labOrders": "Lab orders",
+ "labReferenceNumber": "Lab reference number",
+ "loading": "Loading",
+ "male": "Male",
+ "moreResultsAvailable": "More results available",
+ "observationsDisplayText": "observations",
+ "onDate": "on",
+ "orderActionNew": "New",
+ "ordered": "Ordered",
+ "other": "Other",
+ "panel": "Panel",
+ "print": "Print",
+ "printedBy": "Printed by",
+ "printTestResults": "Print test results",
+ "priority": "Priority",
+ "recentResults": "Recent Results",
+ "recentTestResults": "recent test results",
+ "referenceRange": "Reference range",
+ "removeFromBasket": "Remove from basket",
+ "resetTreeText": "Reset tree",
+ "resulted": "Resulted",
+ "results": "Results",
+ "Results Viewer": "Results Viewer",
+ "resultsText": "results",
+ "returnToTimeline": "Return to timeline",
+ "saveOrder": "Save order",
+ "seeAllResults": "See all results",
+ "showTree": "Show tree",
+ "split": "Split",
+ "startDate": "Start date",
+ "testName": "Test name",
+ "testResults": "test results",
+ "testResults_title": "Test Results",
+ "testResultsData": "Test results data",
+ "testType": "Test type",
+ "testTypePlaceholder": "Select one",
+ "thereAreNoTestResultsFound": "There are no test results found within the specified date range",
+ "timeline": "Timeline",
+ "timeOfTest": "Time of Test",
+ "tree": "Tree",
+ "trend": "Trend",
+ "trendline": "Trendline",
+ "trendlineRangeSelector1Day": "1 day",
+ "trendlineRangeSelector1Month": "1 month",
+ "trendlineRangeSelector1Year": "1 year",
+ "trendlineRangeSelector5Days": "5 days",
+ "trendlineRangeSelector5Years": "5 years",
+ "trendlineRangeSelectorAll": "All",
+ "trendlineRangeSelectorMonths": "6 months",
+ "tryReopeningTheForm": "Please try launching the form again",
+ "unknown": "Unknown",
+ "value": "Value",
+ "view": "View"
+}
diff --git a/packages/esm-patient-lists-app/translations/zh.json b/packages/esm-patient-lists-app/translations/zh.json
new file mode 100644
index 0000000000..5d0ea7cc1e
--- /dev/null
+++ b/packages/esm-patient-lists-app/translations/zh.json
@@ -0,0 +1,19 @@
+{
+ "backToPatientLists": "Back to patient lists",
+ "checkFilters": "Check the filters above",
+ "createdOn": "Created on",
+ "identifier": "Identifier",
+ "listName": "List name",
+ "listType": "List type",
+ "name": "Name",
+ "noMatchingListsFound": "No matching lists to display",
+ "noMatchingPatients": "No matching patients to display",
+ "noPatientListsToDisplay": "No patient lists to display",
+ "noPatientsInList": "There are no patients in this list",
+ "numberOfPatients": "No. of patients",
+ "patientLists": "Patient lists",
+ "patients": "patients",
+ "searchThisList": "Search this list",
+ "sex": "Sex",
+ "startDate": "Start Date"
+}
diff --git a/packages/esm-patient-lists-app/translations/zh_CN.json b/packages/esm-patient-lists-app/translations/zh_CN.json
new file mode 100644
index 0000000000..5d0ea7cc1e
--- /dev/null
+++ b/packages/esm-patient-lists-app/translations/zh_CN.json
@@ -0,0 +1,19 @@
+{
+ "backToPatientLists": "Back to patient lists",
+ "checkFilters": "Check the filters above",
+ "createdOn": "Created on",
+ "identifier": "Identifier",
+ "listName": "List name",
+ "listType": "List type",
+ "name": "Name",
+ "noMatchingListsFound": "No matching lists to display",
+ "noMatchingPatients": "No matching patients to display",
+ "noPatientListsToDisplay": "No patient lists to display",
+ "noPatientsInList": "There are no patients in this list",
+ "numberOfPatients": "No. of patients",
+ "patientLists": "Patient lists",
+ "patients": "patients",
+ "searchThisList": "Search this list",
+ "sex": "Sex",
+ "startDate": "Start Date"
+}
diff --git a/packages/esm-patient-medications-app/translations/zh.json b/packages/esm-patient-medications-app/translations/zh.json
index b2173da811..99de0d0ec9 100644
--- a/packages/esm-patient-medications-app/translations/zh.json
+++ b/packages/esm-patient-medications-app/translations/zh.json
@@ -2,21 +2,19 @@
"activeMedicationsDisplayText": "Active medications",
"activeMedicationsHeaderTitle": "active medications",
"activeMedicationsTableTitle": "Active Medications",
- "activeVisitRequired": "An active visit is required to make orders",
"add": "添加",
"backToOrderBasket": "Back to order basket",
- "cancel": "取消",
"clearSearchResults": "清除结果",
"decrement": "Decrement",
"details": "Details",
"directlyAddToBasket": "Immediately add to basket",
"discard": "放弃",
"discontinue": "Discontinue",
- "discontinuedOrders_one": "{count} discontinued order(s)",
- "discontinuedOrders_other": "{count} discontinued order(s)",
"dispensingInformation": "3. Dispensing instructions",
"dosageInstructions": "1. 用量说明",
"dose": "剂量",
+ "drugAlreadyPrescribed": "Already prescribed",
+ "drugOrders": "Drug orders",
"duration": "Duration",
"durationUnit": "Duration unit",
"durationUnitPlaceholder": "Duration Unit",
@@ -27,35 +25,32 @@
"editDoseComboBoxTitle": "剂量",
"editFrequencyComboBoxTitle": "Frequency",
"editRouteComboBoxTitle": "Route",
- "emptyOrderBasket": "Your basket is empty",
"endDate": "End date",
"error": "错误",
- "errorCreatingAnEncounter": "创建问诊时出现错误",
"errorFetchingDrugOrderTemplates": "获取药物医嘱模板时出现错误",
"errorFetchingDrugResults": "Error fetching results for \"{searchTerm}\"",
"errorFetchingOrderConfig": "获取医嘱配置时发生错误",
+ "female": "Female",
"freeTextDosage": "自由文本剂量",
+ "goToDrugOrderForm": "Order form",
"increment": "Increment",
"indication": "Indication",
"indicationPlaceholder": "e.g. \"Hypertension\"",
+ "male": "Male",
"medicationDurationAndUnit": "for {duration} {durationUnit}",
"medicationIndefiniteDuration": "无限期",
- "medications": "Medications",
+ "Medications": "Medications",
"modify": "修改",
"none": "None",
"noResultsForDrugSearch": "No results to display for \"{searchTerm}\"",
+ "onDate": "on",
"orderActionDiscontinue": "Discontinue",
+ "orderActionIncomplete": "Incomplete",
"orderActionNew": "New",
- "orderActionRenewed": "Renew",
- "orderActionRevised": "修改",
- "orderBasket": "Order Basket",
- "orderBasketWithCount_one": "Order Basket ({count})",
- "orderBasketWithCount_other": "Order Basket ({count})",
- "orderCompleted": "Order placed",
- "orderCompletedSuccessText": "Your order is complete. The items will now appear on the Orders page.",
+ "orderActionRenew": "Renew",
+ "orderActionRevise": "Modify",
"orderForm": "Order Form",
- "ordersAlreadyInBasketWithCount_one": "{count} item(s) already in your basket",
- "ordersAlreadyInBasketWithCount_other": "{count} item(s) already in your basket",
+ "other": "Other",
"pastMedicationsDisplayText": "Past medications",
"pastMedicationsHeaderTitle": "past medications",
"pastMedicationsTableTitle": "Past Medications",
@@ -63,6 +58,8 @@
"patientInstructionsPlaceholder": "Additional dosing instructions (e.g. \"Take after eating\")",
"prescriptionDuration": "2. Prescription duration",
"prescriptionRefills": "Prescription refills",
+ "print": "Print",
+ "printedBy": "Printed by",
"prn": "P.R.N.",
"prnReason": "P.R.N. reason",
"prnReasonPlaceholder": "Reason to take medicine",
@@ -70,25 +67,17 @@
"quantityToDispense": "Quantity to dispense",
"refills": "Refills",
"removeFromBasket": "Remove from basket",
- "renewedOrders_one": "{count} order(s) being renewed (continued)",
- "renewedOrders_other": "{count} order(s) being renewed (continued)",
"reorder": "Reorder",
- "revisedOrders_one": "{count} order(s) being modified (revised)",
- "revisedOrders_other": "{count} order(s) being modified (revised)",
"saveOrder": "Save order",
"searchAgain": "重新搜索",
"searchFieldPlaceholder": "Search for a drug or orderset (e.g. \"Aspirin\")",
- "searchForAnOrder": "Search for an order above",
"searchResultsMatchesForTerm_one": "{count} result{plural} for \"{searchTerm}\"",
"searchResultsMatchesForTerm_other": "{count} result{plural} for \"{searchTerm}\"",
- "signAndClose": "Sign and close",
- "startAVisitToRecordOrders": "Start a visit to order",
"startDate": "Start date",
- "startVisit": "开始就诊",
"takeAsNeeded": "Take as needed",
"tryReopeningTheForm": "请尝试重新启动表单",
- "tryReopeningTheWorkspaceAgain": "请尝试重新启动工作区",
"trySearchingAgain": "请尝试重新搜索",
"tryTo": "Try to",
+ "unknown": "Unknown",
"usingADifferentTerm": "using a different term"
}
diff --git a/packages/esm-patient-medications-app/translations/zh_CN.json b/packages/esm-patient-medications-app/translations/zh_CN.json
index b2173da811..9457035c60 100644
--- a/packages/esm-patient-medications-app/translations/zh_CN.json
+++ b/packages/esm-patient-medications-app/translations/zh_CN.json
@@ -2,21 +2,19 @@
"activeMedicationsDisplayText": "Active medications",
"activeMedicationsHeaderTitle": "active medications",
"activeMedicationsTableTitle": "Active Medications",
- "activeVisitRequired": "An active visit is required to make orders",
"add": "添加",
"backToOrderBasket": "Back to order basket",
- "cancel": "取消",
"clearSearchResults": "清除结果",
"decrement": "Decrement",
"details": "Details",
"directlyAddToBasket": "Immediately add to basket",
"discard": "放弃",
"discontinue": "Discontinue",
- "discontinuedOrders_one": "{count} discontinued order(s)",
- "discontinuedOrders_other": "{count} discontinued order(s)",
"dispensingInformation": "3. Dispensing instructions",
"dosageInstructions": "1. 用量说明",
"dose": "剂量",
+ "drugAlreadyPrescribed": "Already prescribed",
+ "drugOrders": "Drug orders",
"duration": "Duration",
"durationUnit": "Duration unit",
"durationUnitPlaceholder": "Duration Unit",
@@ -27,35 +25,32 @@
"editDoseComboBoxTitle": "剂量",
"editFrequencyComboBoxTitle": "Frequency",
"editRouteComboBoxTitle": "Route",
- "emptyOrderBasket": "Your basket is empty",
"endDate": "End date",
"error": "错误",
- "errorCreatingAnEncounter": "创建问诊时出现错误",
"errorFetchingDrugOrderTemplates": "获取药物医嘱模板时出现错误",
"errorFetchingDrugResults": "Error fetching results for \"{searchTerm}\"",
"errorFetchingOrderConfig": "获取医嘱配置时发生错误",
+ "female": "Female",
"freeTextDosage": "自由文本剂量",
+ "goToDrugOrderForm": "Order form",
"increment": "Increment",
"indication": "Indication",
"indicationPlaceholder": "e.g. \"Hypertension\"",
+ "male": "Male",
"medicationDurationAndUnit": "for {duration} {durationUnit}",
"medicationIndefiniteDuration": "无限期",
- "medications": "Medications",
+ "Medications": "Medications",
"modify": "修改",
"none": "None",
"noResultsForDrugSearch": "No results to display for \"{searchTerm}\"",
+ "onDate": "on",
"orderActionDiscontinue": "Discontinue",
+ "orderActionIncomplete": "Incomplete",
"orderActionNew": "New",
- "orderActionRenewed": "Renew",
- "orderActionRevised": "修改",
- "orderBasket": "Order Basket",
- "orderBasketWithCount_one": "Order Basket ({count})",
- "orderBasketWithCount_other": "Order Basket ({count})",
- "orderCompleted": "Order placed",
- "orderCompletedSuccessText": "Your order is complete. The items will now appear on the Orders page.",
+ "orderActionRenew": "Renew",
+ "orderActionRevise": "Modify",
"orderForm": "Order Form",
- "ordersAlreadyInBasketWithCount_one": "{count} item(s) already in your basket",
- "ordersAlreadyInBasketWithCount_other": "{count} item(s) already in your basket",
+ "other": "Other",
"pastMedicationsDisplayText": "Past medications",
"pastMedicationsHeaderTitle": "past medications",
"pastMedicationsTableTitle": "Past Medications",
@@ -63,6 +58,8 @@
"patientInstructionsPlaceholder": "Additional dosing instructions (e.g. \"Take after eating\")",
"prescriptionDuration": "2. Prescription duration",
"prescriptionRefills": "Prescription refills",
+ "print": "Print",
+ "printedBy": "Printed by",
"prn": "P.R.N.",
"prnReason": "P.R.N. reason",
"prnReasonPlaceholder": "Reason to take medicine",
@@ -70,25 +67,15 @@
"quantityToDispense": "Quantity to dispense",
"refills": "Refills",
"removeFromBasket": "Remove from basket",
- "renewedOrders_one": "{count} order(s) being renewed (continued)",
- "renewedOrders_other": "{count} order(s) being renewed (continued)",
"reorder": "Reorder",
- "revisedOrders_one": "{count} order(s) being modified (revised)",
- "revisedOrders_other": "{count} order(s) being modified (revised)",
"saveOrder": "Save order",
"searchAgain": "重新搜索",
"searchFieldPlaceholder": "Search for a drug or orderset (e.g. \"Aspirin\")",
- "searchForAnOrder": "Search for an order above",
- "searchResultsMatchesForTerm_one": "{count} result{plural} for \"{searchTerm}\"",
- "searchResultsMatchesForTerm_other": "{count} result{plural} for \"{searchTerm}\"",
- "signAndClose": "Sign and close",
- "startAVisitToRecordOrders": "Start a visit to order",
"startDate": "Start date",
- "startVisit": "开始就诊",
"takeAsNeeded": "Take as needed",
"tryReopeningTheForm": "请尝试重新启动表单",
- "tryReopeningTheWorkspaceAgain": "请尝试重新启动工作区",
"trySearchingAgain": "请尝试重新搜索",
"tryTo": "Try to",
+ "unknown": "Unknown",
"usingADifferentTerm": "using a different term"
}
diff --git a/packages/esm-patient-notes-app/translations/zh.json b/packages/esm-patient-notes-app/translations/zh.json
index b68a943c52..a16d2ea664 100644
--- a/packages/esm-patient-notes-app/translations/zh.json
+++ b/packages/esm-patient-notes-app/translations/zh.json
@@ -7,21 +7,21 @@
"clinicalNotePlaceholder": "Write any additional points here",
"date": "日期",
"diagnoses": "诊断",
- "diagnosis": "Diagnosis",
"discard": "放弃",
"emptyDiagnosisText": "No diagnosis selected — Enter a diagnosis below",
"enterPrimaryDiagnoses": "Enter Primary diagnoses",
"enterSecondaryDiagnoses": "Enter Secondary diagnoses",
- "goToSummary": "前往摘要",
"image": "Image",
"imageUploadHelperText": "Upload an image or use this device's camera to capture an image",
"noMatchingDiagnoses": "No diagnoses found matching",
"note": "Note",
"noVisitNoteToDisplay": "No visit note to display",
+ "primaryDiagnosis": "Primary diagnosis",
"primaryDiagnosisInputPlaceholder": "Choose a primary diagnosis",
"saveAndClose": "保存并关闭",
"searchForPrimaryDiagnosis": "Search for a Primary diagnosis",
"searchForSecondaryDiagnosis": "Search for a Secondary diagnosis",
+ "secondaryDiagnosis": "Secondary diagnosis",
"secondaryDiagnosisInputPlaceholder": "Choose a secondary diagnosis",
"seeAll": "查看全部",
"visitDate": "就诊日期",
diff --git a/packages/esm-patient-notes-app/translations/zh_CN.json b/packages/esm-patient-notes-app/translations/zh_CN.json
index b68a943c52..a16d2ea664 100644
--- a/packages/esm-patient-notes-app/translations/zh_CN.json
+++ b/packages/esm-patient-notes-app/translations/zh_CN.json
@@ -7,21 +7,21 @@
"clinicalNotePlaceholder": "Write any additional points here",
"date": "日期",
"diagnoses": "诊断",
- "diagnosis": "Diagnosis",
"discard": "放弃",
"emptyDiagnosisText": "No diagnosis selected — Enter a diagnosis below",
"enterPrimaryDiagnoses": "Enter Primary diagnoses",
"enterSecondaryDiagnoses": "Enter Secondary diagnoses",
- "goToSummary": "前往摘要",
"image": "Image",
"imageUploadHelperText": "Upload an image or use this device's camera to capture an image",
"noMatchingDiagnoses": "No diagnoses found matching",
"note": "Note",
"noVisitNoteToDisplay": "No visit note to display",
+ "primaryDiagnosis": "Primary diagnosis",
"primaryDiagnosisInputPlaceholder": "Choose a primary diagnosis",
"saveAndClose": "保存并关闭",
"searchForPrimaryDiagnosis": "Search for a Primary diagnosis",
"searchForSecondaryDiagnosis": "Search for a Secondary diagnosis",
+ "secondaryDiagnosis": "Secondary diagnosis",
"secondaryDiagnosisInputPlaceholder": "Choose a secondary diagnosis",
"seeAll": "查看全部",
"visitDate": "就诊日期",
diff --git a/packages/esm-patient-orders-app/translations/zh.json b/packages/esm-patient-orders-app/translations/zh.json
new file mode 100644
index 0000000000..c841d2072f
--- /dev/null
+++ b/packages/esm-patient-orders-app/translations/zh.json
@@ -0,0 +1,22 @@
+{
+ "add": "Add",
+ "addResults": "Add Results",
+ "cancelOrder": "Cancel Order",
+ "dateOfOrder": "Date of order",
+ "female": "Female",
+ "male": "Male",
+ "onDate": "on",
+ "order": "Order",
+ "orderedBy": "Ordered by",
+ "orderId": "Order ID",
+ "orders": "Orders",
+ "Orders": "Orders",
+ "orderType": "Order type",
+ "other": "Other",
+ "print": "Print",
+ "printedBy": "Printed by",
+ "priority": "Priority",
+ "status": "Status",
+ "unknown": "Unknown",
+ "viewEdit": "View/Edit Order"
+}
diff --git a/packages/esm-patient-orders-app/translations/zh_CN.json b/packages/esm-patient-orders-app/translations/zh_CN.json
new file mode 100644
index 0000000000..c841d2072f
--- /dev/null
+++ b/packages/esm-patient-orders-app/translations/zh_CN.json
@@ -0,0 +1,22 @@
+{
+ "add": "Add",
+ "addResults": "Add Results",
+ "cancelOrder": "Cancel Order",
+ "dateOfOrder": "Date of order",
+ "female": "Female",
+ "male": "Male",
+ "onDate": "on",
+ "order": "Order",
+ "orderedBy": "Ordered by",
+ "orderId": "Order ID",
+ "orders": "Orders",
+ "Orders": "Orders",
+ "orderType": "Order type",
+ "other": "Other",
+ "print": "Print",
+ "printedBy": "Printed by",
+ "priority": "Priority",
+ "status": "Status",
+ "unknown": "Unknown",
+ "viewEdit": "View/Edit Order"
+}
diff --git a/packages/esm-patient-programs-app/translations/zh.json b/packages/esm-patient-programs-app/translations/zh.json
index d601bf2ba1..7e84f1b7f1 100644
--- a/packages/esm-patient-programs-app/translations/zh.json
+++ b/packages/esm-patient-programs-app/translations/zh.json
@@ -5,15 +5,12 @@
"add": "Add",
"cancel": "Cancel",
"carePrograms": "Care Programs",
- "chooseLocation": "Choose a location",
"chooseProgram": "Choose a program",
"completedOn": "Completed on",
"configurePrograms": "Please configure programs to continue.",
"dateCompleted": "Date completed",
"dateEnrolled": "Date enrolled",
- "discontinue": "Discontinue",
- "enroll": "Enroll",
- "enrollment": "Enrollment",
+ "editProgram": "Edit Program",
"enrollmentLocation": "Enrollment location",
"enrollmentNowVisible": "It is now visible in the Programs table",
"enrollmentSaved": "Program enrollment saved",
@@ -27,6 +24,7 @@
"programEnrollmentSaveError": "Error saving program enrollment",
"programName": "Program name",
"programs": "programs",
+ "Programs": "Programs",
"required": "Required",
"saveAndClose": "Save and close",
"seeAll": "See all",
diff --git a/packages/esm-patient-programs-app/translations/zh_CN.json b/packages/esm-patient-programs-app/translations/zh_CN.json
index d601bf2ba1..7e84f1b7f1 100644
--- a/packages/esm-patient-programs-app/translations/zh_CN.json
+++ b/packages/esm-patient-programs-app/translations/zh_CN.json
@@ -5,15 +5,12 @@
"add": "Add",
"cancel": "Cancel",
"carePrograms": "Care Programs",
- "chooseLocation": "Choose a location",
"chooseProgram": "Choose a program",
"completedOn": "Completed on",
"configurePrograms": "Please configure programs to continue.",
"dateCompleted": "Date completed",
"dateEnrolled": "Date enrolled",
- "discontinue": "Discontinue",
- "enroll": "Enroll",
- "enrollment": "Enrollment",
+ "editProgram": "Edit Program",
"enrollmentLocation": "Enrollment location",
"enrollmentNowVisible": "It is now visible in the Programs table",
"enrollmentSaved": "Program enrollment saved",
@@ -27,6 +24,7 @@
"programEnrollmentSaveError": "Error saving program enrollment",
"programName": "Program name",
"programs": "programs",
+ "Programs": "Programs",
"required": "Required",
"saveAndClose": "Save and close",
"seeAll": "See all",
diff --git a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.component.tsx b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.component.tsx
index 043ee5a2b1..0213a463a7 100644
--- a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.component.tsx
+++ b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.component.tsx
@@ -335,6 +335,7 @@ const VitalsAndBiometricsForm: React.FC = ({ patientUuid,
diastolicBloodPressure,
)
}
+ showErrorMessage={showErrorMessage}
label={t('bloodPressure', 'Blood pressure')}
unitSymbol={conceptUnits.get(config.concepts.systolicBloodPressureUuid) ?? ''}
/>
@@ -358,6 +359,7 @@ const VitalsAndBiometricsForm: React.FC = ({ patientUuid,
pulse && isValueWithinReferenceRange(conceptMetadata, config.concepts['pulseUuid'], pulse)
}
label={t('heartRate', 'Heart rate')}
+ showErrorMessage={showErrorMessage}
unitSymbol={conceptUnits.get(config.concepts.pulseUuid) ?? ''}
/>
@@ -557,6 +559,7 @@ const VitalsAndBiometricsForm: React.FC = ({ patientUuid,
setHasInvalidVitals(false)}
title={t('vitalsAndBiometricsSaveError', 'Error saving vitals and biometrics')}
subtitle={t('checkForValidity', 'Some of the values entered are invalid')}
/>
diff --git a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.test.tsx b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.test.tsx
index 3472f6e6ab..d73bc9eac8 100644
--- a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.test.tsx
+++ b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-form.test.tsx
@@ -238,6 +238,33 @@ describe('VitalsBiometricsForm', () => {
title: 'Error saving vitals and biometrics',
});
});
+
+ it('Display an inline error notification on submit if value of vitals entered is invalid', async () => {
+ const user = userEvent.setup();
+
+ renderForm();
+ const systolic = screen.getByRole('spinbutton', { name: /systolic/i });
+ const pulse = screen.getByRole('spinbutton', { name: /pulse/i });
+ const oxygenSaturation = screen.getByRole('spinbutton', { name: /oxygen saturation/i });
+ const temperature = screen.getByRole('spinbutton', { name: /temperature/i });
+
+ await user.type(systolic, '1000');
+ await user.type(pulse, pulseValue.toString());
+ await user.type(oxygenSaturation, '200');
+ await user.type(temperature, temperatureValue.toString());
+
+ const saveButton = screen.getByRole('button', { name: /save and close/i });
+ await user.click(saveButton);
+
+ expect(screen.getByText(/Some of the values entered are invalid/i)).toBeInTheDocument();
+
+ // close the inline notification --> resubmit --> check for presence of inline notification
+ const closeInlineNotificationButton = screen.getByTitle(/close notification/i);
+ await user.click(closeInlineNotificationButton);
+ expect(screen.queryByText(/some of the values entered are invalid/i)).not.toBeInTheDocument();
+ await user.click(saveButton);
+ expect(screen.getByText(/Some of the values entered are invalid/i)).toBeInTheDocument();
+ });
});
function renderForm() {
diff --git a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-input.test.tsx b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-input.test.tsx
index ed60cae2c3..2c47b97071 100644
--- a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-input.test.tsx
+++ b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/vitals-biometrics-input.test.tsx
@@ -1,9 +1,11 @@
import React from 'react';
-import { screen, render } from '@testing-library/react';
+import { screen, render, cleanup } from '@testing-library/react';
import { useConfig } from '@openmrs/esm-framework';
import { assessValue, getReferenceRangesForConcept } from '../common';
import VitalsAndBiometricsInput from './vitals-biometrics-input.component';
-
+import { isValueWithinReferenceRange } from './vitals-biometrics-form.utils';
+import { useVitalsConceptMetadata } from '@openmrs/esm-patient-common-lib';
+const { conceptRanges, conceptMetadata: mockConceptMetadata } = useVitalsConceptMetadata();
jest.mock('react-hook-form', () => ({
...jest.requireActual('react-hook-form'),
useFormContext: jest.fn().mockImplementation(() => ({
@@ -56,122 +58,120 @@ jest.mock('react-hook-form', () => ({
}),
}));
-const mockConceptMetadata = [
- {
- uuid: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Systolic blood pressure',
- hiNormal: 140,
- hiAbsolute: 250,
- hiCritical: 180,
- lowNormal: 100,
- lowAbsolute: 0,
- lowCritical: 85,
- units: 'mmHg',
- },
- {
- uuid: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Diastolic blood pressure',
- hiNormal: 90,
- hiAbsolute: 150,
- hiCritical: 120,
- lowNormal: 55,
- lowAbsolute: 0,
- lowCritical: 40,
- units: 'mmHg',
- },
- {
- uuid: '5088AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Temperature (c)',
- hiNormal: null,
- hiAbsolute: 43,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 25,
- lowCritical: null,
- units: 'DEG C',
- },
- {
- uuid: '5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Height (cm)',
- hiNormal: null,
- hiAbsolute: 272,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 10,
- lowCritical: null,
- units: 'cm',
- },
- {
- uuid: '5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Weight (kg)',
- hiNormal: null,
- hiAbsolute: 250,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 0,
- lowCritical: null,
- units: 'kg',
- },
- {
- uuid: '5087AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Pulse',
- hiNormal: 100,
- hiAbsolute: 230,
- hiCritical: 130,
- lowNormal: 55,
- lowAbsolute: 0,
- lowCritical: 49,
- units: 'beats/min',
- },
- {
- uuid: '5092AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Arterial blood oxygen saturation (pulse oximeter)',
- hiNormal: null,
- hiAbsolute: 100,
- hiCritical: null,
- lowNormal: 95,
- lowAbsolute: 0,
- lowCritical: 90,
- units: '%',
- },
- {
- uuid: '1343AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Mid-upper arm circumference',
- hiNormal: null,
- hiAbsolute: null,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: null,
- lowCritical: null,
- units: 'cm',
- },
- {
- uuid: '5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Respiratory rate',
- hiNormal: 18,
- hiAbsolute: 999,
- hiCritical: 26,
- lowNormal: 12,
- lowAbsolute: 0,
- lowCritical: 8,
- units: 'breaths/min',
- },
- {
- uuid: '5283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Karnofsky performance score',
- hiNormal: null,
- hiAbsolute: null,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: null,
- lowCritical: null,
- units: '%',
- },
-];
-
jest.mock('@openmrs/esm-patient-common-lib', () => {
const originalModule = jest.requireActual('@openmrs/esm-patient-common-lib');
-
+ const mockConceptMetadata = [
+ {
+ uuid: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Systolic blood pressure',
+ hiNormal: 140,
+ hiAbsolute: 250,
+ hiCritical: 180,
+ lowNormal: 100,
+ lowAbsolute: 0,
+ lowCritical: 85,
+ units: 'mmHg',
+ },
+ {
+ uuid: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Diastolic blood pressure',
+ hiNormal: 90,
+ hiAbsolute: 150,
+ hiCritical: 120,
+ lowNormal: 55,
+ lowAbsolute: 0,
+ lowCritical: 40,
+ units: 'mmHg',
+ },
+ {
+ uuid: '5088AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Temperature (c)',
+ hiNormal: null,
+ hiAbsolute: 43,
+ hiCritical: null,
+ lowNormal: null,
+ lowAbsolute: 25,
+ lowCritical: null,
+ units: 'DEG C',
+ },
+ {
+ uuid: '5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Height (cm)',
+ hiNormal: null,
+ hiAbsolute: 272,
+ hiCritical: null,
+ lowNormal: null,
+ lowAbsolute: 10,
+ lowCritical: null,
+ units: 'cm',
+ },
+ {
+ uuid: '5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Weight (kg)',
+ hiNormal: null,
+ hiAbsolute: 250,
+ hiCritical: null,
+ lowNormal: null,
+ lowAbsolute: 0,
+ lowCritical: null,
+ units: 'kg',
+ },
+ {
+ uuid: '5087AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Pulse',
+ hiNormal: 100,
+ hiAbsolute: 230,
+ hiCritical: 130,
+ lowNormal: 55,
+ lowAbsolute: 0,
+ lowCritical: 49,
+ units: 'beats/min',
+ },
+ {
+ uuid: '5092AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Arterial blood oxygen saturation (pulse oximeter)',
+ hiNormal: null,
+ hiAbsolute: 100,
+ hiCritical: null,
+ lowNormal: 95,
+ lowAbsolute: 0,
+ lowCritical: 90,
+ units: '%',
+ },
+ {
+ uuid: '1343AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Mid-upper arm circumference',
+ hiNormal: null,
+ hiAbsolute: null,
+ hiCritical: null,
+ lowNormal: null,
+ lowAbsolute: null,
+ lowCritical: null,
+ units: 'cm',
+ },
+ {
+ uuid: '5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Respiratory rate',
+ hiNormal: 18,
+ hiAbsolute: 999,
+ hiCritical: 26,
+ lowNormal: 12,
+ lowAbsolute: 0,
+ lowCritical: 8,
+ units: 'breaths/min',
+ },
+ {
+ uuid: '5283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ display: 'Karnofsky performance score',
+ hiNormal: null,
+ hiAbsolute: null,
+ hiCritical: null,
+ lowNormal: null,
+ lowAbsolute: null,
+ lowCritical: null,
+ units: '%',
+ },
+ ];
return {
...originalModule,
useVitalsConceptMetadata: jest.fn().mockImplementation(() => ({
@@ -187,118 +187,18 @@ jest.mock('@openmrs/esm-patient-common-lib', () => {
['5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'breaths/min'],
['5283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', '%'],
]),
- conceptMetadata: [
- {
- uuid: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Systolic blood pressure',
- hiNormal: 140,
- hiAbsolute: 250,
- hiCritical: 180,
- lowNormal: 100,
- lowAbsolute: 0,
- lowCritical: 85,
- units: 'mmHg',
- },
- {
- uuid: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Diastolic blood pressure',
- hiNormal: 90,
- hiAbsolute: 150,
- hiCritical: 120,
- lowNormal: 55,
- lowAbsolute: 0,
- lowCritical: 40,
- units: 'mmHg',
- },
- {
- uuid: '5088AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Temperature (c)',
- hiNormal: null,
- hiAbsolute: 43,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 25,
- lowCritical: null,
- units: 'DEG C',
- },
- {
- uuid: '5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Height (cm)',
- hiNormal: null,
- hiAbsolute: 272,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 10,
- lowCritical: null,
- units: 'cm',
- },
- {
- uuid: '5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Weight (kg)',
- hiNormal: null,
- hiAbsolute: 250,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: 0,
- lowCritical: null,
- units: 'kg',
- },
- {
- uuid: '5087AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Pulse',
- hiNormal: 100,
- hiAbsolute: 230,
- hiCritical: 130,
- lowNormal: 55,
- lowAbsolute: 0,
- lowCritical: 49,
- units: 'beats/min',
- },
- {
- uuid: '5092AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Arterial blood oxygen saturation (pulse oximeter)',
- hiNormal: null,
- hiAbsolute: 100,
- hiCritical: null,
- lowNormal: 95,
- lowAbsolute: 0,
- lowCritical: 90,
- units: '%',
- },
- {
- uuid: '1343AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Mid-upper arm circumference',
- hiNormal: null,
- hiAbsolute: null,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: null,
- lowCritical: null,
- units: 'cm',
- },
- {
- uuid: '5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Respiratory rate',
- hiNormal: 18,
- hiAbsolute: 999,
- hiCritical: 26,
- lowNormal: 12,
- lowAbsolute: 0,
- lowCritical: 8,
- units: 'breaths/min',
- },
- {
- uuid: '5283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
- display: 'Karnofsky performance score',
- hiNormal: null,
- hiAbsolute: null,
- hiCritical: null,
- lowNormal: null,
- lowAbsolute: null,
- lowCritical: null,
- units: '%',
- },
- ],
+ conceptMetadata: mockConceptMetadata,
+ conceptRanges: mockConceptMetadata?.length
+ ? new Map(
+ mockConceptMetadata.map((concept) => [
+ concept.uuid,
+ {
+ lowAbsolute: concept.lowAbsolute ?? null,
+ highAbsolute: concept.hiAbsolute ?? null,
+ },
+ ]),
+ )
+ : new Map([]),
})),
};
});
@@ -311,6 +211,8 @@ jest.mock('@openmrs/esm-framework', () => {
useConfig: jest.fn().mockReturnValue({
concepts: {
pulseUuid: '5087AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ systoleUuid: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
+ diastoleUuid: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
},
}),
};
@@ -318,12 +220,13 @@ jest.mock('@openmrs/esm-framework', () => {
const testProps = {
control: undefined,
- isWithinNormalRange: true,
+ isValueWithinReferenceRange: true,
fieldProperties: [],
interpretation: undefined,
placeholder: '',
label: '',
unitSymbol: '',
+ showErrorMessage: undefined,
};
describe('VitalsAndBiometricsInput', () => {
@@ -368,31 +271,62 @@ describe('VitalsAndBiometricsInput', () => {
it('should validate the input based on the provided interpretation and reference range values', () => {
const config = useConfig();
-
- testProps.fieldProperties = [
+ const fieldsToTest = [
{
id: 'pulse',
name: 'Heart rate',
- min: 0,
- max: 230,
+ min: conceptRanges.get(config.concepts.pulseUuid).lowAbsolute,
+ max: conceptRanges.get(config.concepts.pulseUuid).highAbsolute,
+ type: 'number',
+ uuid: config.concepts.pulseUuid,
+ value: 300,
+ unitSymbol: 'bpm',
+ abnormalValueClass: 'critically-high',
+ },
+
+ {
+ id: 'systole',
+ name: 'Systolic blood pressure',
+ min: conceptRanges.get(config.concepts.systoleUuid).lowAbsolute,
+ max: conceptRanges.get(config.concepts.systoleUuid).highAbsolute,
type: 'number',
+ uuid: config.concepts.systoleUuid,
+ value: -1,
+ unitSymbol: 'mmHg',
+ abnormalValueClass: 'critically-low',
},
];
- testProps.interpretation = assessValue(
- 300,
- getReferenceRangesForConcept(config.concepts.pulseUuid, mockConceptMetadata),
- );
- testProps.label = 'Heart rate';
- testProps.unitSymbol = 'bpm';
- renderVitalsBiometricsInput();
+ fieldsToTest.forEach((field, index) => {
+ testProps.fieldProperties = [fieldsToTest[index]];
+ testProps.isValueWithinReferenceRange = isValueWithinReferenceRange(mockConceptMetadata, field.uuid, field.value);
+ testProps.interpretation = assessValue(
+ field.value,
+ getReferenceRangesForConcept(field.uuid, mockConceptMetadata),
+ );
+ testProps.label = field.name;
+ testProps.unitSymbol = field.unitSymbol;
+ testProps.showErrorMessage = true;
+
+ renderVitalsBiometricsInput();
+
+ screen.findByRole('spinbutton');
- screen.findByRole('spinbutton');
+ expect(screen.getByRole('spinbutton', { name: new RegExp(`${field.name}`, 'i') })).toBeInTheDocument();
+ const abnormalValueFlag = screen.getByTitle(/abnormal value/i);
+ expect(abnormalValueFlag).toBeInTheDocument();
+ expect(abnormalValueFlag).toHaveClass(field.abnormalValueClass);
+ expect(
+ screen.getByText(
+ new RegExp(
+ `Value must be between (${fieldsToTest[index].min}|{{min}}) and (${fieldsToTest[index].max}|{{max}})`,
+ 'i',
+ ),
+ ),
+ ).toBeInTheDocument();
- expect(screen.getByRole('spinbutton', { name: /heart rate/i })).toBeInTheDocument();
- const abnormalValueFlag = screen.getByTitle(/abnormal value/i);
- expect(abnormalValueFlag).toBeInTheDocument();
- expect(abnormalValueFlag).toHaveClass('critically-high');
+ cleanup();
+ });
});
});
diff --git a/packages/esm-patient-vitals-app/translations/zh.json b/packages/esm-patient-vitals-app/translations/zh.json
index ea2fd4f7c7..b2c9043d3a 100644
--- a/packages/esm-patient-vitals-app/translations/zh.json
+++ b/packages/esm-patient-vitals-app/translations/zh.json
@@ -1,24 +1,35 @@
{
+ "abnormalValue": "Abnormal value",
"add": "添加",
"additionalNoteText": "Type any additional notes here",
+ "biometricDisplayed": "Biometric displayed",
+ "biometrics": "Biometrics",
+ "biometrics_lower": "biometrics",
"bloodPressure": "血压",
"bmi": "BMI",
- "bmiCalc": "BMI (calc.)",
"bp": "血压",
- "chartView": "图表视图",
+ "calculatedBmi": "BMI (calc.)",
"checkForValidity": "输入的一些值无效",
+ "date": "Date",
+ "dateAndTime": "Date and time",
"diastolic": "舒张压",
"discard": "放弃",
+ "error": "Error",
+ "female": "Female",
"goToSummary": "前往摘要",
"heartRate": "心率",
"height": "身高",
- "lastRecorded": "上次记录",
"loading": "加载中",
+ "male": "Male",
"muac": "中上臂围",
"noDataRecorded": "该患者尚未记录任何数据",
"notes": "Notes",
- "numericInputError": "必须是在可接受范围内的数字",
+ "other": "Other",
+ "overdue": "Overdue",
"oxygenSaturation": "血氧饱和度",
+ "pleaseFillField": "Please fill at least one field",
+ "print": "Print",
+ "printedBy": "Printed by",
"pulse": "脉搏",
"recordBiometrics": "记录生物特征",
"recordVitals": "记录生命体征",
@@ -28,15 +39,18 @@
"seeAll": "查看全部",
"spo2": "血氧",
"systolic": "收缩压",
- "tableView": "表格视图",
"temp": "体温",
"temperature": "体温",
"temperatureAbbreviated": "体温",
+ "unknown": "Unknown",
+ "validationInputError": "Value must be between {{min}} and {{max}}",
"vitals": "生命体征",
+ "Vitals & Biometrics": "Vitals & Biometrics",
"vitalsAndBiometrics": "生命体征和生物特征",
"vitalsAndBiometricsNowAvailable": "现在在生命体征和生物特征页面上可见",
"vitalsAndBiometricsRecorded": "生命体征和生物特征数据已保存",
"vitalsAndBiometricsSaveError": "保存生命体征和生物特征数据时出现错误",
+ "vitalsHistory": "Vitals history",
"vitalSignDisplayed": "生命体征已显示",
"vitalSigns": "生命体征",
"weight": "体重"
diff --git a/packages/esm-patient-vitals-app/translations/zh_CN.json b/packages/esm-patient-vitals-app/translations/zh_CN.json
index ea2fd4f7c7..b2c9043d3a 100644
--- a/packages/esm-patient-vitals-app/translations/zh_CN.json
+++ b/packages/esm-patient-vitals-app/translations/zh_CN.json
@@ -1,24 +1,35 @@
{
+ "abnormalValue": "Abnormal value",
"add": "添加",
"additionalNoteText": "Type any additional notes here",
+ "biometricDisplayed": "Biometric displayed",
+ "biometrics": "Biometrics",
+ "biometrics_lower": "biometrics",
"bloodPressure": "血压",
"bmi": "BMI",
- "bmiCalc": "BMI (calc.)",
"bp": "血压",
- "chartView": "图表视图",
+ "calculatedBmi": "BMI (calc.)",
"checkForValidity": "输入的一些值无效",
+ "date": "Date",
+ "dateAndTime": "Date and time",
"diastolic": "舒张压",
"discard": "放弃",
+ "error": "Error",
+ "female": "Female",
"goToSummary": "前往摘要",
"heartRate": "心率",
"height": "身高",
- "lastRecorded": "上次记录",
"loading": "加载中",
+ "male": "Male",
"muac": "中上臂围",
"noDataRecorded": "该患者尚未记录任何数据",
"notes": "Notes",
- "numericInputError": "必须是在可接受范围内的数字",
+ "other": "Other",
+ "overdue": "Overdue",
"oxygenSaturation": "血氧饱和度",
+ "pleaseFillField": "Please fill at least one field",
+ "print": "Print",
+ "printedBy": "Printed by",
"pulse": "脉搏",
"recordBiometrics": "记录生物特征",
"recordVitals": "记录生命体征",
@@ -28,15 +39,18 @@
"seeAll": "查看全部",
"spo2": "血氧",
"systolic": "收缩压",
- "tableView": "表格视图",
"temp": "体温",
"temperature": "体温",
"temperatureAbbreviated": "体温",
+ "unknown": "Unknown",
+ "validationInputError": "Value must be between {{min}} and {{max}}",
"vitals": "生命体征",
+ "Vitals & Biometrics": "Vitals & Biometrics",
"vitalsAndBiometrics": "生命体征和生物特征",
"vitalsAndBiometricsNowAvailable": "现在在生命体征和生物特征页面上可见",
"vitalsAndBiometricsRecorded": "生命体征和生物特征数据已保存",
"vitalsAndBiometricsSaveError": "保存生命体征和生物特征数据时出现错误",
+ "vitalsHistory": "Vitals history",
"vitalSignDisplayed": "生命体征已显示",
"vitalSigns": "生命体征",
"weight": "体重"
diff --git a/tools/test-utils.tsx b/tools/test-utils.tsx
index 770fd42982..43e4fdaf6d 100644
--- a/tools/test-utils.tsx
+++ b/tools/test-utils.tsx
@@ -23,9 +23,11 @@ export const renderWithSwr = (ui, options?) => render(ui, { wrapper: swrWrapper,
// Helper function that waits for a loading state to disappear from the screen
export function waitForLoadingToFinish() {
- return waitForElementToBeRemoved(() => [...screen.queryAllByRole('progressbar')], {
- timeout: 4000,
- });
+ if (screen.queryAllByRole('progressbar').length) {
+ return waitForElementToBeRemoved(() => [...screen.queryAllByRole('progressbar')], {
+ timeout: 4000,
+ });
+ }
}
// Custom matcher that queries elements split up by multiple HTML elements by text
@@ -59,14 +61,14 @@ export const mockPatient = {
id: '1f0ad7a1-430f-4397-b571-59ea654a52db',
use: 'secondary',
system: 'Old Identification Number',
- type: { text: 'Old Identification Number' },
+ type: { text: 'Old Identification Number', coding: [{ code: 'Old Identification Number' }] },
value: '100732HE',
},
{
id: '1f0ad7a1-430f-4397-b571-59ea654a52db',
use: 'usual',
system: 'OpenMRS ID',
- type: { text: 'OpenMRS ID' },
+ type: { text: 'OpenMRS ID', coding: [{ code: 'OpenMRS ID' }] },
value: '100GEJ',
},
],
diff --git a/yarn.lock b/yarn.lock
index 8703d34761..29f3fc9550 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2044,6 +2044,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.14.8":
+ version: 7.23.8
+ resolution: "@babel/runtime@npm:7.23.8"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 0bd5543c26811153822a9f382fd39886f66825ff2a397a19008011376533747cd05c33a91f6248c0b8b0edf0448d7c167ebfba34786088f1b7eb11c65be7dfc3
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:7.22.5":
version: 7.22.5
resolution: "@babel/template@npm:7.22.5"
@@ -2184,7 +2193,7 @@ __metadata:
languageName: node
linkType: hard
-"@carbon/colors@npm:^11.20.1":
+"@carbon/colors@npm:^11.20.0, @carbon/colors@npm:^11.20.1":
version: 11.20.1
resolution: "@carbon/colors@npm:11.20.1"
checksum: eb9d983c1ec4852f8542ea21f8bb31d383c417d55fe60a3d1ab8a0e85b617f41699b91657240f07f789b852abe48828f1546da92b1c46de9cfe21c81bb612fd7
@@ -2214,6 +2223,15 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/grid@npm:^11.21.0, @carbon/grid@npm:^11.21.1":
+ version: 11.21.1
+ resolution: "@carbon/grid@npm:11.21.1"
+ dependencies:
+ "@carbon/layout": ^11.20.1
+ checksum: e9bcb0940f6714f428864c8ec356c41c556e802694ede484259235cfc806a021fc498cc6e4f6e2014303ecfdf459ad4b0134820d0d92722f2ceafc9287321a0c
+ languageName: node
+ linkType: hard
+
"@carbon/icon-helpers@npm:^10.44.0":
version: 10.44.0
resolution: "@carbon/icon-helpers@npm:10.44.0"
@@ -2228,20 +2246,20 @@ __metadata:
languageName: node
linkType: hard
-"@carbon/icons-react@npm:^11.28.0":
- version: 11.28.0
- resolution: "@carbon/icons-react@npm:11.28.0"
+"@carbon/icons-react@npm:11.26.0":
+ version: 11.26.0
+ resolution: "@carbon/icons-react@npm:11.26.0"
dependencies:
"@carbon/icon-helpers": ^10.44.0
"@carbon/telemetry": 0.1.0
prop-types: ^15.7.2
peerDependencies:
react: ">=16"
- checksum: c52c63835b43feb3177c4a90161dfb5191a542be0dfe6a3196af96a675f58b75e6c82718413653a313829c04c06d68072a21be66f7d36e39566e61609debaabd
+ checksum: dabc6e7896d2a089aaabac78af9161720995f9e5b0f28694ac664459c5fae164a3d0c16b9cb22f6ab37f01b736cd2613cf232a6b6577b396afd8c083171cae67
languageName: node
linkType: hard
-"@carbon/icons-react@npm:^11.33.0":
+"@carbon/icons-react@npm:^11.26.0, @carbon/icons-react@npm:^11.33.0":
version: 11.33.0
resolution: "@carbon/icons-react@npm:11.33.0"
dependencies:
@@ -2254,6 +2272,19 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/icons-react@npm:^11.28.0":
+ version: 11.28.0
+ resolution: "@carbon/icons-react@npm:11.28.0"
+ dependencies:
+ "@carbon/icon-helpers": ^10.44.0
+ "@carbon/telemetry": 0.1.0
+ prop-types: ^15.7.2
+ peerDependencies:
+ react: ">=16"
+ checksum: c52c63835b43feb3177c4a90161dfb5191a542be0dfe6a3196af96a675f58b75e6c82718413653a313829c04c06d68072a21be66f7d36e39566e61609debaabd
+ languageName: node
+ linkType: hard
+
"@carbon/layout@npm:^11.19.0, @carbon/layout@npm:^11.7.0":
version: 11.19.0
resolution: "@carbon/layout@npm:11.19.0"
@@ -2261,6 +2292,13 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/layout@npm:^11.20.0, @carbon/layout@npm:^11.20.1":
+ version: 11.20.1
+ resolution: "@carbon/layout@npm:11.20.1"
+ checksum: 8db3a31c08ab1fc62bd06404a72ca1e724c938d1ac73c708a63b06103fe054a5ab4294b1fba3471e3f55140ebe0e91e32872a2828dda73a32801fccb670acd35
+ languageName: node
+ linkType: hard
+
"@carbon/motion@npm:^11.15.0, @carbon/motion@npm:^11.5.0":
version: 11.15.0
resolution: "@carbon/motion@npm:11.15.0"
@@ -2268,7 +2306,14 @@ __metadata:
languageName: node
linkType: hard
-"@carbon/react@npm:^1.12.0, @carbon/react@npm:^1.33.1, @carbon/react@npm:^1.37.0":
+"@carbon/motion@npm:^11.16.0":
+ version: 11.16.1
+ resolution: "@carbon/motion@npm:11.16.1"
+ checksum: 1b7644fb19a9154a7d690128ed2fe831232576308dfeb30c694d533e5f8d357dbaf1b3bed7d4c274acb407d84d1ade087583d4f9aec4a8ac1aa9dfffb6922098
+ languageName: node
+ linkType: hard
+
+"@carbon/react@npm:^1.12.0, @carbon/react@npm:^1.33.1":
version: 1.40.0
resolution: "@carbon/react@npm:1.40.0"
dependencies:
@@ -2301,6 +2346,60 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/react@npm:~1.37.0":
+ version: 1.37.0
+ resolution: "@carbon/react@npm:1.37.0"
+ dependencies:
+ "@babel/runtime": ^7.18.3
+ "@carbon/feature-flags": ^0.16.0
+ "@carbon/icons-react": ^11.26.0
+ "@carbon/layout": ^11.19.0
+ "@carbon/styles": ^1.37.0
+ "@carbon/telemetry": 0.1.0
+ classnames: 2.3.2
+ copy-to-clipboard: ^3.3.1
+ downshift: 8.1.0
+ flatpickr: 4.6.9
+ invariant: ^2.2.3
+ lodash.debounce: ^4.0.8
+ lodash.findlast: ^4.5.0
+ lodash.isequal: ^4.5.0
+ lodash.omit: ^4.5.0
+ lodash.throttle: ^4.1.1
+ prop-types: ^15.7.2
+ react-is: ^18.2.0
+ use-resize-observer: ^6.0.0
+ wicg-inert: ^3.1.1
+ window-or-global: ^1.0.1
+ peerDependencies:
+ react: ^16.8.6 || ^17.0.1 || ^18.2.0
+ react-dom: ^16.8.6 || ^17.0.1 || ^18.2.0
+ sass: ^1.33.0
+ checksum: 40ba04d687462d178227080582a074ca6a7b7515f7f08f602fef9fd96bb90918e0051d5ce7adc9c9a5140bd9f724634a14fd06701afa23aa2bd023c6d14efd44
+ languageName: node
+ linkType: hard
+
+"@carbon/styles@npm:^1.37.0":
+ version: 1.47.0
+ resolution: "@carbon/styles@npm:1.47.0"
+ dependencies:
+ "@carbon/colors": ^11.20.0
+ "@carbon/feature-flags": ^0.16.0
+ "@carbon/grid": ^11.21.0
+ "@carbon/layout": ^11.20.0
+ "@carbon/motion": ^11.16.0
+ "@carbon/themes": ^11.28.0
+ "@carbon/type": ^11.25.0
+ "@ibm/plex": 6.0.0-next.6
+ peerDependencies:
+ sass: ^1.33.0
+ peerDependenciesMeta:
+ sass:
+ optional: true
+ checksum: 29dd2d1728bcff844632e242d4743706a74268c1b33e0b54b1f12f2811b86b5317a2a7022fa69c08a1eb494140d7d20e5c432db1b18bde6754a445d7bf857083
+ languageName: node
+ linkType: hard
+
"@carbon/styles@npm:^1.40.0":
version: 1.40.0
resolution: "@carbon/styles@npm:1.40.0"
@@ -2361,6 +2460,18 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/themes@npm:^11.28.0":
+ version: 11.28.0
+ resolution: "@carbon/themes@npm:11.28.0"
+ dependencies:
+ "@carbon/colors": ^11.20.0
+ "@carbon/layout": ^11.20.0
+ "@carbon/type": ^11.25.0
+ color: ^4.0.0
+ checksum: 52bc43b1b5ee846afc870c1898fadd3efe258fa66cb0e66672a1e20179c3833d6e517be433b339f6538887593342aba27f3130c0c3a61646c505eb16b24e06c2
+ languageName: node
+ linkType: hard
+
"@carbon/type@npm:^11.10.0, @carbon/type@npm:^11.24.0":
version: 11.24.0
resolution: "@carbon/type@npm:11.24.0"
@@ -2371,6 +2482,16 @@ __metadata:
languageName: node
linkType: hard
+"@carbon/type@npm:^11.25.0":
+ version: 11.25.1
+ resolution: "@carbon/type@npm:11.25.1"
+ dependencies:
+ "@carbon/grid": ^11.21.1
+ "@carbon/layout": ^11.20.1
+ checksum: 5184b9cddf050d06dbc3a369400c149e594cd281e090eb0fea972ef964b741ca94c20b828cb6c138be0812861d335d0abbabfe78b368483a5a97bf2ad7e1fc68
+ languageName: node
+ linkType: hard
+
"@carbon/utils-position@npm:^1.1.4":
version: 1.1.4
resolution: "@carbon/utils-position@npm:1.1.4"
@@ -4267,27 +4388,28 @@ __metadata:
languageName: node
linkType: hard
-"@openmrs/esm-api@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-api@npm:5.2.1-pre.1168"
+"@openmrs/esm-api@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-api@npm:5.3.3-pre.1404"
dependencies:
"@types/fhir": 0.0.31
lodash-es: ^4.17.21
peerDependencies:
"@openmrs/esm-config": 5.x
"@openmrs/esm-error-handling": 5.x
+ "@openmrs/esm-navigation": 5.x
"@openmrs/esm-offline": 5.x
- checksum: 7d80245995dd6541c7cab36fbe1b28335e42fd955d8daf62a1f86fc5c2d748640f0c117fb232aabe26ffec5fb5a1959502657357f60ffab981e9a5d7d705522d
+ checksum: 875b3b199565cc44474190be1a10563956cd6e855594f9615ab1ba5b72ca0ab451129d87b1994ef293705cd3619d5264cdece57dc18a7363b4694305d5aaa3e6
languageName: node
linkType: hard
-"@openmrs/esm-app-shell@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-app-shell@npm:5.2.1-pre.1168"
+"@openmrs/esm-app-shell@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-app-shell@npm:5.3.3-pre.1404"
dependencies:
- "@carbon/react": ^1.37.0
- "@openmrs/esm-framework": 5.2.1-pre.1168
- "@openmrs/esm-styleguide": 5.2.1-pre.1168
+ "@carbon/react": ~1.37.0
+ "@openmrs/esm-framework": 5.3.3-pre.1404
+ "@openmrs/esm-styleguide": 5.3.3-pre.1404
dayjs: ^1.10.4
dexie: ^3.0.3
html-webpack-plugin: ^5.5.0
@@ -4301,7 +4423,7 @@ __metadata:
react-router-dom: ^6.3.0
rxjs: ^6.5.3
semver: ^7.3.4
- single-spa: ^5.9.2
+ single-spa: ^6.0.0
swc-loader: ^0.2.3
swr: ^2.2.2
systemjs: ^6.8.3
@@ -4312,55 +4434,44 @@ __metadata:
workbox-strategies: ^6.1.5
workbox-webpack-plugin: ^6.1.5
workbox-window: ^6.1.5
- checksum: 8cc7e727b002f4126ee6dfb4773aa4fa320c2fda54258f280bfa967fe717b0d5e5c6cb3d0f9df9064f54fa7f4d5ca3d8b9795730405c5c15ff92dd89ef4ce35f
+ checksum: 03669949fab620a034e9835764e44afb395dbc3feb310cad336a11743a64b91676d8d40816edbbddab85aaee3689796a6d55c3620f14b2e9b852774712e0d44f
languageName: node
linkType: hard
-"@openmrs/esm-breadcrumbs@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-breadcrumbs@npm:5.2.1-pre.1168"
- dependencies:
- path-to-regexp: 6.1.0
- peerDependencies:
- "@openmrs/esm-state": 5.x
- checksum: a86e86e69e491a27a749c5b949e334b90ee3ff63b2a3583a208ed95da043f94108711f1b1ae21acb0222e53ca42bbbe06e2ba11d3beeece75889b8dc2504d601
- languageName: node
- linkType: hard
-
-"@openmrs/esm-config@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-config@npm:5.2.1-pre.1168"
+"@openmrs/esm-config@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-config@npm:5.3.3-pre.1404"
dependencies:
ramda: ^0.26.1
peerDependencies:
"@openmrs/esm-globals": 5.x
"@openmrs/esm-state": 5.x
single-spa: 5.x
- checksum: 883d5b52c7997f63f86898b0e43f034edf9332c7fdc9eb4c125a8440d9f2a32516d0c4272e565e320889d1ec9cb683062545984d3a2cb912f83220c79dd7050d
+ checksum: 93a61dc50091f19f8a92dd2575950364b0d58dca7c4d88dabaf11e39bee6bd0d008173cdf1cd60d9e622b639717b99791b8fa8a47395cc924b784c5b8d03ca75
languageName: node
linkType: hard
-"@openmrs/esm-dynamic-loading@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-dynamic-loading@npm:5.2.1-pre.1168"
+"@openmrs/esm-dynamic-loading@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-dynamic-loading@npm:5.3.3-pre.1404"
peerDependencies:
"@openmrs/esm-globals": 5.x
- checksum: a1b1e0042b48d4d28bbc58c6287f997dfffcdb259ab749e8638f5f4aabcc714d36b0af0698245d114ab13cb432fc7bf0d9a828de0896eec78034e664ef396d67
+ checksum: 932af656d8c6d70a1731ef23f08446e2747b89d41e82ebfa1f2d88e227b083e578dd7eb096ecbad0cfb5b877e087287589f060c5a7794f71ae048614d6145e37
languageName: node
linkType: hard
-"@openmrs/esm-error-handling@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-error-handling@npm:5.2.1-pre.1168"
+"@openmrs/esm-error-handling@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-error-handling@npm:5.3.3-pre.1404"
peerDependencies:
"@openmrs/esm-globals": 5.x
- checksum: 2c7d90d03aad3fae75b8b19b9cc3a4a8ea048d459ceac74f92819cc7afd36aefb164a27e0e4381487cb95ea84f1cd040df8b685a35764d54ee149be4aa1d1578
+ checksum: 7045047385a3486c89579f5fcb747df86f7185b30cedddd7eeb73fd110ad3d3e330dac11ba2af0dfff45e26f4392d679e1e1f335c72d09c7b0f6ff16a4e23d7d
languageName: node
linkType: hard
-"@openmrs/esm-extensions@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-extensions@npm:5.2.1-pre.1168"
+"@openmrs/esm-extensions@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-extensions@npm:5.3.3-pre.1404"
dependencies:
lodash-es: ^4.17.21
peerDependencies:
@@ -4369,20 +4480,20 @@ __metadata:
"@openmrs/esm-feature-flags": 5.x
"@openmrs/esm-state": 5.x
single-spa: 5.x
- checksum: 73255c4cd7013a5f8642919c6c83ec851a7308e629d6853d8df1dc7c0740c0aa6c4940830f62e1cd991747f1a242055580fe10efd265b5c1d4b7a15afda4fb5f
+ checksum: a1a6264a70aa18ee1603005d295cb773e3cd2d8488721018ab5e859231fb2e668a2ea7b240bb10e8d759411431dea080dca5602948361aca8685ef554c059759
languageName: node
linkType: hard
-"@openmrs/esm-feature-flags@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-feature-flags@npm:5.2.1-pre.1168"
+"@openmrs/esm-feature-flags@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-feature-flags@npm:5.3.3-pre.1404"
dependencies:
ramda: ^0.26.1
peerDependencies:
"@openmrs/esm-globals": 5.x
"@openmrs/esm-state": 5.x
single-spa: 5.x
- checksum: e8bfa9c5c12e1e4dd73ecb1da98064c6ab2150add5f542da574207c963932b6a9cccd086373dbadcfec8298ffaba0efea6862f1e298b68821be9bcdc56ef7d26
+ checksum: 011792fefea3cb069f63492501ee55353708398dfcb523916110198d7417a898993f7e12d8c84f17ab3b90c210433356a342fcd58481a3040d4d70d8af311184
languageName: node
linkType: hard
@@ -4477,23 +4588,24 @@ __metadata:
languageName: unknown
linkType: soft
-"@openmrs/esm-framework@npm:5.2.1-pre.1168, @openmrs/esm-framework@npm:next":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-framework@npm:5.2.1-pre.1168"
- dependencies:
- "@openmrs/esm-api": 5.2.1-pre.1168
- "@openmrs/esm-breadcrumbs": 5.2.1-pre.1168
- "@openmrs/esm-config": 5.2.1-pre.1168
- "@openmrs/esm-dynamic-loading": 5.2.1-pre.1168
- "@openmrs/esm-error-handling": 5.2.1-pre.1168
- "@openmrs/esm-extensions": 5.2.1-pre.1168
- "@openmrs/esm-feature-flags": 5.2.1-pre.1168
- "@openmrs/esm-globals": 5.2.1-pre.1168
- "@openmrs/esm-offline": 5.2.1-pre.1168
- "@openmrs/esm-react-utils": 5.2.1-pre.1168
- "@openmrs/esm-state": 5.2.1-pre.1168
- "@openmrs/esm-styleguide": 5.2.1-pre.1168
- "@openmrs/esm-utils": 5.2.1-pre.1168
+"@openmrs/esm-framework@npm:5.3.3-pre.1404, @openmrs/esm-framework@npm:next":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-framework@npm:5.3.3-pre.1404"
+ dependencies:
+ "@openmrs/esm-api": 5.3.3-pre.1404
+ "@openmrs/esm-config": 5.3.3-pre.1404
+ "@openmrs/esm-dynamic-loading": 5.3.3-pre.1404
+ "@openmrs/esm-error-handling": 5.3.3-pre.1404
+ "@openmrs/esm-extensions": 5.3.3-pre.1404
+ "@openmrs/esm-feature-flags": 5.3.3-pre.1404
+ "@openmrs/esm-globals": 5.3.3-pre.1404
+ "@openmrs/esm-navigation": 5.3.3-pre.1404
+ "@openmrs/esm-offline": 5.3.3-pre.1404
+ "@openmrs/esm-react-utils": 5.3.3-pre.1404
+ "@openmrs/esm-routes": 5.3.3-pre.1404
+ "@openmrs/esm-state": 5.3.3-pre.1404
+ "@openmrs/esm-styleguide": 5.3.3-pre.1404
+ "@openmrs/esm-utils": 5.3.3-pre.1404
dayjs: ^1.10.7
peerDependencies:
dayjs: 1.x
@@ -4504,7 +4616,7 @@ __metadata:
rxjs: 6.x
single-spa: 5.x
swr: 2.x
- checksum: 035c0e92d54bcd0e003394946cfb4fff6f71283da880544a14bd6ef3eea1cbc2793b6ff8d390834bdc6ca4f07d1bddb0dfb6f1a8f15dff94a06910ddaad41f14
+ checksum: 3e90fbf513e134bfd3ca7784a7518831d4b4aaf339690ce27856d3d13a05c7c2a574085930bec42d305dccf4857b7385e253cc9264f1d783245605e76c4ea93a
languageName: node
linkType: hard
@@ -4530,18 +4642,29 @@ __metadata:
languageName: unknown
linkType: soft
-"@openmrs/esm-globals@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-globals@npm:5.2.1-pre.1168"
+"@openmrs/esm-globals@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-globals@npm:5.3.3-pre.1404"
peerDependencies:
single-spa: 5.x
- checksum: 8ee32c7fc5b4b5484a8be4d109bfbc27d991376e50d1a5bd4983920d79e7558d6dece9e3ce9cbb6319e737b285126a808d2555e510f1ed4f96c86a2730675ba5
+ checksum: 1a378c4246a2aff8e8e1eaf2ac576c03af2aa642f5a3c33f8543eb348a94987f87999a17f6c743e4b2b5ae35110d9cba402f3701f3185a338fe40246f8b127b0
+ languageName: node
+ linkType: hard
+
+"@openmrs/esm-navigation@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-navigation@npm:5.3.3-pre.1404"
+ dependencies:
+ path-to-regexp: 6.1.0
+ peerDependencies:
+ "@openmrs/esm-state": 5.x
+ checksum: e510862e5d29657319c1869eb724ac708f5fbe57870a9ddf5a39d9e9b546426e717406255267354b75bbd22fc0300e2b50fac7d2fc78914d677a559f5b94718f
languageName: node
linkType: hard
-"@openmrs/esm-offline@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-offline@npm:5.2.1-pre.1168"
+"@openmrs/esm-offline@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-offline@npm:5.3.3-pre.1404"
dependencies:
dexie: ^3.0.3
lodash-es: ^4.17.21
@@ -4553,7 +4676,7 @@ __metadata:
"@openmrs/esm-state": 5.x
"@openmrs/esm-styleguide": 5.x
rxjs: 6.x
- checksum: b9605c88deabbcdbb18b03b15daa335a10f970611a7c2e9b9af26420a7dc4ac713d514617de73067512892365dc9bdacf7e9aca299493782e1a0b27cfb44a6a4
+ checksum: b492415acece28e1ae177ea9b2c5e0bf2d243dd009d33fbe69d93a0954fe9924e20986aadc7ffd373137390022d0839ba3a33e86398f47a4d22a2fed37c51621
languageName: node
linkType: hard
@@ -4963,18 +5086,19 @@ __metadata:
languageName: unknown
linkType: soft
-"@openmrs/esm-react-utils@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-react-utils@npm:5.2.1-pre.1168"
+"@openmrs/esm-react-utils@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-react-utils@npm:5.3.3-pre.1404"
dependencies:
lodash-es: ^4.17.21
- single-spa-react: ~5.0.0
+ single-spa-react: ^6.0.0
peerDependencies:
"@openmrs/esm-api": 5.x
"@openmrs/esm-config": 5.x
"@openmrs/esm-error-handling": 5.x
"@openmrs/esm-extensions": 5.x
"@openmrs/esm-globals": 5.x
+ "@openmrs/esm-navigation": 5.x
dayjs: 1.x
i18next: 19.x
react: 18.x
@@ -4982,27 +5106,37 @@ __metadata:
react-i18next: 11.x
rxjs: 6.x
swr: 2.x
- checksum: bdbc8dc4b65bc5eb36f25dda684c1ac29a1dee2bd904852f7cbbc8d5af539c0e3155401d570e678029a6539918bad4cdddc3db75048757054e393aaae3c54da7
+ checksum: 5b1e7f1359e58d83bd05480fa33fc19a3b94d7415f8fdcc2e6ec0943f4a423e523ea64586110f7d0c5ebc910f68ee5716eb1f69ce3f2dbc5394f7ce2746e657b
languageName: node
linkType: hard
-"@openmrs/esm-state@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-state@npm:5.2.1-pre.1168"
+"@openmrs/esm-routes@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-routes@npm:5.3.3-pre.1404"
+ peerDependencies:
+ "@openmrs/esm-globals": 5.x
+ "@openmrs/esm-utils": 5.x
+ checksum: 7ddf83879362fd9680bae4c43598abac9433f98d608de869e6ad4476050758acc63868752520e7cf11c2392e9892e489fb0277e3c819afe78d081f73c1d74904
+ languageName: node
+ linkType: hard
+
+"@openmrs/esm-state@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-state@npm:5.3.3-pre.1404"
dependencies:
zustand: ^4.3.6
peerDependencies:
"@openmrs/esm-globals": 5.x
- checksum: a091c43f49feb1cf8e60fa9d5daf85696e0c7a22b0813fcefd54cb772ed34f9b28bacb9075d3e15dc9ceaa07542ac6041d0a093e6a750ffe1c6b1d6217ad2358
+ checksum: 989795e206c0f2ccb375a9ae9c2304803e22af4113f51ae974a61f5be31dab7b2edaf063fe653276573bf37bde980fd9b51abce7861df313308d9b5124831a8f
languageName: node
linkType: hard
-"@openmrs/esm-styleguide@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-styleguide@npm:5.2.1-pre.1168"
+"@openmrs/esm-styleguide@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-styleguide@npm:5.3.3-pre.1404"
dependencies:
"@carbon/charts": ^1.12.0
- "@carbon/react": ^1.37.0
+ "@carbon/react": ~1.37.0
"@internationalized/date": ^3.5.0
"@react-spectrum/datepicker": ^3.8.0
"@react-spectrum/provider": ^3.9.0
@@ -5018,20 +5152,20 @@ __metadata:
react: 18.x
react-dom: 18.x
rxjs: 6.x
- checksum: 2afa4a88b6dbf99d3298ceb4af54b21d1b04cc7384f60e9049964e1987946e3b50f40e5925b7b30d2cd5481d6f337978c7b1868e786c713f577f01249a367362
+ checksum: 93540fa2029ea30d7bc0df2d52fb69972831de5d442bcc02c238329e3a132affc496291aea2dbd143c6e30223da3175c0aaa2aaec736d2eec319360946e1c863
languageName: node
linkType: hard
-"@openmrs/esm-utils@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/esm-utils@npm:5.2.1-pre.1168"
+"@openmrs/esm-utils@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/esm-utils@npm:5.3.3-pre.1404"
dependencies:
semver: 7.3.2
peerDependencies:
dayjs: 1.x
i18next: 19.x
rxjs: 6.x
- checksum: a7062351221814e061dd0304692b36fc5e6c0512531d28e9342c31ce84c229bbe0d66099bef0d5f582bc1e0c4c4bad08404d09388cbc7cb29f6f14468a194651
+ checksum: 5ad86c28113da2a03178ee5a77fce02b42b98f5b73b5a0c439875430d03fee8a1d6a5338a6daa6132c9bd95230d654a663003b19f8e201eba18782d8c59d45b6
languageName: node
linkType: hard
@@ -5111,9 +5245,9 @@ __metadata:
languageName: node
linkType: hard
-"@openmrs/webpack-config@npm:5.2.1-pre.1168":
- version: 5.2.1-pre.1168
- resolution: "@openmrs/webpack-config@npm:5.2.1-pre.1168"
+"@openmrs/webpack-config@npm:5.3.3-pre.1404":
+ version: 5.3.3-pre.1404
+ resolution: "@openmrs/webpack-config@npm:5.3.3-pre.1404"
dependencies:
"@swc/core": ^1.3.58
clean-webpack-plugin: ^4.0.0
@@ -5130,7 +5264,7 @@ __metadata:
webpack-stats-plugin: ^1.0.3
peerDependencies:
webpack: 5.x
- checksum: a8893c01c706f91af391ed8a605ccb082c066b542984184c1381b587a198cd5452ae55856dd19ba9465e481f7bcc86647bb3224eb4ef038662d7d2b8b1cf1799
+ checksum: fcfdce97969513037dab7ab3ddd0cd1beb973d68b8e3dc79c9c35658898557f3a21f2e29266659ed203a5b934801569e71a98e78068ebe819fc8ad5812fb88d2
languageName: node
linkType: hard
@@ -10078,6 +10212,13 @@ __metadata:
languageName: node
linkType: hard
+"compute-scroll-into-view@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "compute-scroll-into-view@npm:2.0.4"
+ checksum: f3d1db9276c16af42155b572750514939cd0ab0a0f46498906f6811c5b654c5ff2b3f9bfd65958e57439e000a5e1ae092eb96b9e153d194a73e52ffd2380550c
+ languageName: node
+ linkType: hard
+
"compute-scroll-into-view@npm:^3.0.3":
version: 3.1.0
resolution: "compute-scroll-into-view@npm:3.1.0"
@@ -11817,6 +11958,21 @@ __metadata:
languageName: node
linkType: hard
+"downshift@npm:8.1.0":
+ version: 8.1.0
+ resolution: "downshift@npm:8.1.0"
+ dependencies:
+ "@babel/runtime": ^7.14.8
+ compute-scroll-into-view: ^2.0.4
+ prop-types: ^15.7.2
+ react-is: ^17.0.2
+ tslib: ^2.3.0
+ peerDependencies:
+ react: ">=16.12.0"
+ checksum: 5ede6190dc85ad295f623b30d3ad035a83b9ef5753084096e71e6fad5276a9abd3b1c1a26583958368e4e7fe14a40ef8b5a246f9f6eec058c4eba30a5104539d
+ languageName: node
+ linkType: hard
+
"downshift@npm:8.2.1":
version: 8.2.1
resolution: "downshift@npm:8.2.1"
@@ -18636,6 +18792,13 @@ __metadata:
languageName: node
linkType: hard
+"node-watch@npm:^0.7.4":
+ version: 0.7.4
+ resolution: "node-watch@npm:0.7.4"
+ checksum: effca2aa3575afdc8caae2a422d5738ecf8322962f051574c5dd3c1a399b4bf188c3ad3cb32890fc5e530604f0f037bc0160ec94b37f8d3ae4b76006a98f9df3
+ languageName: node
+ linkType: hard
+
"nopt@npm:^6.0.0":
version: 6.0.0
resolution: "nopt@npm:6.0.0"
@@ -19248,16 +19411,18 @@ __metadata:
linkType: hard
"openmrs@npm:next":
- version: 5.2.1-pre.1168
- resolution: "openmrs@npm:5.2.1-pre.1168"
+ version: 5.3.3-pre.1404
+ resolution: "openmrs@npm:5.3.3-pre.1404"
dependencies:
- "@openmrs/esm-app-shell": 5.2.1-pre.1168
- "@openmrs/webpack-config": 5.2.1-pre.1168
+ "@carbon/icons-react": 11.26.0
+ "@openmrs/esm-app-shell": 5.3.3-pre.1404
+ "@openmrs/webpack-config": 5.3.3-pre.1404
"@pnpm/npm-conf": ^2.1.0
"@swc/core": ^1.3.58
autoprefixer: ^10.4.2
axios: ^0.21.1
browserslist-config-openmrs: ^1.0.1
+ chalk: ^4.1.2
copy-webpack-plugin: ^11.0.0
cssnano: ^5.0.16
ejs: ^3.1.8
@@ -19265,6 +19430,7 @@ __metadata:
html-webpack-plugin: ^5.5.0
inquirer: ^7.3.3
mini-css-extract-plugin: ^2.4.5
+ node-watch: ^0.7.4
npm-registry-fetch: ^14.0.3
pacote: ^15.0.0
postcss: ^8.4.6
@@ -19281,7 +19447,7 @@ __metadata:
yargs: ^17.6.2
bin:
openmrs: ./dist/cli.js
- checksum: 9c4823e604215ab00ccfdc4cbe93baf92f905a07b1a15015ef044903280125a60ba4b9e7bc80d245e9f7d2d961e99761e9472e356d911cb06a5c94a4ee591b73
+ checksum: e369415883977c3cc8aea88dd2ef29f614f4a18bf7e751d414731b1428ab97343da4eb44e815242863c4d53807e7916f1bed4d71b18e62506be3645758349bd9
languageName: node
linkType: hard
@@ -20976,7 +21142,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^17.0.0, react-is@npm:^17.0.1":
+"react-is@npm:^17.0.0, react-is@npm:^17.0.1, react-is@npm:^17.0.2":
version: 17.0.2
resolution: "react-is@npm:17.0.2"
checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8
@@ -22403,9 +22569,9 @@ __metadata:
languageName: node
linkType: hard
-"single-spa-react@npm:~5.0.0":
- version: 5.0.2
- resolution: "single-spa-react@npm:5.0.2"
+"single-spa-react@npm:^6.0.0":
+ version: 6.0.1
+ resolution: "single-spa-react@npm:6.0.1"
dependencies:
browserslist-config-single-spa: ^1.0.1
peerDependencies:
@@ -22417,14 +22583,14 @@ __metadata:
optional: true
"@types/react-dom":
optional: true
- checksum: 3c2503384ab27aed7e4f9f5c6a40cf5aae120cae1749244aba12647159354c143ac03669bfc41a43533077c874866b7042dad9463abe253da198da3f200d8fe1
+ checksum: aefe69502735a5a4062a0539d61e2b1e84c50146e333838d688ee3f511f101cc07f94daa27ab399e5286a2c3399278e5da8c87fdc5ca36648504de2b338e45b6
languageName: node
linkType: hard
-"single-spa@npm:^5.9.2":
- version: 5.9.4
- resolution: "single-spa@npm:5.9.4"
- checksum: 8547b5db3d1c6788f44833b1bf7a89697a72a4ca4b801c3f9ddbf4e2949a40bc1d9e9a24650460c7a16f5a668d4e332fc237acacb84f329031815c19578a5907
+"single-spa@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "single-spa@npm:6.0.0"
+ checksum: 4efc6248e5ba3b2c02090869a1d85c8fdb77994465d760233ff58462d35614503fefcb2330999b15ef7e43508181939a41628410912f9a1cc01860b192580d11
languageName: node
linkType: hard