From d0b9f5b76f2fa08a137ea35499937baad7cb7b8b Mon Sep 17 00:00:00 2001 From: Ayush <54752747+ayush-AI@users.noreply.github.com> Date: Sun, 27 Aug 2023 23:56:57 +0530 Subject: [PATCH 01/14] (test) Add test for `patient-search-icon.component` (#781) --- .../patient-search-icon.test.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 packages/esm-patient-search-app/src/patient-search-icon/patient-search-icon.test.tsx diff --git a/packages/esm-patient-search-app/src/patient-search-icon/patient-search-icon.test.tsx b/packages/esm-patient-search-app/src/patient-search-icon/patient-search-icon.test.tsx new file mode 100644 index 000000000..0cba40cf4 --- /dev/null +++ b/packages/esm-patient-search-app/src/patient-search-icon/patient-search-icon.test.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { render, fireEvent, screen } from '@testing-library/react'; +import PatientSearchLaunch from './patient-search-icon.component'; +import { isDesktop } from '@openmrs/esm-framework'; + +const isDesktopMock = isDesktop as jest.Mock; + +jest.mock('@openmrs/esm-framework', () => ({ + ...jest.requireActual('@openmrs/esm-framework'), + isDesktop: jest.fn(), + useOnClickOutside: jest.fn(), +})); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useSearchParams: jest.fn(() => [ + { + get: jest.fn(() => 'John'), + }, + ]), +})); + +describe('PatientSearchLaunch', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders without errors', () => { + render(); + expect(screen.getByRole('button', { name: 'Search Patient' })).toBeInTheDocument(); + }); + + it('toggles search input when search button is clicked', () => { + render(); + const searchButton = screen.getByTestId('searchPatientIcon'); + + fireEvent.click(searchButton); + const searchInput = screen.getByText('Search results'); + expect(searchInput).toBeInTheDocument(); + + fireEvent.click(searchButton); + expect(searchInput).not.toBeInTheDocument(); + }); + + it('displays search input in overlay on mobile', () => { + isDesktopMock.mockReturnValue(false); + render(); + const searchButton = screen.getByTestId('searchPatientIcon'); + + fireEvent.click(searchButton); + const overlay = screen.getByText('Search results'); + expect(overlay).toBeInTheDocument(); + }); +}); From 0a29603a9df2a1cafeaa47e3429bd32487b5107e Mon Sep 17 00:00:00 2001 From: Ayush <54752747+ayush-AI@users.noreply.github.com> Date: Mon, 28 Aug 2023 00:31:27 +0530 Subject: [PATCH 02/14] (test): Add test for `patient-list-detail.component` (#790) --- .../patient-list-detail.test.tsx | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 packages/esm-patient-list-app/src/patient-list-detail/patient-list-detail.test.tsx diff --git a/packages/esm-patient-list-app/src/patient-list-detail/patient-list-detail.test.tsx b/packages/esm-patient-list-app/src/patient-list-detail/patient-list-detail.test.tsx new file mode 100644 index 000000000..5aee11bd5 --- /dev/null +++ b/packages/esm-patient-list-app/src/patient-list-detail/patient-list-detail.test.tsx @@ -0,0 +1,105 @@ +import React from 'react'; +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { usePatientListDetails, usePatientListMembers } from '../api/hooks'; +import { showToast } from '@openmrs/esm-framework'; +import { deletePatientList } from '../api/api-remote'; +import PatientListDetailComponent from './patient-list-detail.component'; + +const mockedUsePatientListDetails = usePatientListDetails as jest.Mock; +const mockedUsePatientListMembers = usePatientListMembers as jest.Mock; +const mockedDeletePatientList = deletePatientList as jest.Mock; + +jest.mock('../api/hooks', () => ({ + usePatientListDetails: jest.fn(), + usePatientListMembers: jest.fn(), +})); + +jest.mock('../api/api-remote'); + +jest.mock('@openmrs/esm-framework', () => ({ + ...jest.requireActual('@openmrs/esm-framework'), + showToast: jest.fn(), + navigate: jest.fn(), + ExtensionSlot: jest.fn(), +})); + +const mockedPatientListDetails = { + name: 'Test Patient List', + description: 'This is a test patient list', + size: 5, + startDate: '2023-08-14', +}; + +const mockedPatientListMembers = [ + { + patient: { + person: { + display: 'John Doe', + gender: 'Male', + }, + identifiers: [ + { + identifier: '100GEJ', + }, + ], + uuid: '7cd38a6d-377e-491b-8284-b04cf8b8c6d8', + }, + startDate: '2023-08-10', + }, +]; + +describe('PatientListDetailComponent', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockedUsePatientListDetails.mockReturnValue({ + data: mockedPatientListDetails, + }); + + mockedUsePatientListMembers.mockReturnValue({ + data: mockedPatientListMembers, + }); + + mockedDeletePatientList.mockResolvedValue({}); + }); + + it('renders patient list details', async () => { + render(); + + await waitFor(() => { + expect(screen.getByText('Test Patient List')).toBeInTheDocument(); + expect(screen.getByText('This is a test patient list')).toBeInTheDocument(); + }); + }); + + it('displays patient list members', async () => { + render(); + + await waitFor(() => { + expect(screen.getByText('John Doe')).toBeInTheDocument(); + expect(screen.getByText('Male')).toBeInTheDocument(); + expect(screen.getByText('100GEJ')).toBeInTheDocument(); + }); + }); + + it('opens edit overlay when "Edit Name/ Description" is clicked', () => { + render(); + + userEvent.click(screen.getByText('Actions')); + const editBtn = screen.getByText('Edit Name/ Description'); + userEvent.click(editBtn); + }); + + it('deletes patient list and navigates on successful delete', async () => { + render(); + + await waitFor(() => { + userEvent.click(screen.getByText('Delete')); + }); + + await waitFor(() => { + expect(mockedDeletePatientList).toHaveBeenCalledTimes(1); + expect(showToast).toHaveBeenCalledTimes(1); + }); + }); +}); From 3dbcfdee6dc822c78610fd72602b575833a62183 Mon Sep 17 00:00:00 2001 From: CynthiaKamau Date: Wed, 30 Aug 2023 11:11:47 +0300 Subject: [PATCH 03/14] KHP3-4011 Add column to denote patient previous location in in queue (#776) --- .../active-visits/active-visits-table.component.tsx | 10 +++++++++- .../src/active-visits/active-visits-table.resource.ts | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/esm-outpatient-app/src/active-visits/active-visits-table.component.tsx b/packages/esm-outpatient-app/src/active-visits/active-visits-table.component.tsx index 06b7673c6..eeef1b6be 100644 --- a/packages/esm-outpatient-app/src/active-visits/active-visits-table.component.tsx +++ b/packages/esm-outpatient-app/src/active-visits/active-visits-table.component.tsx @@ -161,11 +161,16 @@ function ActiveVisitsTable() { }, { id: 3, + header: t('locationComingFrom', 'Coming from'), + key: 'locationComingFrom', + }, + { + id: 4, header: t('status', 'Status'), key: 'status', }, { - id: 4, + id: 5, header: t('waitTime', 'Wait time'), key: 'waitTime', }, @@ -213,6 +218,9 @@ function ActiveVisitsTable() { ), }, + locationComingFrom: { + content: {entry?.locationComingFrom}, + }, status: { content: ( diff --git a/packages/esm-outpatient-app/src/active-visits/active-visits-table.resource.ts b/packages/esm-outpatient-app/src/active-visits/active-visits-table.resource.ts index 3829b9a14..cafcb3336 100644 --- a/packages/esm-outpatient-app/src/active-visits/active-visits-table.resource.ts +++ b/packages/esm-outpatient-app/src/active-visits/active-visits-table.resource.ts @@ -71,6 +71,9 @@ export interface VisitQueueEntry { uuid: string; visit: Visit; sortWeight: number; + locationComingFrom: { + name: string; + }; } export interface MappedVisitQueueEntry { @@ -99,6 +102,7 @@ export interface MappedVisitQueueEntry { sortWeight: number; visitQueueNumber: string; identifiers: Array; + locationComingFrom: string; } interface UseVisitQueueEntries { @@ -244,6 +248,7 @@ export function useVisitQueueEntries(currServiceName: string, locationUuid: stri (e) => e.attributeType.uuid === visitQueueNumberAttributeUuid, )?.value, identifiers: visitQueueEntry.queueEntry.patient?.identifiers, + locationComingFrom: visitQueueEntry.queueEntry?.locationComingFrom?.name, }); let mappedVisitQueueEntries; @@ -310,6 +315,7 @@ export async function updateQueueEntry( }, startedAt: toDateObjectStrict(toOmrsIsoString(new Date())), sortWeight: sortWeight, + locationComingFrom: previousQueueUuid, }, }, }); From dc68fe93d98cd9fb4b44d728a9aa6a5097aab67b Mon Sep 17 00:00:00 2001 From: Donald Kibet Date: Wed, 30 Aug 2023 11:34:51 +0300 Subject: [PATCH 04/14] (fix) Resolved crash in active-visit component due to missing patientUuid on visit object (#799) --- .../active-visits.component.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/esm-active-visits-app/src/active-visits-widget/active-visits.component.tsx b/packages/esm-active-visits-app/src/active-visits-widget/active-visits.component.tsx index 6bf2042b3..2177e2285 100644 --- a/packages/esm-active-visits-app/src/active-visits-widget/active-visits.component.tsx +++ b/packages/esm-active-visits-app/src/active-visits-widget/active-visits.component.tsx @@ -247,15 +247,21 @@ const ActiveVisitsTable = () => { {rows.map((row, index) => { const visit = activeVisits.find((visit) => visit.id === row.id); + if (!visit) { + return null; + } + + const patientLink = `$\{openmrsSpaBase}/patient/${visit.patientUuid}/chart/Patient%20Summary`; + return ( - + {row.cells.map((cell) => ( - {cell.info.header === 'name' ? ( - + {cell.info.header === 'name' && visit.patientUuid ? ( + {cell.value} ) : ( From 63587079fea27aa80d98fe69f3ddc645497cec5f Mon Sep 17 00:00:00 2001 From: Makombe Kennedy Date: Thu, 31 Aug 2023 14:53:01 +0300 Subject: [PATCH 05/14] =?UTF-8?q?(fix):Appointment=20calendar=20should=20b?= =?UTF-8?q?e=20relative=20to=20the=20date=20selected=20as=E2=80=A6=20(#801?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * (fix):Appointment calendar should be relative to the date selected as appointment scheduled date * Code review * code review fix --------- Co-authored-by: Makombe --- .../appointments-calendar-view.component.tsx | 9 ++-- .../monthly/monthly-header.module.tsx | 3 +- .../appointments-header.component.tsx | 6 +-- .../appointments-metrics.component.tsx | 6 +-- .../appointments-table.resource.ts | 4 +- .../location-select-option.component.tsx | 48 +++++++++++++++++++ .../cancel-appointment.component.tsx | 6 +-- .../appointments-form.component.tsx | 46 +++++++++++------- .../src/appointments/forms/workload-helper.ts | 12 +++-- .../scheduled-appointments.component.tsx | 23 +++++---- .../esm-appointments-app/src/helpers/time.tsx | 2 +- .../appointments-table.resource.ts | 6 +-- .../src/hooks/useAppointmentList.tsx | 12 ++--- .../src/hooks/useClinicalMetrics.tsx | 14 +++--- .../hooks/usePatientAppointmentHistory.tsx | 4 +- .../src/hooks/useUnscheduledAppointments.tsx | 4 +- .../src/hooks/useVisits.tsx | 4 +- .../visit-form/visit-form.component.tsx | 6 +-- .../esm-outpatient-app/translations/am.json | 1 + .../esm-outpatient-app/translations/en.json | 1 + .../esm-outpatient-app/translations/es.json | 1 + .../esm-outpatient-app/translations/fr.json | 1 + .../esm-outpatient-app/translations/he.json | 1 + .../esm-outpatient-app/translations/km.json | 1 + 24 files changed, 150 insertions(+), 71 deletions(-) create mode 100644 packages/esm-appointments-app/src/appointments/common-components/location-select-option.component.tsx diff --git a/packages/esm-appointments-app/src/appointments-calendar/appointments-calendar-view.component.tsx b/packages/esm-appointments-app/src/appointments-calendar/appointments-calendar-view.component.tsx index 50f1eb018..5e0663e76 100644 --- a/packages/esm-appointments-app/src/appointments-calendar/appointments-calendar-view.component.tsx +++ b/packages/esm-appointments-app/src/appointments-calendar/appointments-calendar-view.component.tsx @@ -6,12 +6,13 @@ import type { CalendarType } from '../types'; import AppointmentsHeader from '../appointments-header/appointments-header.component'; import CalendarHeader from './header/calendar-header.component'; import CalendarView from './calendar-view.component'; +import { useAppointmentDate } from '../helpers'; const AppointmentsCalendarView: React.FC = () => { const { t } = useTranslation(); const [calendarView, setCalendarView] = useState('monthly'); - const [currentDate, setCurrentDate] = useState(dayjs()); - const { calendarEvents } = useAppointmentsCalendar(currentDate.toISOString(), calendarView); + const { currentAppointmentDate, setCurrentAppointmentDate } = useAppointmentDate(); + const { calendarEvents } = useAppointmentsCalendar(dayjs(currentAppointmentDate).toISOString(), calendarView); return (
@@ -20,8 +21,8 @@ const AppointmentsCalendarView: React.FC = () => {
); diff --git a/packages/esm-appointments-app/src/appointments-calendar/monthly/monthly-header.module.tsx b/packages/esm-appointments-app/src/appointments-calendar/monthly/monthly-header.module.tsx index 631332ffb..2d4c88519 100644 --- a/packages/esm-appointments-app/src/appointments-calendar/monthly/monthly-header.module.tsx +++ b/packages/esm-appointments-app/src/appointments-calendar/monthly/monthly-header.module.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Dayjs } from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import styles from './monthly-header.module.scss'; import { Button } from '@carbon/react'; import { useTranslation } from 'react-i18next'; @@ -24,6 +24,7 @@ function MonthlyHeader({ setCurrentDate: (date: Dayjs) => void; }) { const { t } = useTranslation(); + return ( <>
diff --git a/packages/esm-appointments-app/src/appointments-header/appointments-header.component.tsx b/packages/esm-appointments-app/src/appointments-header/appointments-header.component.tsx index 9beecb5b5..498ef9e32 100644 --- a/packages/esm-appointments-app/src/appointments-header/appointments-header.component.tsx +++ b/packages/esm-appointments-app/src/appointments-header/appointments-header.component.tsx @@ -6,7 +6,7 @@ import AppointmentsIllustration from './appointments-illustration.component'; import styles from './appointments-header.scss'; import { DatePicker, DatePickerInput, Dropdown, Layer } from '@carbon/react'; import dayjs from 'dayjs'; -import { changeStartDate } from '../helpers'; +import { changeStartDate, useAppointmentDate } from '../helpers'; import { useAppointmentServices } from '../hooks/useAppointmentService'; interface AppointmentHeaderProps { @@ -18,7 +18,7 @@ const AppointmentsHeader: React.FC = ({ title, onChange const { t } = useTranslation(); const session = useSession(); const datePickerRef = useRef(null); - const [appointmentDate, setDateTime] = useState(new Date()); + const { currentAppointmentDate } = useAppointmentDate(); const location = session?.sessionLocation?.display; const { serviceTypes } = useAppointmentServices(); return ( @@ -46,7 +46,7 @@ const AppointmentsHeader: React.FC = ({ title, onChange placeholder="DD-MMM-YYYY" labelText="" type="text" - value={dayjs(appointmentDate).format('DD MMM YYYY')} + value={dayjs(currentAppointmentDate).format('DD MMM YYYY')} />
diff --git a/packages/esm-appointments-app/src/appointments-metrics/appointments-metrics.component.tsx b/packages/esm-appointments-app/src/appointments-metrics/appointments-metrics.component.tsx index 9cdd6b685..aca0f909d 100644 --- a/packages/esm-appointments-app/src/appointments-metrics/appointments-metrics.component.tsx +++ b/packages/esm-appointments-app/src/appointments-metrics/appointments-metrics.component.tsx @@ -15,8 +15,8 @@ const AppointmentsMetrics: React.FC<{ serviceUuid: string }> = ({ serviceUuid }) const { totalProviders, isLoading: allAppointmentsLoading } = useAllAppointmentsByDate(); const { totalScheduledAppointments } = useScheduledAppointment(serviceUuid); - const startDate = useAppointmentDate(); - const formattedStartDate = formatDate(parseDate(startDate), { mode: 'standard', time: false }); + const { currentAppointmentDate } = useAppointmentDate(); + const formattedStartDate = formatDate(parseDate(currentAppointmentDate), { mode: 'standard', time: false }); const { appointmentList: arrivedAppointments } = useAppointmentList('Honoured'); const { appointmentList: pendingAppointments } = useAppointmentList('Pending'); @@ -43,7 +43,7 @@ const AppointmentsMetrics: React.FC<{ serviceUuid: string }> = ({ serviceUuid }) value={totalScheduledAppointments} headerLabel={t('scheduledAppointments', 'Scheduled appointments')} count={{ pendingAppointments: filteredPendingAppointments, arrivedAppointments: filteredArrivedAppointments }} - appointmentDate={startDate} + appointmentDate={currentAppointmentDate} /> ; +} + +interface LocationOptions { + uuid?: string; + display?: string; +} + +const LocationSelectOption: React.FC = ({ selectedLocation, defaultFacility, locations }) => { + const { t } = useTranslation(); + if (!selectedLocation) { + return ; + } + + if (defaultFacility && Object.keys(defaultFacility).length !== 0) { + return ( + + {defaultFacility?.display} + + ); + } + + if (locations && locations.length > 0) { + return ( + <> + {locations.map((location) => ( + + {location.display} + + ))} + + ); + } + + return null; +}; + +export default LocationSelectOption; diff --git a/packages/esm-appointments-app/src/appointments/forms/cancel-form/cancel-appointment.component.tsx b/packages/esm-appointments-app/src/appointments/forms/cancel-form/cancel-appointment.component.tsx index 049a796cf..843a424f5 100644 --- a/packages/esm-appointments-app/src/appointments/forms/cancel-form/cancel-appointment.component.tsx +++ b/packages/esm-appointments-app/src/appointments/forms/cancel-form/cancel-appointment.component.tsx @@ -19,7 +19,7 @@ const CancelAppointment: React.FC = ({ appointment }) => const session = useSession(); const [selectedLocation, setSelectedLocation] = useState(appointment.location); const [reason, setReason] = useState(''); - const startDate = useAppointmentDate(); + const { currentAppointmentDate } = useAppointmentDate(); const [isSubmitting, setIsSubmitting] = useState(false); useEffect(() => { @@ -38,8 +38,8 @@ const CancelAppointment: React.FC = ({ appointment }) => description: t('appointmentNowVisible', 'It has been cancelled successfully'), title: t('appointmentCancelled', 'Appointment cancelled'), }); - mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${startDate}&status=Scheduled`); - mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${startDate}&status=Cancelled`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${currentAppointmentDate}&status=Scheduled`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${currentAppointmentDate}&status=Cancelled`); closeOverlay(); } else { showNotification({ diff --git a/packages/esm-appointments-app/src/appointments/forms/create-edit-form/appointments-form.component.tsx b/packages/esm-appointments-app/src/appointments/forms/create-edit-form/appointments-form.component.tsx index e457d5c19..77df4feea 100644 --- a/packages/esm-appointments-app/src/appointments/forms/create-edit-form/appointments-form.component.tsx +++ b/packages/esm-appointments-app/src/appointments/forms/create-edit-form/appointments-form.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; import { @@ -32,6 +32,7 @@ import { showNotification, showToast, ConfigObject, + useSession, } from '@openmrs/esm-framework'; import first from 'lodash-es/first'; @@ -50,6 +51,8 @@ import { import { useInitialAppointmentFormValue, PatientAppointment } from '../useInitialFormValues'; import { useCalendarDistribution } from '../workload-helper'; import WorkloadCard from '../workload.component'; +import { useDefaultLoginLocation } from '../../../hooks/useDefaultLocation'; +import LocationSelectOption from '../../common-components/location-select-option.component'; interface AppointmentFormProps { appointment?: MappedAppointment; @@ -63,6 +66,7 @@ const AppointmentForm: React.FC = ({ appointment, patientU const [patientAppointment, setPatientAppointment] = useState(initialAppointmentFormValues); const { patient, isLoading } = usePatient(patientUuid ?? patientAppointment.patientUuid); const locations = useLocations(); + const sessionUser = useSession(); const { providers } = useProviders(); const { services } = useServices(); const [isSubmitting, setIsSubmitting] = useState(false); @@ -71,11 +75,22 @@ const AppointmentForm: React.FC = ({ appointment, patientU const calendarWorkload = useCalendarDistribution( patientAppointment.serviceUuid, selectedTab === 0 ? 'week' : 'month', + patientAppointment.visitDate, ); - const appointmentStartDate = useAppointmentDate(); + const { currentAppointmentDate } = useAppointmentDate(); + const [selectedLocation, setSelectedLocation] = useState(''); + const { defaultFacility, isLoading: loadingDefaultFacility } = useDefaultLoginLocation(); const appointmentService = services?.find(({ uuid }) => uuid === patientAppointment.serviceUuid); + useEffect(() => { + if (locations?.length && sessionUser) { + setSelectedLocation(sessionUser?.sessionLocation?.uuid); + } else if (!loadingDefaultFacility && defaultFacility) { + setSelectedLocation(defaultFacility?.uuid); + } + }, [locations, sessionUser, loadingDefaultFacility]); + const handleSubmit = async () => { const [hours, minutes] = convertTime12to24(patientAppointment.startDateTime, patientAppointment.timeFormat); const startDatetime = toAppointmentDateTime(patientAppointment.visitDate, hours, minutes); @@ -107,11 +122,11 @@ const AppointmentForm: React.FC = ({ appointment, patientU title: t('appointmentScheduled', 'Appointment scheduled'), }); setIsSubmitting(false); - mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${appointmentStartDate}&status=Scheduled`); - mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${appointmentStartDate}&status=CheckedIn`); - mutate(`/ws/rest/v1/appointment/all?forDate=${appointmentStartDate}`); - mutate(`/ws/rest/v1/appointment/appointmentStatus?status=Scheduled&forDate=${appointmentStartDate}`); - mutate(`/ws/rest/v1/appointment/appointmentStatus?status=Pending&forDate=${appointmentStartDate}`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${currentAppointmentDate}&status=Scheduled`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?forDate=${currentAppointmentDate}&status=CheckedIn`); + mutate(`/ws/rest/v1/appointment/all?forDate=${currentAppointmentDate}`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?status=Scheduled&forDate=${currentAppointmentDate}`); + mutate(`/ws/rest/v1/appointment/appointmentStatus?status=Pending&forDate=${currentAppointmentDate}`); closeOverlay(); } }, @@ -159,15 +174,14 @@ const AppointmentForm: React.FC = ({ appointment, patientU labelText={t('selectLocation', 'Select a location')} id="location" invalidText="Required" - value={patientAppointment.locationUuid} - className={styles.inputContainer} - onChange={(event) => setPatientAppointment({ ...patientAppointment, locationUuid: event.target.value })}> - {locations?.length > 0 && - locations.map((location) => ( - - {location.display} - - ))} + value={selectedLocation} + defaultSelected={selectedLocation} + onChange={(event) => setSelectedLocation(event.target.value)}> +