@openmrs/esm-appointments-app 9.2.1-pre.6938 → 9.2.1-pre.6942
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/dist/1431.js +1 -1
- package/dist/3092.js +1 -1
- package/dist/3167.js +1 -1
- package/dist/3431.js +1 -1
- package/dist/4300.js +1 -1
- package/dist/4733.js +1 -1
- package/dist/4745.js +1 -1
- package/dist/4889.js +1 -1
- package/dist/4889.js.map +1 -1
- package/dist/5160.js +1 -1
- package/dist/525.js +1 -1
- package/dist/5257.js +2 -0
- package/dist/5257.js.map +1 -0
- package/dist/592.js +1 -1
- package/dist/6886.js +1 -1
- package/dist/8252.js +1 -1
- package/dist/8252.js.map +1 -1
- package/dist/9208.js +1 -1
- package/dist/9712.js +1 -1
- package/dist/main.js +1 -1
- package/dist/openmrs-esm-appointments-app.js +1 -1
- package/dist/openmrs-esm-appointments-app.js.buildmanifest.json +52 -52
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/form/appointments-form.scss +6 -18
- package/src/form/appointments-form.test.tsx +516 -2
- package/src/form/appointments-form.workspace.tsx +67 -67
- package/translations/en.json +1 -1
- package/dist/8560.js +0 -2
- package/dist/8560.js.map +0 -1
- /package/dist/{8560.js.LICENSE.txt → 5257.js.LICENSE.txt} +0 -0
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Button,
|
|
7
7
|
ButtonSet,
|
|
8
8
|
Form,
|
|
9
|
+
FormGroup,
|
|
9
10
|
InlineLoading,
|
|
10
11
|
MultiSelect,
|
|
11
12
|
NumberInput,
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
} from '@openmrs/esm-framework';
|
|
38
39
|
import { z } from 'zod';
|
|
39
40
|
import { type ConfigObject } from '../config-schema';
|
|
41
|
+
import type { Appointment, AppointmentPayload, RecurringPattern } from '../types';
|
|
40
42
|
import {
|
|
41
43
|
checkAppointmentConflict,
|
|
42
44
|
saveAppointment,
|
|
@@ -44,17 +46,9 @@ import {
|
|
|
44
46
|
useAppointmentService,
|
|
45
47
|
useMutateAppointments,
|
|
46
48
|
} from './appointments-form.resource';
|
|
47
|
-
import {
|
|
48
|
-
appointmentLocationTagName,
|
|
49
|
-
dateFormat,
|
|
50
|
-
datePickerFormat,
|
|
51
|
-
datePickerPlaceHolder,
|
|
52
|
-
moduleName,
|
|
53
|
-
weekDays,
|
|
54
|
-
} from '../constants';
|
|
55
|
-
import { useProviders } from '../hooks/useProviders';
|
|
56
|
-
import type { Appointment, AppointmentPayload, RecurringPattern } from '../types';
|
|
49
|
+
import { appointmentLocationTagName, dateFormat, moduleName, weekDays } from '../constants';
|
|
57
50
|
import { useAppointmentsStore } from '../store';
|
|
51
|
+
import { useProviders } from '../hooks/useProviders';
|
|
58
52
|
import Workload from '../workload/workload.component';
|
|
59
53
|
import styles from './appointments-form.scss';
|
|
60
54
|
|
|
@@ -202,7 +196,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
202
196
|
},
|
|
203
197
|
)
|
|
204
198
|
.superRefine((data, ctx) => {
|
|
205
|
-
// If not all-day, duration must be > 0
|
|
199
|
+
// If not all-day, duration must be > 0 and <= 1440 minutes (24 hours)
|
|
206
200
|
if (!data.isAllDayAppointment && (!data.duration || data.duration <= 0)) {
|
|
207
201
|
ctx.addIssue({
|
|
208
202
|
path: ['duration'],
|
|
@@ -210,6 +204,17 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
210
204
|
message: translateFrom(moduleName, 'durationErrorMessage', 'Duration should be greater than zero'),
|
|
211
205
|
});
|
|
212
206
|
}
|
|
207
|
+
if (!data.isAllDayAppointment && data.duration && data.duration > 1440) {
|
|
208
|
+
ctx.addIssue({
|
|
209
|
+
path: ['duration'],
|
|
210
|
+
code: z.ZodIssueCode.custom,
|
|
211
|
+
message: translateFrom(
|
|
212
|
+
moduleName,
|
|
213
|
+
'durationMaxErrorMessage',
|
|
214
|
+
'Duration cannot exceed 1440 minutes (24 hours)',
|
|
215
|
+
),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
213
218
|
});
|
|
214
219
|
|
|
215
220
|
type AppointmentFormData = z.infer<typeof appointmentsFormSchema>;
|
|
@@ -476,19 +481,18 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
476
481
|
|
|
477
482
|
return (
|
|
478
483
|
<Form onSubmit={handleSubmit(handleSaveAppointment)}>
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
<
|
|
491
|
-
<span className={styles.heading}>{t('location', 'Location')}</span>
|
|
484
|
+
{patient && (
|
|
485
|
+
<ExtensionSlot
|
|
486
|
+
name="patient-header-slot"
|
|
487
|
+
state={{
|
|
488
|
+
patient,
|
|
489
|
+
patientUuid: patientUuid,
|
|
490
|
+
hideActionsOverflow: true,
|
|
491
|
+
}}
|
|
492
|
+
/>
|
|
493
|
+
)}
|
|
494
|
+
<Stack className={styles.formWrapper} gap={6}>
|
|
495
|
+
<FormGroup className={styles.formGroup} legendText={t('location', 'Location')}>
|
|
492
496
|
<ResponsiveWrapper>
|
|
493
497
|
<Controller
|
|
494
498
|
name="location"
|
|
@@ -514,9 +518,8 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
514
518
|
)}
|
|
515
519
|
/>
|
|
516
520
|
</ResponsiveWrapper>
|
|
517
|
-
</
|
|
518
|
-
<
|
|
519
|
-
<span className={styles.heading}>{t('service', 'Service')}</span>
|
|
521
|
+
</FormGroup>
|
|
522
|
+
<FormGroup className={styles.formGroup} legendText={t('service', 'Service')}>
|
|
520
523
|
<ResponsiveWrapper>
|
|
521
524
|
<Controller
|
|
522
525
|
name="selectedService"
|
|
@@ -560,9 +563,8 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
560
563
|
)}
|
|
561
564
|
/>
|
|
562
565
|
</ResponsiveWrapper>
|
|
563
|
-
</
|
|
564
|
-
<
|
|
565
|
-
<span className={styles.heading}>{t('appointmentType_title', 'Appointment Type')}</span>
|
|
566
|
+
</FormGroup>
|
|
567
|
+
<FormGroup className={styles.formGroup} legendText={t('appointmentType_title', 'Appointment Type')}>
|
|
566
568
|
<ResponsiveWrapper>
|
|
567
569
|
<Controller
|
|
568
570
|
name="appointmentType"
|
|
@@ -589,21 +591,21 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
589
591
|
)}
|
|
590
592
|
/>
|
|
591
593
|
</ResponsiveWrapper>
|
|
592
|
-
</
|
|
593
|
-
|
|
594
|
-
<
|
|
595
|
-
<
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
594
|
+
</FormGroup>
|
|
595
|
+
|
|
596
|
+
<FormGroup className={styles.formGroup} legendText={t('recurringAppointment', 'Recurring Appointment')}>
|
|
597
|
+
<div>
|
|
598
|
+
<Toggle
|
|
599
|
+
id="recurringToggle"
|
|
600
|
+
labelB={t('yes', 'Yes')}
|
|
601
|
+
labelA={t('no', 'No')}
|
|
602
|
+
labelText={t('isRecurringAppointment', 'Is this a recurring appointment?')}
|
|
603
|
+
onClick={() => setIsRecurringAppointment(!isRecurringAppointment)}
|
|
604
|
+
/>
|
|
605
|
+
</div>
|
|
606
|
+
</FormGroup>
|
|
607
|
+
|
|
608
|
+
<FormGroup className={styles.formGroup} legendText={t('dateTime', 'Date & Time')}>
|
|
607
609
|
<div className={styles.dateTimeFields}>
|
|
608
610
|
{isRecurringAppointment && (
|
|
609
611
|
<div className={styles.inputContainer}>
|
|
@@ -673,7 +675,6 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
673
675
|
max={356}
|
|
674
676
|
label={t('repeatEvery', 'Repeat every')}
|
|
675
677
|
invalidText={t('invalidNumber', 'Number is not valid')}
|
|
676
|
-
size="md"
|
|
677
678
|
value={value}
|
|
678
679
|
onBlur={onBlur}
|
|
679
680
|
onChange={(e) => {
|
|
@@ -782,10 +783,10 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
782
783
|
</div>
|
|
783
784
|
)}
|
|
784
785
|
</div>
|
|
785
|
-
</
|
|
786
|
+
</FormGroup>
|
|
786
787
|
|
|
787
788
|
{getValues('selectedService') && (
|
|
788
|
-
<
|
|
789
|
+
<FormGroup className={styles.formGroup} legendText="">
|
|
789
790
|
<ResponsiveWrapper>
|
|
790
791
|
<Workload
|
|
791
792
|
appointmentDate={watch('appointmentDateTime').startDate}
|
|
@@ -793,12 +794,11 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
793
794
|
selectedService={watch('selectedService')}
|
|
794
795
|
/>
|
|
795
796
|
</ResponsiveWrapper>
|
|
796
|
-
</
|
|
797
|
+
</FormGroup>
|
|
797
798
|
)}
|
|
798
799
|
|
|
799
800
|
{context !== 'creating' ? (
|
|
800
|
-
<
|
|
801
|
-
<span className={styles.heading}>{t('appointmentStatus', 'Appointment Status')}</span>
|
|
801
|
+
<FormGroup className={styles.formGroup} legendText={t('appointmentStatus', 'Appointment Status')}>
|
|
802
802
|
<ResponsiveWrapper>
|
|
803
803
|
<Controller
|
|
804
804
|
name="appointmentStatus"
|
|
@@ -824,11 +824,10 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
824
824
|
)}
|
|
825
825
|
/>
|
|
826
826
|
</ResponsiveWrapper>
|
|
827
|
-
</
|
|
827
|
+
</FormGroup>
|
|
828
828
|
) : null}
|
|
829
829
|
|
|
830
|
-
<
|
|
831
|
-
<span className={styles.heading}>{t('provider', 'Provider')}</span>
|
|
830
|
+
<FormGroup className={styles.formGroup} legendText={t('provider', 'Provider')}>
|
|
832
831
|
<ResponsiveWrapper>
|
|
833
832
|
<Controller
|
|
834
833
|
name="provider"
|
|
@@ -853,9 +852,11 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
853
852
|
)}
|
|
854
853
|
/>
|
|
855
854
|
</ResponsiveWrapper>
|
|
856
|
-
</
|
|
857
|
-
|
|
858
|
-
|
|
855
|
+
</FormGroup>
|
|
856
|
+
|
|
857
|
+
<FormGroup
|
|
858
|
+
className={styles.formGroup}
|
|
859
|
+
legendText={t('dateAppointmentScheduled', 'Date appointment scheduled')}>
|
|
859
860
|
<ResponsiveWrapper>
|
|
860
861
|
<Controller
|
|
861
862
|
name="dateAppointmentScheduled"
|
|
@@ -869,19 +870,18 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
869
870
|
invalidText={fieldState?.error?.message}
|
|
870
871
|
labelText={t('dateAppointmentIssued', 'Date appointment issued')}
|
|
871
872
|
maxDate={new Date()}
|
|
872
|
-
style={{ width: '100%' }}
|
|
873
873
|
onBlur={field.onBlur}
|
|
874
874
|
onChange={field.onChange}
|
|
875
|
+
style={{ width: '100%' }}
|
|
875
876
|
value={field.value}
|
|
876
877
|
/>
|
|
877
878
|
</div>
|
|
878
879
|
)}
|
|
879
880
|
/>
|
|
880
881
|
</ResponsiveWrapper>
|
|
881
|
-
</
|
|
882
|
+
</FormGroup>
|
|
882
883
|
|
|
883
|
-
<
|
|
884
|
-
<span className={styles.heading}>{t('note', 'Note')}</span>
|
|
884
|
+
<FormGroup className={styles.formGroup} legendText={t('note', 'Note')}>
|
|
885
885
|
<ResponsiveWrapper>
|
|
886
886
|
<Controller
|
|
887
887
|
name="appointmentNote"
|
|
@@ -901,7 +901,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
901
901
|
)}
|
|
902
902
|
/>
|
|
903
903
|
</ResponsiveWrapper>
|
|
904
|
-
</
|
|
904
|
+
</FormGroup>
|
|
905
905
|
</Stack>
|
|
906
906
|
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
907
907
|
<Button className={styles.button} onClick={closeWorkspace} kind="secondary">
|
|
@@ -960,19 +960,19 @@ function TimeAndDuration({ t, watch, control, services, errors }) {
|
|
|
960
960
|
control={control}
|
|
961
961
|
render={({ field: { onChange, onBlur, value, ref } }) => (
|
|
962
962
|
<NumberInput
|
|
963
|
+
allowEmpty
|
|
963
964
|
disableWheel
|
|
964
965
|
hideSteppers
|
|
965
966
|
id="duration"
|
|
966
967
|
invalid={!!errors?.duration}
|
|
967
968
|
invalidText={errors?.duration?.message}
|
|
968
969
|
label={t('durationInMinutes', 'Duration (minutes)')}
|
|
969
|
-
max={1440}
|
|
970
|
-
min={0}
|
|
971
970
|
onBlur={onBlur}
|
|
972
|
-
onChange={(event
|
|
971
|
+
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
|
972
|
+
onChange(event.target.value === '' ? null : Number(event.target.value))
|
|
973
|
+
}
|
|
973
974
|
ref={ref}
|
|
974
|
-
|
|
975
|
-
value={value}
|
|
975
|
+
value={value ?? ''}
|
|
976
976
|
/>
|
|
977
977
|
)}
|
|
978
978
|
/>
|
package/translations/en.json
CHANGED
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"date&Time": "Date & time",
|
|
62
62
|
"dateAppointmentIssued": "Date appointment issued",
|
|
63
63
|
"dateAppointmentIssuedCannotBeAfterAppointmentDate": "Date appointment issued cannot be after the appointment date",
|
|
64
|
+
"dateAppointmentScheduled": "Date appointment scheduled",
|
|
64
65
|
"dateOfBirth": "Date of birth",
|
|
65
66
|
"dateRange": "Set date range",
|
|
66
|
-
"dateScheduled": "Date appointment issued",
|
|
67
67
|
"dateTime": "Date & Time",
|
|
68
68
|
"day": "Day",
|
|
69
69
|
"daysOfWeek": "Days of the week",
|