diff --git a/README.md b/README.md index e8061eacf..799e32212 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository contains frontend modules for the OpenMRS SPA. These modules rel - [Active visits app](packages/esm-active-visits-app/) - [Appointments app](packages/esm-appointments-app/) -- [Outpatient app](packages/esm-outpatient-app/README.md) +- [Service queues](packages/esm-service-queues-app/README.md) - [Patient search](packages/esm-patient-search-app) - [Patient registration](packages/esm-patient-registration-app) - [Patient list](packages/esm-patient-list-app) 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} ) : ( 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)}> +