From f4e486fcc7932caad6ab001d988c62fd0901e0ca Mon Sep 17 00:00:00 2001 From: Usama Idriss Kakumba Date: Wed, 7 Aug 2024 13:45:38 +0300 Subject: [PATCH] feat: add patient notes history --- .../src/hooks/useEmrConfiguration.ts | 13 +- packages/esm-ward-app/src/types/index.ts | 10 + .../ward-patient-card.component.tsx | 2 +- .../form/notes-form.component.tsx | 33 +-- .../form/notes-form.resource.ts | 13 -- .../history/note.component.tsx | 51 +++++ .../history/notes-container.component.tsx | 60 +++++ .../history/notes-container.test.tsx | 110 +++++++++ .../ward-patient-notes/history/styles.scss | 62 +++++ .../ward-patient-notes/notes.resource.ts | 66 ++++++ .../ward-patient-notes/notes.workspace.tsx | 33 ++- .../ward-patient-notes/types.ts | 45 +++- yarn.lock | 212 +++++++++--------- 13 files changed, 560 insertions(+), 150 deletions(-) delete mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.resource.ts create mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/note.component.tsx create mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.component.tsx create mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.test.tsx create mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/styles.scss create mode 100644 packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.resource.ts diff --git a/packages/esm-ward-app/src/hooks/useEmrConfiguration.ts b/packages/esm-ward-app/src/hooks/useEmrConfiguration.ts index 967ea01c6..f3936f026 100644 --- a/packages/esm-ward-app/src/hooks/useEmrConfiguration.ts +++ b/packages/esm-ward-app/src/hooks/useEmrConfiguration.ts @@ -1,16 +1,7 @@ -import { type FetchResponse, openmrsFetch, type OpenmrsResource, restBaseUrl } from '@openmrs/esm-framework'; +import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import { useMemo } from 'react'; import useSWRImmutable from 'swr/immutable'; - -interface EmrApiConfigurationResponse { - admissionEncounterType: OpenmrsResource; - clinicianEncounterRole: OpenmrsResource; - consultFreeTextCommentsConcept: OpenmrsResource; - visitNoteEncounterType: OpenmrsResource; - transferWithinHospitalEncounterType: OpenmrsResource; - // There are many more keys to this object, but we only need these for now - // Add more keys as needed -} +import { type EmrApiConfigurationResponse } from '../types'; export default function useEmrConfiguration() { const swrData = useSWRImmutable>( diff --git a/packages/esm-ward-app/src/types/index.ts b/packages/esm-ward-app/src/types/index.ts index f56540aec..8f683a1b1 100644 --- a/packages/esm-ward-app/src/types/index.ts +++ b/packages/esm-ward-app/src/types/index.ts @@ -183,3 +183,13 @@ export interface ObsPayload { value: string; }>; } + +export interface EmrApiConfigurationResponse { + admissionEncounterType: OpenmrsResource; + clinicianEncounterRole: OpenmrsResource; + consultFreeTextCommentsConcept: OpenmrsResource; + visitNoteEncounterType: OpenmrsResource; + transferWithinHospitalEncounterType: OpenmrsResource; + // There are many more keys to this object, but we only need these for now + // Add more keys as needed +} diff --git a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx index 4b7b128c0..0f828ef67 100644 --- a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { type Encounter, type Bed } from '../types'; +import { type Bed, type Encounter } from '../types'; import { WardPatientCardElement } from './ward-patient-card-element.component'; import { useCurrentWardCardConfig } from '../hooks/useCurrentWardCardConfig'; import styles from './ward-patient-card.scss'; diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx index 04c90e3f6..620841cd2 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx @@ -13,10 +13,10 @@ import { translateFrom, useSession, } from '@openmrs/esm-framework'; -import { savePatientNote } from './notes-form.resource'; import styles from './notes-form.scss'; import { moduleName } from '../../../constant'; -import useEmrConfiguration from '../../../hooks/useEmrConfiguration'; +import { savePatientNote } from '../notes.resource'; +import { type EmrApiConfigurationResponse } from '../../../types'; type NotesFormData = z.infer; @@ -29,14 +29,19 @@ const noteFormSchema = z.object({ interface PatientNotesFormProps extends DefaultWorkspaceProps { patientUuid: PatientUuid; + emrConfiguration: EmrApiConfigurationResponse; + isLoadingEmrConfiguration: boolean; + errorFetchingEmrConfiguration: Error; } const PatientNotesForm: React.FC = ({ closeWorkspaceWithSavedChanges, patientUuid, promptBeforeClosing, + emrConfiguration, + isLoadingEmrConfiguration, + errorFetchingEmrConfiguration, }) => { - const { emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useEmrConfiguration(); const { t } = useTranslation(); const session = useSession(); const [isSubmitting, setIsSubmitting] = useState(false); @@ -120,18 +125,16 @@ const PatientNotesForm: React.FC = ({ return (
{errorFetchingEmrConfiguration && ( -
- -
+ )} diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.resource.ts b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.resource.ts deleted file mode 100644 index 3c00f34f9..000000000 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/form/notes-form.resource.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; -import { type EncounterPayload } from '../../../types'; - -export function savePatientNote(payload: EncounterPayload, abortController: AbortController = new AbortController()) { - return openmrsFetch(`${restBaseUrl}/encounter`, { - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - body: payload, - signal: abortController.signal, - }); -} diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/note.component.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/note.component.tsx new file mode 100644 index 000000000..64ac4b116 --- /dev/null +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/note.component.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { type PatientNote } from '../types'; +import { SkeletonText, Tag, Tile } from '@carbon/react'; +import dayjs from 'dayjs'; +import styles from './styles.scss'; + +export const InPatientNoteSkeleton: React.FC = () => { + return ( + +
+ + +
+ + + +
+ ); +}; + +interface InPatientNoteProps { + note: PatientNote; +} + +const InPatientNote: React.FC = ({ note }) => { + const formattedDate = note.encounterNoteRecordedAt + ? dayjs(note.encounterNoteRecordedAt).format('dddd, D MMM YYYY') + : ''; + const formattedTime = note.encounterNoteRecordedAt ? dayjs(note.encounterNoteRecordedAt).format('HH:mm') : ''; + + return ( + +
+ Nurse’s note + + {formattedDate}, {formattedTime} + +
+ {note.diagnoses && + note.diagnoses.split(',').map((diagnosis, index) => ( + + {diagnosis.trim()} + + ))} +
{note.encounterNote}
+
{note.encounterProvider}
+
+ ); +}; + +export default InPatientNote; diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.component.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.component.tsx new file mode 100644 index 000000000..c6e378981 --- /dev/null +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.component.tsx @@ -0,0 +1,60 @@ +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { isDesktop, type PatientUuid, useLayoutType } from '@openmrs/esm-framework'; +import { usePatientNotes } from '../notes.resource'; +import InPatientNote, { InPatientNoteSkeleton } from './note.component'; +import { type EmrApiConfigurationResponse } from '../../../types'; +import styles from './styles.scss'; +import { Dropdown } from '@carbon/react'; + +interface PatientNotesHistoryProps { + patientUuid: PatientUuid; + emrConfiguration: EmrApiConfigurationResponse; + isLoadingEmrConfiguration: boolean; +} + +const PatientNotesHistory: React.FC = ({ + patientUuid, + emrConfiguration, + isLoadingEmrConfiguration, +}) => { + const { t } = useTranslation(); + const desktopLayout = isDesktop(useLayoutType()); + const [filter, setFilter] = useState(''); + const { patientNotes, isLoadingPatientNotes } = usePatientNotes( + patientUuid, + emrConfiguration?.visitNoteEncounterType?.uuid, + emrConfiguration?.consultFreeTextCommentsConcept.uuid, + ); + + const handleEncounterTypeChange = ({ selectedItem }) => setFilter(selectedItem); + + const isLoading = isLoadingPatientNotes || isLoadingEmrConfiguration; + + return ( +
+
+
History
+
+ +
+
+ {isLoading ? [1, 2, 3, 4].map((item, index) => ) : null} + {patientNotes.map((patientNote) => ( + + ))} +
+ ); +}; + +export default PatientNotesHistory; diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.test.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.test.tsx new file mode 100644 index 000000000..c5a16fb23 --- /dev/null +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/notes-container.test.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { render, screen } from '@testing-library/react'; +import { createErrorHandler, ResponsiveWrapper, showSnackbar, translateFrom, useSession } from '@openmrs/esm-framework'; +import { savePatientNote } from './notes-form.resource'; +import PatientNotesForm from './notes-form.component'; +import { emrConfigurationMock, mockPatient, mockSession } from '__mocks__'; +import useEmrConfiguration from '../../../hooks/useEmrConfiguration'; + +const testProps = { + patientUuid: mockPatient.uuid, + closeWorkspace: jest.fn(), + closeWorkspaceWithSavedChanges: jest.fn(), + promptBeforeClosing: jest.fn(), + setTitle: jest.fn(), + onWorkspaceClose: jest.fn(), + setOnCloseCallback: jest.fn(), +}; + +const mockSavePatientNote = savePatientNote as jest.Mock; +const mockedShowSnackbar = jest.mocked(showSnackbar); +const mockedCreateErrorHandler = jest.mocked(createErrorHandler); +const mockedTranslateFrom = jest.mocked(translateFrom); +const mockedResponsiveWrapper = jest.mocked(ResponsiveWrapper); +const mockedUseSession = jest.mocked(useSession); + +jest.mock('./notes-form.resource', () => ({ + savePatientNote: jest.fn(), +})); + +jest.mock('../../../hooks/useEmrConfiguration', () => jest.fn()); + +const mockedUseEmrConfiguration = jest.mocked(useEmrConfiguration); + +mockedUseEmrConfiguration.mockReturnValue({ + emrConfiguration: emrConfigurationMock, + mutateEmrConfiguration: jest.fn(), + isLoadingEmrConfiguration: false, + errorFetchingEmrConfiguration: null, +}); + +test('renders the visit notes form with all the relevant fields and values', () => { + renderWardPatientNotesForm(); + + expect(screen.getByRole('textbox', { name: /Write your notes/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Save/i })).toBeInTheDocument(); +}); + +test('renders a success snackbar upon successfully recording a visit note', async () => { + const successPayload = { + encounterType: emrConfigurationMock.visitNoteEncounterType.uuid, + location: undefined, + obs: expect.arrayContaining([ + { + concept: { display: '', uuid: '162169AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' }, + value: 'Sample clinical note', + }, + ]), + patient: mockPatient.uuid, + }; + + mockSavePatientNote.mockResolvedValue({ status: 201, body: 'Condition created' }); + + renderWardPatientNotesForm(); + + const note = screen.getByRole('textbox', { name: /Write your notes/i }); + await userEvent.clear(note); + await userEvent.type(note, 'Sample clinical note'); + expect(note).toHaveValue('Sample clinical note'); + + const submitButton = screen.getByRole('button', { name: /Save/i }); + await userEvent.click(submitButton); + + expect(mockSavePatientNote).toHaveBeenCalledTimes(1); + expect(mockSavePatientNote).toHaveBeenCalledWith(expect.objectContaining(successPayload), new AbortController()); +}); + +test('renders an error snackbar if there was a problem recording a visit note', async () => { + const error = { + message: 'Internal Server Error', + response: { + status: 500, + statusText: 'Internal Server Error', + }, + }; + + mockSavePatientNote.mockRejectedValueOnce(error); + renderWardPatientNotesForm(); + + const note = screen.getByRole('textbox', { name: /Write your notes/i }); + await userEvent.clear(note); + await userEvent.type(note, 'Sample clinical note'); + expect(note).toHaveValue('Sample clinical note'); + + const submitButton = screen.getByRole('button', { name: /Save/i }); + + await userEvent.click(submitButton); + + expect(mockedShowSnackbar).toHaveBeenCalledWith({ + isLowContrast: false, + kind: 'error', + subtitle: 'Internal Server Error', + title: 'Error saving patient note', + }); +}); + +function renderWardPatientNotesForm() { + mockedUseSession.mockReturnValue(mockSession); + render(); +} diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/styles.scss b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/styles.scss new file mode 100644 index 000000000..83bb93817 --- /dev/null +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/history/styles.scss @@ -0,0 +1,62 @@ +@use '@carbon/layout'; +@use '@carbon/colors'; +@import '@carbon/styles/scss/type'; +@import '@openmrs/esm-styleguide/src/vars'; + +.notesContainer { + margin: layout.$spacing-04; +} + +.notesContainerHeader { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + margin-top: layout.$spacing-05; + margin-bottom: layout.$spacing-02; +} + +.notesContainerTitle { + font-weight: 600; + font-size: layout.$spacing-05; + color: #393939; +} + +.noteTile { + padding: layout.$spacing-04; + margin-bottom: layout.$spacing-04; +} + +.noteHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: layout.$spacing-04; +} + +.noteProviderRole { + flex-grow: 0; + font-size: 0.875rem; + font-weight: 600; + color: $text-02; +} + +.noteBody { + font-size: 0.875rem; + color: $text-02; +} + +.noteDateAndTime { + font-size: layout.$spacing-04; + color: $text-02; +} + +.noteProviderName { + font-size: layout.$spacing-04; + margin-top: layout.$spacing-04; + color: $text-02; +} + +.noteSkeletonContainer { + height: layout.$spacing-13; +} diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.resource.ts b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.resource.ts new file mode 100644 index 000000000..43d17d22c --- /dev/null +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.resource.ts @@ -0,0 +1,66 @@ +import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; +import useSWR from 'swr'; +import { type PatientNote, type UsePatientNotes, type VisitEncountersFetchResponse } from './types'; +import { type EncounterPayload } from '../../types'; +import { useMemo } from 'react'; + +export function savePatientNote(payload: EncounterPayload, abortController: AbortController = new AbortController()) { + return openmrsFetch(`${restBaseUrl}/encounter`, { + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + body: payload, + signal: abortController.signal, + }); +} + +export function usePatientNotes(patientUuid: string, encounterType: string, conceptUuid: string): UsePatientNotes { + const customRepresentation = + 'custom:(uuid,display,encounterDatetime,patient,obs,' + + 'encounterProviders:(uuid,display,' + + 'encounterRole:(uuid,display),' + + 'provider:(uuid,person:(uuid,display))),' + + 'diagnoses'; + const encountersApiUrl = `${restBaseUrl}/encounter?patient=${patientUuid}&encounterType=${encounterType}&v=${customRepresentation}`; + + const { data, error, isLoading, isValidating, mutate } = useSWR, Error>( + patientUuid && encounterType ? encountersApiUrl : null, + openmrsFetch, + ); + + const patientNotes: Array | null = useMemo( + () => + data + ? data.data.results + .map((encounter) => { + const noteObs = encounter.obs.find((obs) => obs.concept.uuid === conceptUuid); + + return { + id: encounter.uuid, + diagnoses: encounter.diagnoses.map((d) => d.display).join(', '), + encounterDate: encounter.encounterDatetime, + encounterNote: noteObs ? noteObs.value : '', + encounterNoteRecordedAt: noteObs ? noteObs.obsDatetime : '', + encounterProvider: encounter.encounterProviders.map((ep) => ep.provider.person.display).join(', '), + encounterProviderRole: encounter.encounterProviders.map((ep) => ep.encounterRole.display).join(', '), + }; + }) + .sort( + (a, b) => new Date(b.encounterNoteRecordedAt).getTime() - new Date(a.encounterNoteRecordedAt).getTime(), + ) + : [], + [data, conceptUuid], + ); + + return useMemo( + () => ({ + patientNotes, + errorFetchingPatientNotes: error, + isLoadingPatientNotes: isLoading, + isValidatingPatientNotes: isValidating, + mutatePatientNotes: mutate, + }), + [patientNotes, isLoading, isValidating, mutate, error], + ); +} diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx index 7bec24dd9..f778699c3 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx @@ -2,22 +2,49 @@ import React, { useMemo } from 'react'; import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component'; import { type WardPatientNotesWorkspaceProps } from './types'; import PatientNotesForm from './form/notes-form.component'; +import PatientNotesHistory from './history/notes-container.component'; +import useEmrConfiguration from '../../hooks/useEmrConfiguration'; const WardPatientNotesWorkspace = (props: WardPatientNotesWorkspaceProps) => { - const { patient, visit, bed, admitted, encounterAssigningToCurrentInpatientLocation, firstAdmissionOrTransferEncounter, ...restWorkspaceProps } = props; - const wardPatient = { patient, visit, bed, admitted, encounterAssigningToCurrentInpatientLocation, firstAdmissionOrTransferEncounter }; + const { + patient, + visit, + bed, + admitted, + encounterAssigningToCurrentInpatientLocation, + firstAdmissionOrTransferEncounter, + ...restWorkspaceProps + } = props; + const { emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useEmrConfiguration(); + + const wardPatient = { + patient, + visit, + bed, + admitted, + encounterAssigningToCurrentInpatientLocation, + firstAdmissionOrTransferEncounter, + }; const notesFormState = useMemo( () => ({ patientUuid: patient?.uuid, + emrConfiguration, + isLoadingEmrConfiguration, + errorFetchingEmrConfiguration, ...restWorkspaceProps, }), - [patient, restWorkspaceProps], + [patient, restWorkspaceProps, errorFetchingEmrConfiguration, emrConfiguration, isLoadingEmrConfiguration], ); return (
+
); }; diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts index a12afe5ee..74d8d8d06 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts @@ -1,4 +1,47 @@ -import type { DefaultWorkspaceProps } from '@openmrs/esm-framework'; +import { type Concept, type DefaultWorkspaceProps, type OpenmrsResource } from '@openmrs/esm-framework'; import { type WardPatient } from '../../types'; export interface WardPatientNotesWorkspaceProps extends DefaultWorkspaceProps, WardPatient {} + +export interface VisitEncountersFetchResponse { + results: Array; +} + +export interface RESTPatientNote extends OpenmrsResource { + uuid: string; + display: string; + encounterDatetime: string; + encounterType: { name: string; uuid: string }; + encounterProviders: [{ encounterRole: { uuid: string; display: string }; provider: { person: { display: string } } }]; + location: { uuid: string; display: string; name: string }; + obs: Array; + diagnoses: Array; +} + +export interface PatientNote { + id: string; + diagnoses: string; + encounterDate: string; + encounterNote: string; + encounterNoteRecordedAt: string; + encounterProvider: string; + encounterProviderRole: string; +} + +export interface UsePatientNotes { + patientNotes: Array | null; + errorFetchingPatientNotes: Error; + isLoadingPatientNotes: boolean; + isValidatingPatientNotes?: boolean; + mutatePatientNotes: () => void; +} + +export interface ObsData { + concept: Concept; + value?: string | any; + groupMembers?: Array<{ + concept: Concept; + value?: string | any; + }>; + obsDatetime: string; +} diff --git a/yarn.lock b/yarn.lock index 5295e8bf9..54e4808aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2677,9 +2677,9 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/esm-api@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-api@npm:5.7.3-pre.2157" +"@openmrs/esm-api@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-api@npm:5.7.3-pre.2161" dependencies: "@types/fhir": "npm:0.0.31" lodash-es: "npm:^4.17.21" @@ -2688,17 +2688,17 @@ __metadata: "@openmrs/esm-error-handling": 5.x "@openmrs/esm-navigation": 5.x "@openmrs/esm-offline": 5.x - checksum: 10/fb47e930fa9029ca2c1eb8f8cc4a490dadb8cfabd6b99c3f8ec721b4906f0454e0f15209b1348745d9ecb5e041b2c32e8cd98e5d71255377e01bf7f70a0a2b9b + checksum: 10/d6603f657df643dc39e359223d750574c7863ad5226f0c4adb02df2eb22fa20949c0e996b94957857ce406a9c51d09aecd403ebcde66a4b6bd5b914a8b091693 languageName: node linkType: hard -"@openmrs/esm-app-shell@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-app-shell@npm:5.7.3-pre.2157" +"@openmrs/esm-app-shell@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-app-shell@npm:5.7.3-pre.2161" dependencies: "@carbon/react": "npm:~1.37.0" - "@openmrs/esm-framework": "npm:5.7.3-pre.2157" - "@openmrs/esm-styleguide": "npm:5.7.3-pre.2157" + "@openmrs/esm-framework": "npm:5.7.3-pre.2161" + "@openmrs/esm-styleguide": "npm:5.7.3-pre.2161" dayjs: "npm:^1.10.4" dexie: "npm:^3.0.3" html-webpack-plugin: "npm:^5.5.0" @@ -2723,7 +2723,7 @@ __metadata: workbox-strategies: "npm:^6.1.5" workbox-webpack-plugin: "npm:^6.1.5" workbox-window: "npm:^6.1.5" - checksum: 10/897b5f3bc74e521049f202d850f3abe65b6dcc08b1d0cf03f1f02893743f9434004af20ec28fb2e099784252975d3faa4552565adb17194fee9cf67713c24507 + checksum: 10/07d1408ada089eb9a814a02958305caf72559339d002f6aad100d68888b2835b7ee6605cc30baf59c38558c6af09b9ee9299e331316a083e7238aabca3113fa6 languageName: node linkType: hard @@ -2763,53 +2763,53 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/esm-config@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-config@npm:5.7.3-pre.2157" +"@openmrs/esm-config@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-config@npm:5.7.3-pre.2161" dependencies: ramda: "npm:^0.26.1" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x single-spa: 5.x - checksum: 10/f591650f8b8fc4061e8668c02831804bc6ed890c44ae312223fa98ea22f1ce2c80b8b5732736c07b6e2b637fd9466e194bc97b73a4e376cd9ebf7cc35809fe32 + checksum: 10/f650f6540cf33061d573fbc48c17317f272d768244f6416ecfbea1b27e739b4ec60d6b40196b4916a8d909092eb9281a3a9ca9eca2f4928d00c7c18aeeba792a languageName: node linkType: hard -"@openmrs/esm-context@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-context@npm:5.7.3-pre.2157" +"@openmrs/esm-context@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-context@npm:5.7.3-pre.2161" dependencies: immer: "npm:^10.0.4" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x - checksum: 10/a04bb335f4a7990974a5d6ab96eaeb78afa8f5396b38d05a028e20312ab222be99694fb94b23794f67357934d1be662592f0818f9a1a40edf1b7a26ae2e6f2cd + checksum: 10/2da63321c0820fe6509d53bcaae00320095276f1fca653919a758719ad8cf352979bbef70d2e3dd8128e95091c9672ef1acfe0ef47b548443fb7dc793af550ef languageName: node linkType: hard -"@openmrs/esm-dynamic-loading@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-dynamic-loading@npm:5.7.3-pre.2157" +"@openmrs/esm-dynamic-loading@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-dynamic-loading@npm:5.7.3-pre.2161" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-translations": 5.x - checksum: 10/7e8d18f6aeb30410bdfa24d3526556e3ffb5fa96064abc7da7966c39df209bce781d97ddf424d4d0bdfb8444109b4e3ea5219ef8adb61b755d7d1d0bbec40f07 + checksum: 10/7eb1317d5dda0bf5211cb144f298a41113536aaa22b23bfe7f19c7083a771a64a4e35dfacf17e6720e4e692c17dddf6829977c224ee4b374b96beacd917c4b58 languageName: node linkType: hard -"@openmrs/esm-error-handling@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-error-handling@npm:5.7.3-pre.2157" +"@openmrs/esm-error-handling@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-error-handling@npm:5.7.3-pre.2161" peerDependencies: "@openmrs/esm-globals": 5.x - checksum: 10/27edb6b97ca0d095fb866e179147ddb75522313b3cca5b8e0e475eb6e480a77373314f8361495bf52bd6445c8aedb3cab1cd69d62fb2ca461490e8a0e8823a3d + checksum: 10/47d9266fe71e09cc1140bf064223940edf730a7c7e87a9434cd8fdefdd7375db49e687f24374020fab367b89773b703e4ff24376035b872f4d3001959675a3af languageName: node linkType: hard -"@openmrs/esm-extensions@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-extensions@npm:5.7.3-pre.2157" +"@openmrs/esm-extensions@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-extensions@npm:5.7.3-pre.2161" dependencies: lodash-es: "npm:^4.17.21" peerDependencies: @@ -2819,43 +2819,43 @@ __metadata: "@openmrs/esm-state": 5.x "@openmrs/esm-utils": 5.x single-spa: 5.x - checksum: 10/6bcad070d9cd36bdb4023121c43239aa021b1050d4fcd5d53c113f98b1d92387ebe14cde80466667968e2ef2b8a9432153b8386333bc4f895073326d5b125e1a + checksum: 10/78e8b33d758bf29a3406d3eec3d78ca8f408d50331ac8fba9ef3e5a150dc713eda16c8aa51b58be5c25b65c063866f88c4da8ea8f617e7ba59c34e59acad6d51 languageName: node linkType: hard -"@openmrs/esm-feature-flags@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-feature-flags@npm:5.7.3-pre.2157" +"@openmrs/esm-feature-flags@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-feature-flags@npm:5.7.3-pre.2161" dependencies: ramda: "npm:^0.26.1" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x single-spa: 5.x - checksum: 10/4a10b74b62c1c721856b57ab76870be3476be0f214cc70643670d610c705e01306d988b3ccea0f6cc2437ad99986aa5183371994d1faf6d32a552eeb36f767c9 - languageName: node - linkType: hard - -"@openmrs/esm-framework@npm:5.7.3-pre.2157, @openmrs/esm-framework@npm:next": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-framework@npm:5.7.3-pre.2157" - dependencies: - "@openmrs/esm-api": "npm:5.7.3-pre.2157" - "@openmrs/esm-config": "npm:5.7.3-pre.2157" - "@openmrs/esm-context": "npm:5.7.3-pre.2157" - "@openmrs/esm-dynamic-loading": "npm:5.7.3-pre.2157" - "@openmrs/esm-error-handling": "npm:5.7.3-pre.2157" - "@openmrs/esm-extensions": "npm:5.7.3-pre.2157" - "@openmrs/esm-feature-flags": "npm:5.7.3-pre.2157" - "@openmrs/esm-globals": "npm:5.7.3-pre.2157" - "@openmrs/esm-navigation": "npm:5.7.3-pre.2157" - "@openmrs/esm-offline": "npm:5.7.3-pre.2157" - "@openmrs/esm-react-utils": "npm:5.7.3-pre.2157" - "@openmrs/esm-routes": "npm:5.7.3-pre.2157" - "@openmrs/esm-state": "npm:5.7.3-pre.2157" - "@openmrs/esm-styleguide": "npm:5.7.3-pre.2157" - "@openmrs/esm-translations": "npm:5.7.3-pre.2157" - "@openmrs/esm-utils": "npm:5.7.3-pre.2157" + checksum: 10/5daea49544ebced760fa4aed1f6f24431eeddac97293cd4b277f3287368fb53434fcb23fcc81bc08d16a52188f52b2b12d89b52879352b819f76c5a04ac7efd4 + languageName: node + linkType: hard + +"@openmrs/esm-framework@npm:5.7.3-pre.2161, @openmrs/esm-framework@npm:^5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-framework@npm:5.7.3-pre.2161" + dependencies: + "@openmrs/esm-api": "npm:5.7.3-pre.2161" + "@openmrs/esm-config": "npm:5.7.3-pre.2161" + "@openmrs/esm-context": "npm:5.7.3-pre.2161" + "@openmrs/esm-dynamic-loading": "npm:5.7.3-pre.2161" + "@openmrs/esm-error-handling": "npm:5.7.3-pre.2161" + "@openmrs/esm-extensions": "npm:5.7.3-pre.2161" + "@openmrs/esm-feature-flags": "npm:5.7.3-pre.2161" + "@openmrs/esm-globals": "npm:5.7.3-pre.2161" + "@openmrs/esm-navigation": "npm:5.7.3-pre.2161" + "@openmrs/esm-offline": "npm:5.7.3-pre.2161" + "@openmrs/esm-react-utils": "npm:5.7.3-pre.2161" + "@openmrs/esm-routes": "npm:5.7.3-pre.2161" + "@openmrs/esm-state": "npm:5.7.3-pre.2161" + "@openmrs/esm-styleguide": "npm:5.7.3-pre.2161" + "@openmrs/esm-translations": "npm:5.7.3-pre.2161" + "@openmrs/esm-utils": "npm:5.7.3-pre.2161" dayjs: "npm:^1.10.7" peerDependencies: dayjs: 1.x @@ -2866,35 +2866,35 @@ __metadata: rxjs: 6.x single-spa: 5.x swr: 2.x - checksum: 10/0e5b1a721d7fcdfc239e3a00831316ef6e155fb4822fe00a45f564c7d0d568497f99036cb62000d50dc85c19fafb2b30b237fb343ed2ab9c7d0558025cc6b7a9 + checksum: 10/2f2d54477e6b7468ff0d574b036ec942f2f70336c2d32b9f0395b77d885dace1e6f7ab2bf17f19abfca8e57d77d5eaa16f6ea2e713c172692401f2378cd65f0a languageName: node linkType: hard -"@openmrs/esm-globals@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-globals@npm:5.7.3-pre.2157" +"@openmrs/esm-globals@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-globals@npm:5.7.3-pre.2161" dependencies: "@types/fhir": "npm:0.0.31" peerDependencies: single-spa: 5.x - checksum: 10/9a54835bd86e5fd5164a59231954236120ff4e32c5d008179749eef949aa20a636b1811a90179f4d48f90c037c894afc538371a02e48210986eb852a07325787 + checksum: 10/f9f8bcf9aff7aaabb417859a3bc804741b96c15c2477508f777e21fc1b12f020299ff37b1adfd60f84936252fec84192703da59bd58072e32bc493e3a81555c7 languageName: node linkType: hard -"@openmrs/esm-navigation@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-navigation@npm:5.7.3-pre.2157" +"@openmrs/esm-navigation@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-navigation@npm:5.7.3-pre.2161" dependencies: path-to-regexp: "npm:6.1.0" peerDependencies: "@openmrs/esm-state": 5.x - checksum: 10/f21b33d0bc967361de3dbb1b225d29c63ad1d25e760835ec27c8e443965a6a234daf9882b2a1bc939235443986fcdfa2d432f0a85a0ffc738073c5323e6c064a + checksum: 10/23b1b369bf0a93679bba35066c034d047e941261d1ab6e1e40632c9280c96553a5615c2131aa224d543d49b5d9b00de842f44fa3e00037949a110736f780ef98 languageName: node linkType: hard -"@openmrs/esm-offline@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-offline@npm:5.7.3-pre.2157" +"@openmrs/esm-offline@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-offline@npm:5.7.3-pre.2161" dependencies: dexie: "npm:^3.0.3" lodash-es: "npm:^4.17.21" @@ -2905,7 +2905,7 @@ __metadata: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x rxjs: 6.x - checksum: 10/e2a8fd93c66c3463add879476eff975a4718243f3d4ab83da678955b4d0e0c0dd82123174472773f2e30be4195033d81cd37fd5cfbea8b2eb7480a78280ee1d6 + checksum: 10/5997dee788f93594e668476527c05621085b491471313fe5366887760536836a6e08526312d4ded28be29e820cbbd3eea7bac246892dc86f6f81c5d540eb02ed languageName: node linkType: hard @@ -2950,7 +2950,7 @@ __metadata: "@carbon/react": "npm:~1.37.0" "@hookform/resolvers": "npm:^3.3.1" "@internationalized/date": "npm:^3.5.4" - "@openmrs/esm-framework": "npm:next" + "@openmrs/esm-framework": "npm:^5.7.3-pre.2161" "@openmrs/esm-patient-common-lib": "npm:next" "@playwright/test": "npm:1.45.2" "@swc/core": "npm:^1.2.165" @@ -2988,7 +2988,7 @@ __metadata: jest-cli: "npm:^29.7.0" jest-environment-jsdom: "npm:^29.7.0" lint-staged: "npm:^15.2.1" - openmrs: "npm:next" + openmrs: "npm:^5.7.3-pre.2161" prettier: "npm:^3.1.1" react: "npm:^18.1.0" react-dom: "npm:^18.1.0" @@ -3046,9 +3046,9 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/esm-react-utils@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-react-utils@npm:5.7.3-pre.2157" +"@openmrs/esm-react-utils@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-react-utils@npm:5.7.3-pre.2161" dependencies: lodash-es: "npm:^4.17.21" single-spa-react: "npm:^6.0.0" @@ -3069,13 +3069,13 @@ __metadata: react-i18next: 11.x rxjs: 6.x swr: 2.x - checksum: 10/aa38909094ca7176e6fc6f8ca3a00051a7d081d8f4a5d439f84d992927ea52cd349e552f8170b4cdc5e2cdb818eabab0aee5d06c9815286c0faa2fef7ea75517 + checksum: 10/b85dc63408008b2e763b0208f8e164a7e0488e32d3a5d403ab54cd9dba512a1a9e0b412bea5d3c87486bf668cdae987e27a16439356692ec43fa9f20639b62c0 languageName: node linkType: hard -"@openmrs/esm-routes@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-routes@npm:5.7.3-pre.2157" +"@openmrs/esm-routes@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-routes@npm:5.7.3-pre.2161" peerDependencies: "@openmrs/esm-config": 5.x "@openmrs/esm-dynamic-loading": 5.x @@ -3084,7 +3084,7 @@ __metadata: "@openmrs/esm-globals": 5.x "@openmrs/esm-utils": 5.x single-spa: 6.x - checksum: 10/1999bdf7553a5f0679287734f608715d468cb23633de48e50e78ba9714a1fc37b473e6e3832fd2a4f45936b566da15c5225c45655028ea83c6d73de265b9b8a6 + checksum: 10/66bf92782abecf3a73366754d856fa40c2de06b480191a8c5d795d81943eca2cbb5fa923440348997fe039c43d94650032e79dbd9102ae22df6d9636207fcc91 languageName: node linkType: hard @@ -3104,20 +3104,20 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/esm-state@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-state@npm:5.7.3-pre.2157" +"@openmrs/esm-state@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-state@npm:5.7.3-pre.2161" dependencies: zustand: "npm:^4.3.6" peerDependencies: "@openmrs/esm-globals": 5.x - checksum: 10/454f461e62d5fa05aae0e255301ff561c498ced3cfb17e8c95106fc37936d376391b244db0416f78ca78f4ae6918169e98cd16e8044d4bc15107273ef710b2cd + checksum: 10/61badf5b7344634cfe5fd3cdd504cde34d0441c634d380d6ce2b651f5a7cacd5929de26cabd08c06057f5823fbca8c844ebdeec8be3d2295c43f0471d00d9b05 languageName: node linkType: hard -"@openmrs/esm-styleguide@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-styleguide@npm:5.7.3-pre.2157" +"@openmrs/esm-styleguide@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-styleguide@npm:5.7.3-pre.2161" dependencies: "@carbon/charts": "npm:^1.12.0" "@carbon/react": "npm:~1.37.0" @@ -3140,24 +3140,24 @@ __metadata: react: 18.x react-dom: 18.x rxjs: 6.x - checksum: 10/8af679b8f1504fd084fed30f2c5099a93a8642f92bee5b6b0b54da6953122c98cbda293c3d16f9ea4611c4330ee42c992c6e9be6647acefca93079b73485f43c + checksum: 10/bb04abe01ba726064bd7435fd31c15bf208c4bdb2191afcf35e427af654287e56b5f472ab2117a9d849af5b8b178c68af5085e8df8091edb4e5a79283e6a41c6 languageName: node linkType: hard -"@openmrs/esm-translations@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-translations@npm:5.7.3-pre.2157" +"@openmrs/esm-translations@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-translations@npm:5.7.3-pre.2161" dependencies: i18next: "npm:21.10.0" peerDependencies: i18next: 21.x - checksum: 10/d829b5dead67142dfce376a7a691011eb79316d1133259e7fbbdfe36dd442a2604ba9f83c0048b3dfb07ac2d6249fa68ae2d559e9e85c4f8e705d4a6d062cff4 + checksum: 10/4458cf7427925756f9165219d34dca3ebc9699857ef933517fe0ff2ab870416ff74e8ee6981b12a4e1700767dc8b1aa84e3724672c64c4f5bb0871392fccaf59 languageName: node linkType: hard -"@openmrs/esm-utils@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/esm-utils@npm:5.7.3-pre.2157" +"@openmrs/esm-utils@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/esm-utils@npm:5.7.3-pre.2161" dependencies: "@formatjs/intl-durationformat": "npm:^0.2.4" "@internationalized/date": "npm:^3.5.4" @@ -3167,7 +3167,7 @@ __metadata: dayjs: 1.x i18next: 21.x rxjs: 6.x - checksum: 10/92d31ad13d267233f7bd776cc3e3df14a44405e360b4fb862242bac2513492990e11c829499a15775edfd2f6e1adc97186e204937d0b5974d9ef783686ee5a79 + checksum: 10/755f4195bde9cf2dccd9570a6e450236db6e34ad7122db101deec1b08eaf7083809f342de4e8e3f3d3f7c5d24269383e896d52e2412ae539390bbb78e0a5624e languageName: node linkType: hard @@ -3187,9 +3187,9 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/webpack-config@npm:5.7.3-pre.2157": - version: 5.7.3-pre.2157 - resolution: "@openmrs/webpack-config@npm:5.7.3-pre.2157" +"@openmrs/webpack-config@npm:5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "@openmrs/webpack-config@npm:5.7.3-pre.2161" dependencies: "@swc/core": "npm:^1.3.58" clean-webpack-plugin: "npm:^4.0.0" @@ -3207,7 +3207,7 @@ __metadata: webpack-stats-plugin: "npm:^1.0.3" peerDependencies: webpack: 5.x - checksum: 10/0d626f2437bd158c429da4ccc81765407b7266014f1040f24f96e1927bd5f986a1a268e9fae998d1b4325b8c10dd77e1f6c4a23dfd00c5feb1eb9747c233011f + checksum: 10/a812b16104c65cae4d3ca8e1c2db35fe36bfd64b3dd7e81641e68cf776eb38c27f9f376f5ffd081c56e7e5a2c3769d43d070ce4a66b1af49981049fde0dbc66b languageName: node linkType: hard @@ -13341,12 +13341,12 @@ __metadata: languageName: node linkType: hard -"openmrs@npm:next": - version: 5.7.3-pre.2157 - resolution: "openmrs@npm:5.7.3-pre.2157" +"openmrs@npm:^5.7.3-pre.2161": + version: 5.7.3-pre.2161 + resolution: "openmrs@npm:5.7.3-pre.2161" dependencies: - "@openmrs/esm-app-shell": "npm:5.7.3-pre.2157" - "@openmrs/webpack-config": "npm:5.7.3-pre.2157" + "@openmrs/esm-app-shell": "npm:5.7.3-pre.2161" + "@openmrs/webpack-config": "npm:5.7.3-pre.2161" "@pnpm/npm-conf": "npm:^2.1.0" "@swc/core": "npm:^1.3.58" autoprefixer: "npm:^10.4.2" @@ -13385,7 +13385,7 @@ __metadata: yargs: "npm:^17.6.2" bin: openmrs: ./dist/cli.js - checksum: 10/f912f8326e2998e6e3c75acc1260d86213a49a9d72a6e8a8f985977202ad061e9e6d5fdb6c312a63250d3af07c396b62c8e582b3b50db19ba928fccaf5237edc + checksum: 10/a2ffdf9d33f126308bab7dac55e4a62454471e1ddc561df9fe77b64c4d753992170188c17a5b202c130e9b77c0effc9e4df438a329e1991b341ed0df9358a74e languageName: node linkType: hard