@openmrs/esm-appointments-app 9.2.1-pre.7303 → 9.2.1-pre.7315
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 +8 -8
- package/dist/1431.js +1 -1
- package/dist/1431.js.map +1 -1
- package/dist/1559.js +1 -1
- package/dist/1559.js.map +1 -1
- package/dist/2265.js +1 -0
- package/dist/2265.js.map +1 -0
- package/dist/{5160.js → 4036.js} +1 -1
- package/dist/{5160.js.map → 4036.js.map} +1 -1
- package/dist/449.js +1 -1
- package/dist/449.js.map +1 -1
- package/dist/4515.js +1 -0
- package/dist/4515.js.map +1 -0
- package/dist/4745.js +1 -1
- package/dist/4745.js.map +1 -1
- package/dist/4889.js +1 -1
- package/dist/4889.js.map +1 -1
- package/dist/525.js +1 -1
- package/dist/525.js.map +1 -1
- package/dist/5666.js +1 -1
- package/dist/5666.js.map +1 -1
- package/dist/5755.js +1 -1
- package/dist/5755.js.map +1 -1
- package/dist/592.js +1 -1
- package/dist/592.js.map +1 -1
- package/dist/6467.js +1 -1
- package/dist/6467.js.map +1 -1
- package/dist/6886.js +1 -1
- package/dist/6886.js.map +1 -1
- package/dist/{7565.js → 7294.js} +1 -1
- package/dist/7294.js.map +1 -0
- package/dist/9712.js +1 -1
- package/dist/9712.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-appointments-app.js.buildmanifest.json +121 -120
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/appointments/common-components/appointments-table.component.tsx +4 -6
- package/src/constants.ts +1 -0
- package/src/form/appointments-form.resource.ts +1 -0
- package/src/form/appointments-form.test.tsx +111 -71
- package/src/form/appointments-form.workspace.tsx +437 -436
- package/src/form/exported-appointments-form.workspace.tsx +24 -0
- package/src/helpers/functions.ts +72 -25
- package/src/index.ts +5 -3
- package/src/metrics/metrics-cards/highest-volume-service.extension.tsx +1 -1
- package/src/metrics/metrics-cards/metrics-card.component.tsx +1 -1
- package/src/metrics/metrics-header.component.tsx +9 -24
- package/src/patient-appointments/patient-appointments-action-menu.component.tsx +2 -6
- package/src/patient-appointments/patient-appointments-detailed-summary.extension.tsx +176 -15
- package/src/patient-appointments/{patient-appointments-base.test.tsx → patient-appointments-detailed-summary.test.tsx} +14 -22
- package/src/patient-appointments/patient-appointments-overview.component.tsx +15 -18
- package/src/routes.json +22 -7
- package/dist/3092.js +0 -1
- package/dist/3092.js.map +0 -1
- package/dist/7026.js +0 -1
- package/dist/7026.js.map +0 -1
- package/dist/7565.js.map +0 -1
- package/src/hooks/patient-appointment-context.ts +0 -18
- package/src/patient-appointments/patient-appointments-base.component.tsx +0 -178
- package/src/patient-search/patient-search.component.tsx +0 -33
- package/src/patient-search/patient-search.scss +0 -24
- /package/src/patient-appointments/{patient-appointments-base.scss → patient-appointments-detailed-summary.scss} +0 -0
|
@@ -33,7 +33,8 @@ import {
|
|
|
33
33
|
useLocations,
|
|
34
34
|
usePatient,
|
|
35
35
|
useSession,
|
|
36
|
-
|
|
36
|
+
Workspace2,
|
|
37
|
+
type Workspace2DefinitionProps,
|
|
37
38
|
type FetchResponse,
|
|
38
39
|
} from '@openmrs/esm-framework';
|
|
39
40
|
import { z } from 'zod';
|
|
@@ -55,21 +56,20 @@ import styles from './appointments-form.scss';
|
|
|
55
56
|
interface AppointmentsFormProps {
|
|
56
57
|
appointment?: Appointment;
|
|
57
58
|
recurringPattern?: RecurringPattern;
|
|
58
|
-
patientUuid
|
|
59
|
-
context: string;
|
|
59
|
+
patientUuid: string;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const time12HourFormatRegexPattern = '^(1[0-2]|0?[1-9]):[0-5][0-9]$';
|
|
63
|
+
const time12HourFormatRegex = /^(1[0-2]|0?[1-9]):[0-5][0-9]$/;
|
|
63
64
|
|
|
64
|
-
const isValidTime = (timeStr: string) =>
|
|
65
|
+
const isValidTime = (timeStr: string) => time12HourFormatRegex.test(timeStr);
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Workspace used to create or edit an appointment within the appointments app
|
|
69
|
+
*/
|
|
70
|
+
const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps>> = ({
|
|
71
|
+
workspaceProps: { appointment, recurringPattern, patientUuid },
|
|
71
72
|
closeWorkspace,
|
|
72
|
-
promptBeforeClosing,
|
|
73
73
|
}) => {
|
|
74
74
|
const { patient } = usePatient(patientUuid);
|
|
75
75
|
const { mutateAppointments } = useMutateAppointments();
|
|
@@ -264,7 +264,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
264
264
|
|
|
265
265
|
useEffect(() => setValue('formIsRecurringAppointment', isRecurringAppointment), [isRecurringAppointment, setValue]);
|
|
266
266
|
|
|
267
|
-
//
|
|
267
|
+
// Retrieve ref callback for appointmentDateTime (startDate & recurringPatternEndDate)
|
|
268
268
|
const {
|
|
269
269
|
field: { ref: startDateRef },
|
|
270
270
|
} = useController({ name: 'appointmentDateTime.startDate', control });
|
|
@@ -283,12 +283,9 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
283
283
|
useEffect(() => {
|
|
284
284
|
if (isSuccessful) {
|
|
285
285
|
reset();
|
|
286
|
-
|
|
287
|
-
closeWorkspace();
|
|
288
|
-
return;
|
|
286
|
+
closeWorkspace({ discardUnsavedChanges: true, closeWindow: true });
|
|
289
287
|
}
|
|
290
|
-
|
|
291
|
-
}, [isDirty, promptBeforeClosing, isSuccessful, reset, closeWorkspace]);
|
|
288
|
+
}, [isSuccessful, reset, closeWorkspace]);
|
|
292
289
|
|
|
293
290
|
const handleWorkloadDateChange = (date: Date) => {
|
|
294
291
|
const appointmentDate = getValues('appointmentDateTime');
|
|
@@ -331,23 +328,21 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
331
328
|
}
|
|
332
329
|
})();
|
|
333
330
|
|
|
331
|
+
const isEditing = Boolean(appointment);
|
|
332
|
+
|
|
334
333
|
// Same for creating and editing
|
|
335
334
|
const handleSaveAppointment = async (data: AppointmentFormData) => {
|
|
336
335
|
setIsSubmitting(true);
|
|
337
336
|
// Construct appointment payload
|
|
338
337
|
const appointmentPayload = constructAppointmentPayload(data);
|
|
339
338
|
|
|
340
|
-
//
|
|
339
|
+
// Check if a duplicate response occurs
|
|
341
340
|
const response: FetchResponse = await checkAppointmentConflict(appointmentPayload);
|
|
342
341
|
let errorMessage = t('appointmentConflict', 'Appointment conflict');
|
|
343
342
|
if (response?.data?.hasOwnProperty('SERVICE_UNAVAILABLE')) {
|
|
344
343
|
errorMessage = t('serviceUnavailable', 'Appointment time is outside of service hours');
|
|
345
344
|
} else if (response?.data?.hasOwnProperty('PATIENT_DOUBLE_BOOKING')) {
|
|
346
|
-
|
|
347
|
-
errorMessage = t('patientDoubleBooking', 'Patient already booked for an appointment at this time');
|
|
348
|
-
} else {
|
|
349
|
-
errorMessage = null;
|
|
350
|
-
}
|
|
345
|
+
errorMessage = t('patientDoubleBooking', 'Patient already booked for an appointment at this time');
|
|
351
346
|
}
|
|
352
347
|
|
|
353
348
|
if (response.status === 200 && errorMessage) {
|
|
@@ -381,19 +376,17 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
381
376
|
isLowContrast: true,
|
|
382
377
|
kind: 'success',
|
|
383
378
|
subtitle: t('appointmentNowVisible', 'It is now visible on the Appointments page'),
|
|
384
|
-
title:
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
: t('appointmentScheduled', 'Appointment scheduled'),
|
|
379
|
+
title: isEditing
|
|
380
|
+
? t('appointmentEdited', 'Appointment edited')
|
|
381
|
+
: t('appointmentScheduled', 'Appointment scheduled'),
|
|
388
382
|
});
|
|
389
383
|
}
|
|
390
384
|
if (status === 204) {
|
|
391
385
|
setIsSubmitting(false);
|
|
392
386
|
showSnackbar({
|
|
393
|
-
title:
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
: t('appointmentFormError', 'Error scheduling appointment'),
|
|
387
|
+
title: isEditing
|
|
388
|
+
? t('appointmentEditError', 'Error editing appointment')
|
|
389
|
+
: t('appointmentFormError', 'Error scheduling appointment'),
|
|
397
390
|
kind: 'error',
|
|
398
391
|
isLowContrast: false,
|
|
399
392
|
subtitle: t('noContent', 'No Content'),
|
|
@@ -403,10 +396,9 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
403
396
|
(error) => {
|
|
404
397
|
setIsSubmitting(false);
|
|
405
398
|
showSnackbar({
|
|
406
|
-
title:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
: t('appointmentFormError', 'Error scheduling appointment'),
|
|
399
|
+
title: isEditing
|
|
400
|
+
? t('appointmentEditError', 'Error editing appointment')
|
|
401
|
+
: t('appointmentFormError', 'Error scheduling appointment'),
|
|
410
402
|
kind: 'error',
|
|
411
403
|
isLowContrast: false,
|
|
412
404
|
subtitle: error?.message,
|
|
@@ -450,7 +442,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
450
442
|
providers: [{ uuid: provider }],
|
|
451
443
|
patientUuid: patientUuid,
|
|
452
444
|
comments: appointmentNote,
|
|
453
|
-
uuid:
|
|
445
|
+
uuid: isEditing ? appointment.uuid : undefined,
|
|
454
446
|
dateAppointmentScheduled: dayjs(dateAppointmentScheduled).format(),
|
|
455
447
|
};
|
|
456
448
|
};
|
|
@@ -474,346 +466,380 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
474
466
|
};
|
|
475
467
|
};
|
|
476
468
|
|
|
477
|
-
if (isLoading)
|
|
469
|
+
if (isLoading) {
|
|
478
470
|
return (
|
|
479
471
|
<InlineLoading className={styles.loader} description={`${t('loading', 'Loading')} ...`} role="progressbar" />
|
|
480
472
|
);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const title = isEditing
|
|
476
|
+
? t('editAppointment', 'Edit appointment')
|
|
477
|
+
: t('createNewAppointment', 'Create new appointment');
|
|
481
478
|
|
|
482
479
|
return (
|
|
483
|
-
<
|
|
484
|
-
{
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
<
|
|
496
|
-
<
|
|
497
|
-
<
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
locations
|
|
513
|
-
|
|
514
|
-
{location.display}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
/>
|
|
520
|
-
</ResponsiveWrapper>
|
|
521
|
-
</FormGroup>
|
|
522
|
-
<FormGroup className={styles.formGroup} legendText={t('service', 'Service')}>
|
|
523
|
-
<ResponsiveWrapper>
|
|
524
|
-
<Controller
|
|
525
|
-
name="selectedService"
|
|
526
|
-
control={control}
|
|
527
|
-
render={({ field: { onBlur, onChange, value, ref } }) => (
|
|
528
|
-
<Select
|
|
529
|
-
id="service"
|
|
530
|
-
invalid={!!errors?.selectedService}
|
|
531
|
-
invalidText={errors?.selectedService?.message}
|
|
532
|
-
labelText={t('selectService', 'Select a service')}
|
|
533
|
-
onBlur={onBlur}
|
|
534
|
-
onChange={(event) => {
|
|
535
|
-
if (context === 'creating') {
|
|
536
|
-
setValue(
|
|
537
|
-
'duration',
|
|
538
|
-
services?.find((service) => service.name === event.target.value)?.durationMins,
|
|
539
|
-
);
|
|
540
|
-
} else if (context === 'editing') {
|
|
541
|
-
const previousServiceDuration = services?.find(
|
|
542
|
-
(service) => service.name === getValues('selectedService'),
|
|
543
|
-
)?.durationMins;
|
|
544
|
-
const selectedServiceDuration = services?.find(
|
|
545
|
-
(service) => service.name === event.target.value,
|
|
546
|
-
)?.durationMins;
|
|
547
|
-
if (selectedServiceDuration && previousServiceDuration === getValues('duration')) {
|
|
548
|
-
setValue('duration', selectedServiceDuration);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
onChange(event);
|
|
552
|
-
}}
|
|
553
|
-
ref={ref}
|
|
554
|
-
value={value}>
|
|
555
|
-
<SelectItem text={t('chooseService', 'Select service')} value="" />
|
|
556
|
-
{services?.length > 0 &&
|
|
557
|
-
services.map((service) => (
|
|
558
|
-
<SelectItem key={service.uuid} text={service.name} value={service.name}>
|
|
559
|
-
{service.name}
|
|
560
|
-
</SelectItem>
|
|
561
|
-
))}
|
|
562
|
-
</Select>
|
|
563
|
-
)}
|
|
564
|
-
/>
|
|
565
|
-
</ResponsiveWrapper>
|
|
566
|
-
</FormGroup>
|
|
567
|
-
<FormGroup className={styles.formGroup} legendText={t('appointmentType_title', 'Appointment Type')}>
|
|
568
|
-
<ResponsiveWrapper>
|
|
569
|
-
<Controller
|
|
570
|
-
name="appointmentType"
|
|
571
|
-
control={control}
|
|
572
|
-
render={({ field: { onBlur, onChange, value, ref } }) => (
|
|
573
|
-
<Select
|
|
574
|
-
disabled={!appointmentTypes?.length}
|
|
575
|
-
id="appointmentType"
|
|
576
|
-
invalid={!!errors?.appointmentType}
|
|
577
|
-
invalidText={errors?.appointmentType?.message}
|
|
578
|
-
labelText={t('selectAppointmentType', 'Select the type of appointment')}
|
|
579
|
-
onBlur={onBlur}
|
|
580
|
-
onChange={onChange}
|
|
581
|
-
ref={ref}
|
|
582
|
-
value={value}>
|
|
583
|
-
<SelectItem text={t('chooseAppointmentType', 'Choose appointment type')} value="" />
|
|
584
|
-
{appointmentTypes?.length > 0 &&
|
|
585
|
-
appointmentTypes.map((appointmentType, index) => (
|
|
586
|
-
<SelectItem key={index} text={appointmentType} value={appointmentType}>
|
|
587
|
-
{appointmentType}
|
|
588
|
-
</SelectItem>
|
|
589
|
-
))}
|
|
590
|
-
</Select>
|
|
591
|
-
)}
|
|
592
|
-
/>
|
|
593
|
-
</ResponsiveWrapper>
|
|
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')}>
|
|
609
|
-
<div className={styles.dateTimeFields}>
|
|
610
|
-
{isRecurringAppointment && (
|
|
611
|
-
<div className={styles.inputContainer}>
|
|
612
|
-
{allowAllDayAppointments && (
|
|
613
|
-
<Controller
|
|
614
|
-
name="isAllDayAppointment"
|
|
615
|
-
control={control}
|
|
616
|
-
render={({ field: { value, onChange } }) => (
|
|
617
|
-
<Toggle
|
|
618
|
-
id="allDayToggle"
|
|
619
|
-
labelA={t('no', 'No')}
|
|
620
|
-
labelB={t('yes', 'Yes')}
|
|
621
|
-
labelText={t('allDay', 'All day')}
|
|
622
|
-
toggled={value}
|
|
623
|
-
onToggle={onChange}
|
|
624
|
-
/>
|
|
625
|
-
)}
|
|
626
|
-
/>
|
|
480
|
+
<Workspace2 title={title} hasUnsavedChanges={isDirty}>
|
|
481
|
+
<Form onSubmit={handleSubmit(handleSaveAppointment)}>
|
|
482
|
+
{patient && (
|
|
483
|
+
<ExtensionSlot
|
|
484
|
+
name="patient-header-slot"
|
|
485
|
+
state={{
|
|
486
|
+
patient,
|
|
487
|
+
patientUuid: patientUuid,
|
|
488
|
+
hideActionsOverflow: true,
|
|
489
|
+
}}
|
|
490
|
+
/>
|
|
491
|
+
)}
|
|
492
|
+
<Stack className={styles.formWrapper} gap={6}>
|
|
493
|
+
<FormGroup className={styles.formGroup} legendText={t('location', 'Location')}>
|
|
494
|
+
<ResponsiveWrapper>
|
|
495
|
+
<Controller
|
|
496
|
+
name="location"
|
|
497
|
+
control={control}
|
|
498
|
+
render={({ field: { onChange, value, onBlur, ref } }) => (
|
|
499
|
+
<Select
|
|
500
|
+
id="location"
|
|
501
|
+
invalid={!!errors?.location}
|
|
502
|
+
invalidText={errors?.location?.message}
|
|
503
|
+
labelText={t('selectALocation', 'Select a location')}
|
|
504
|
+
onChange={onChange}
|
|
505
|
+
onBlur={onBlur}
|
|
506
|
+
ref={ref}
|
|
507
|
+
value={value}>
|
|
508
|
+
<SelectItem text={t('chooseLocation', 'Choose a location')} value="" />
|
|
509
|
+
{locations?.length > 0 &&
|
|
510
|
+
locations.map((location) => (
|
|
511
|
+
<SelectItem key={location.uuid} text={location.display} value={location.uuid}>
|
|
512
|
+
{location.display}
|
|
513
|
+
</SelectItem>
|
|
514
|
+
))}
|
|
515
|
+
</Select>
|
|
627
516
|
)}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
517
|
+
/>
|
|
518
|
+
</ResponsiveWrapper>
|
|
519
|
+
</FormGroup>
|
|
520
|
+
<FormGroup className={styles.formGroup} legendText={t('service', 'Service')}>
|
|
521
|
+
<ResponsiveWrapper>
|
|
522
|
+
<Controller
|
|
523
|
+
name="selectedService"
|
|
524
|
+
control={control}
|
|
525
|
+
render={({ field: { onBlur, onChange, value, ref } }) => (
|
|
526
|
+
<Select
|
|
527
|
+
id="service"
|
|
528
|
+
invalid={!!errors?.selectedService}
|
|
529
|
+
invalidText={errors?.selectedService?.message}
|
|
530
|
+
labelText={t('selectService', 'Select a service')}
|
|
531
|
+
onBlur={onBlur}
|
|
532
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
533
|
+
if (!isEditing) {
|
|
534
|
+
setValue(
|
|
535
|
+
'duration',
|
|
536
|
+
services?.find((service) => service.name === event.target.value)?.durationMins,
|
|
537
|
+
);
|
|
538
|
+
} else {
|
|
539
|
+
const previousServiceDuration = services?.find(
|
|
540
|
+
(service) => service.name === getValues('selectedService'),
|
|
541
|
+
)?.durationMins;
|
|
542
|
+
const selectedServiceDuration = services?.find(
|
|
543
|
+
(service) => service.name === event.target.value,
|
|
544
|
+
)?.durationMins;
|
|
545
|
+
if (selectedServiceDuration && previousServiceDuration === getValues('duration')) {
|
|
546
|
+
setValue('duration', selectedServiceDuration);
|
|
638
547
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
<RadioButton labelText={t('day', 'Day')} value="DAY" id="radioDay" />
|
|
697
|
-
<RadioButton labelText={t('week', 'Week')} value="WEEK" id="radioWeek" />
|
|
698
|
-
</RadioButtonGroup>
|
|
699
|
-
)}
|
|
700
|
-
/>
|
|
701
|
-
</ResponsiveWrapper>
|
|
548
|
+
}
|
|
549
|
+
onChange(event);
|
|
550
|
+
}}
|
|
551
|
+
ref={ref}
|
|
552
|
+
value={value}>
|
|
553
|
+
<SelectItem text={t('chooseService', 'Select service')} value="" />
|
|
554
|
+
{services?.length > 0 &&
|
|
555
|
+
services.map((service) => (
|
|
556
|
+
<SelectItem key={service.uuid} text={service.name} value={service.name}>
|
|
557
|
+
{service.name}
|
|
558
|
+
</SelectItem>
|
|
559
|
+
))}
|
|
560
|
+
</Select>
|
|
561
|
+
)}
|
|
562
|
+
/>
|
|
563
|
+
</ResponsiveWrapper>
|
|
564
|
+
</FormGroup>
|
|
565
|
+
<FormGroup className={styles.formGroup} legendText={t('appointmentType_title', 'Appointment Type')}>
|
|
566
|
+
<ResponsiveWrapper>
|
|
567
|
+
<Controller
|
|
568
|
+
name="appointmentType"
|
|
569
|
+
control={control}
|
|
570
|
+
render={({ field: { onBlur, onChange, value, ref } }) => (
|
|
571
|
+
<Select
|
|
572
|
+
disabled={!appointmentTypes?.length}
|
|
573
|
+
id="appointmentType"
|
|
574
|
+
invalid={!!errors?.appointmentType}
|
|
575
|
+
invalidText={errors?.appointmentType?.message}
|
|
576
|
+
labelText={t('selectAppointmentType', 'Select the type of appointment')}
|
|
577
|
+
onBlur={onBlur}
|
|
578
|
+
onChange={onChange}
|
|
579
|
+
ref={ref}
|
|
580
|
+
value={value}>
|
|
581
|
+
<SelectItem text={t('chooseAppointmentType', 'Choose appointment type')} value="" />
|
|
582
|
+
{appointmentTypes?.length > 0 &&
|
|
583
|
+
appointmentTypes.map((appointmentType, index) => (
|
|
584
|
+
<SelectItem key={index} text={appointmentType} value={appointmentType}>
|
|
585
|
+
{appointmentType}
|
|
586
|
+
</SelectItem>
|
|
587
|
+
))}
|
|
588
|
+
</Select>
|
|
589
|
+
)}
|
|
590
|
+
/>
|
|
591
|
+
</ResponsiveWrapper>
|
|
592
|
+
</FormGroup>
|
|
593
|
+
|
|
594
|
+
<FormGroup className={styles.formGroup} legendText={t('recurringAppointment', 'Recurring Appointment')}>
|
|
595
|
+
<div>
|
|
596
|
+
<Toggle
|
|
597
|
+
id="recurringToggle"
|
|
598
|
+
labelB={t('yes', 'Yes')}
|
|
599
|
+
labelA={t('no', 'No')}
|
|
600
|
+
labelText={t('isRecurringAppointment', 'Is this a recurring appointment?')}
|
|
601
|
+
onClick={() => setIsRecurringAppointment(!isRecurringAppointment)}
|
|
602
|
+
/>
|
|
603
|
+
</div>
|
|
604
|
+
</FormGroup>
|
|
702
605
|
|
|
703
|
-
|
|
704
|
-
|
|
606
|
+
<FormGroup className={styles.formGroup} legendText={t('dateTime', 'Date & Time')}>
|
|
607
|
+
<div className={styles.dateTimeFields}>
|
|
608
|
+
{isRecurringAppointment && (
|
|
609
|
+
<div className={styles.inputContainer}>
|
|
610
|
+
{allowAllDayAppointments && (
|
|
705
611
|
<Controller
|
|
706
|
-
name="
|
|
612
|
+
name="isAllDayAppointment"
|
|
707
613
|
control={control}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
614
|
+
render={({ field: { value, onChange } }) => (
|
|
615
|
+
<Toggle
|
|
616
|
+
id="allDayToggle"
|
|
617
|
+
labelA={t('no', 'No')}
|
|
618
|
+
labelB={t('yes', 'Yes')}
|
|
619
|
+
labelText={t('allDay', 'All day')}
|
|
620
|
+
toggled={value}
|
|
621
|
+
onToggle={onChange}
|
|
622
|
+
/>
|
|
623
|
+
)}
|
|
624
|
+
/>
|
|
625
|
+
)}
|
|
626
|
+
<ResponsiveWrapper>
|
|
627
|
+
<Controller
|
|
628
|
+
name="appointmentDateTime"
|
|
629
|
+
control={control}
|
|
630
|
+
render={({ field: { onChange, value }, fieldState }) => (
|
|
631
|
+
<OpenmrsDateRangePicker
|
|
632
|
+
value={
|
|
633
|
+
value.startDate && value.recurringPatternEndDate
|
|
634
|
+
? [value.startDate, value.recurringPatternEndDate]
|
|
635
|
+
: null
|
|
636
|
+
}
|
|
637
|
+
onChange={(dateRange) => {
|
|
638
|
+
const [startDate, endDate] = dateRange;
|
|
639
|
+
onChange({
|
|
640
|
+
...value,
|
|
641
|
+
startDate,
|
|
642
|
+
startDateText: startDate ? dayjs(startDate).format(dateFormat) : '',
|
|
643
|
+
recurringPatternEndDate: endDate,
|
|
644
|
+
recurringPatternEndDateText: endDate ? dayjs(endDate).format(dateFormat) : '',
|
|
645
|
+
});
|
|
722
646
|
}}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
647
|
+
startName="start"
|
|
648
|
+
endName="end"
|
|
649
|
+
id="appointmentRecurringDateRangePicker"
|
|
650
|
+
data-testid="appointmentRecurringDateRangePicker"
|
|
651
|
+
labelText={t('dateRange', 'Set date range')}
|
|
652
|
+
invalid={!!fieldState?.error?.message}
|
|
653
|
+
invalidText={fieldState?.error?.message}
|
|
654
|
+
isRequired
|
|
655
|
+
/>
|
|
656
|
+
)}
|
|
657
|
+
/>
|
|
658
|
+
</ResponsiveWrapper>
|
|
659
|
+
|
|
660
|
+
{!watch('isAllDayAppointment') && <TimeAndDuration t={t} control={control} errors={errors} />}
|
|
661
|
+
|
|
662
|
+
<ResponsiveWrapper>
|
|
663
|
+
<Controller
|
|
664
|
+
name="recurringPatternPeriod"
|
|
665
|
+
control={control}
|
|
666
|
+
render={({ field: { onBlur, onChange, value } }) => (
|
|
667
|
+
<NumberInput
|
|
668
|
+
hideSteppers
|
|
669
|
+
id="repeatNumber"
|
|
670
|
+
min={1}
|
|
671
|
+
max={356}
|
|
672
|
+
label={t('repeatEvery', 'Repeat every')}
|
|
673
|
+
invalidText={t('invalidNumber', 'Number is not valid')}
|
|
674
|
+
value={value}
|
|
675
|
+
onBlur={onBlur}
|
|
676
|
+
onChange={(e) => {
|
|
677
|
+
onChange(Number(e.target.value));
|
|
726
678
|
}}
|
|
727
679
|
/>
|
|
728
680
|
)}
|
|
729
681
|
/>
|
|
730
|
-
</
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
682
|
+
</ResponsiveWrapper>
|
|
683
|
+
|
|
684
|
+
<ResponsiveWrapper>
|
|
685
|
+
<Controller
|
|
686
|
+
name="recurringPatternType"
|
|
687
|
+
control={control}
|
|
688
|
+
render={({ field: { onChange, value } }) => (
|
|
689
|
+
<RadioButtonGroup
|
|
690
|
+
legendText={t('period', 'Period')}
|
|
691
|
+
name="radio-button-group"
|
|
692
|
+
onChange={(type) => onChange(type)}
|
|
693
|
+
valueSelected={value}>
|
|
694
|
+
<RadioButton labelText={t('day', 'Day')} value="DAY" id="radioDay" />
|
|
695
|
+
<RadioButton labelText={t('week', 'Week')} value="WEEK" id="radioWeek" />
|
|
696
|
+
</RadioButtonGroup>
|
|
697
|
+
)}
|
|
698
|
+
/>
|
|
699
|
+
</ResponsiveWrapper>
|
|
700
|
+
|
|
701
|
+
{watch('recurringPatternType') === 'WEEK' && (
|
|
702
|
+
<div>
|
|
703
|
+
<Controller
|
|
704
|
+
name="selectedDaysOfWeekText"
|
|
705
|
+
control={control}
|
|
706
|
+
defaultValue={defaultSelectedDaysOfWeekText}
|
|
707
|
+
render={({ field: { onChange } }) => (
|
|
708
|
+
<MultiSelect
|
|
709
|
+
className={styles.weekSelect}
|
|
710
|
+
id="daysOfWeek"
|
|
711
|
+
initialSelectedItems={weekDays.filter((i) =>
|
|
712
|
+
getValues('recurringPatternDaysOfWeek').includes(i.id),
|
|
713
|
+
)}
|
|
714
|
+
items={weekDays}
|
|
715
|
+
itemToString={(item) => (item ? t(item.labelCode, item.label) : '')}
|
|
716
|
+
label={getValues('selectedDaysOfWeekText')}
|
|
717
|
+
onChange={(e) => {
|
|
718
|
+
onChange(e);
|
|
719
|
+
handleSelectChange(e);
|
|
720
|
+
}}
|
|
721
|
+
selectionFeedback="top-after-reopen"
|
|
722
|
+
sortItems={(items) => {
|
|
723
|
+
return items.sort((a, b) => a.order > b.order);
|
|
724
|
+
}}
|
|
725
|
+
/>
|
|
726
|
+
)}
|
|
773
727
|
/>
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
</
|
|
728
|
+
</div>
|
|
729
|
+
)}
|
|
730
|
+
</div>
|
|
731
|
+
)}
|
|
777
732
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
733
|
+
{!isRecurringAppointment && (
|
|
734
|
+
<div className={styles.inputContainer}>
|
|
735
|
+
{allowAllDayAppointments && (
|
|
736
|
+
<Controller
|
|
737
|
+
name="isAllDayAppointment"
|
|
738
|
+
control={control}
|
|
739
|
+
render={({ field: { value, onChange } }) => (
|
|
740
|
+
<Toggle
|
|
741
|
+
id="allDayToggle"
|
|
742
|
+
labelA={t('no', 'No')}
|
|
743
|
+
labelB={t('yes', 'Yes')}
|
|
744
|
+
labelText={t('allDay', 'All day')}
|
|
745
|
+
toggled={value}
|
|
746
|
+
onToggle={onChange}
|
|
747
|
+
/>
|
|
748
|
+
)}
|
|
749
|
+
/>
|
|
750
|
+
)}
|
|
751
|
+
<ResponsiveWrapper>
|
|
752
|
+
<Controller
|
|
753
|
+
name="appointmentDateTime"
|
|
754
|
+
control={control}
|
|
755
|
+
render={({ field, fieldState }) => (
|
|
756
|
+
<OpenmrsDatePicker
|
|
757
|
+
data-testid="datePickerInput"
|
|
758
|
+
id="datePickerInput"
|
|
759
|
+
invalid={!!fieldState?.error?.message}
|
|
760
|
+
invalidText={fieldState?.error?.message}
|
|
761
|
+
labelText={t('date', 'Date')}
|
|
762
|
+
onBlur={field.onBlur}
|
|
763
|
+
onChange={(date) => {
|
|
764
|
+
field.onChange({
|
|
765
|
+
...field.value,
|
|
766
|
+
startDate: date,
|
|
767
|
+
});
|
|
768
|
+
}}
|
|
769
|
+
style={{ width: '100%' }}
|
|
770
|
+
value={field.value.startDate}
|
|
771
|
+
/>
|
|
772
|
+
)}
|
|
773
|
+
/>
|
|
774
|
+
</ResponsiveWrapper>
|
|
783
775
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
appointmentDate={watch('appointmentDateTime').startDate}
|
|
789
|
-
onWorkloadDateChange={handleWorkloadDateChange}
|
|
790
|
-
selectedService={watch('selectedService')}
|
|
791
|
-
/>
|
|
792
|
-
</ResponsiveWrapper>
|
|
776
|
+
{!watch('isAllDayAppointment') && <TimeAndDuration t={t} control={control} errors={errors} />}
|
|
777
|
+
</div>
|
|
778
|
+
)}
|
|
779
|
+
</div>
|
|
793
780
|
</FormGroup>
|
|
794
|
-
)}
|
|
795
781
|
|
|
796
|
-
|
|
797
|
-
|
|
782
|
+
{getValues('selectedService') && (
|
|
783
|
+
<FormGroup className={styles.formGroup} legendText="">
|
|
784
|
+
<ResponsiveWrapper>
|
|
785
|
+
<Workload
|
|
786
|
+
appointmentDate={watch('appointmentDateTime').startDate}
|
|
787
|
+
onWorkloadDateChange={handleWorkloadDateChange}
|
|
788
|
+
selectedService={watch('selectedService')}
|
|
789
|
+
/>
|
|
790
|
+
</ResponsiveWrapper>
|
|
791
|
+
</FormGroup>
|
|
792
|
+
)}
|
|
793
|
+
|
|
794
|
+
{isEditing ? (
|
|
795
|
+
<FormGroup className={styles.formGroup} legendText={t('appointmentStatus', 'Appointment Status')}>
|
|
796
|
+
<ResponsiveWrapper>
|
|
797
|
+
<Controller
|
|
798
|
+
name="appointmentStatus"
|
|
799
|
+
control={control}
|
|
800
|
+
render={({ field: { onBlur, onChange, value, ref } }) => (
|
|
801
|
+
<Select
|
|
802
|
+
id="appointmentStatus"
|
|
803
|
+
invalid={!!errors?.appointmentStatus}
|
|
804
|
+
invalidText={errors?.appointmentStatus?.message}
|
|
805
|
+
labelText={t('selectAppointmentStatus', 'Select status')}
|
|
806
|
+
onBlur={onBlur}
|
|
807
|
+
onChange={onChange}
|
|
808
|
+
ref={ref}
|
|
809
|
+
value={value}>
|
|
810
|
+
<SelectItem text={t('selectAppointmentStatus', 'Select status')} value="" />
|
|
811
|
+
{appointmentStatuses?.length > 0 &&
|
|
812
|
+
appointmentStatuses.map((appointmentStatus, index) => (
|
|
813
|
+
<SelectItem key={index} text={appointmentStatus} value={appointmentStatus}>
|
|
814
|
+
{appointmentStatus}
|
|
815
|
+
</SelectItem>
|
|
816
|
+
))}
|
|
817
|
+
</Select>
|
|
818
|
+
)}
|
|
819
|
+
/>
|
|
820
|
+
</ResponsiveWrapper>
|
|
821
|
+
</FormGroup>
|
|
822
|
+
) : null}
|
|
823
|
+
|
|
824
|
+
<FormGroup className={styles.formGroup} legendText={t('provider', 'Provider')}>
|
|
798
825
|
<ResponsiveWrapper>
|
|
799
826
|
<Controller
|
|
800
|
-
name="
|
|
827
|
+
name="provider"
|
|
801
828
|
control={control}
|
|
802
|
-
render={({ field: {
|
|
829
|
+
render={({ field: { onChange, value, onBlur, ref } }) => (
|
|
803
830
|
<Select
|
|
804
|
-
id="
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
labelText={t('selectAppointmentStatus', 'Select status')}
|
|
808
|
-
onBlur={onBlur}
|
|
831
|
+
id="provider"
|
|
832
|
+
invalidText="Required"
|
|
833
|
+
labelText={t('selectProvider', 'Select a provider')}
|
|
809
834
|
onChange={onChange}
|
|
835
|
+
onBlur={onBlur}
|
|
810
836
|
ref={ref}
|
|
811
837
|
value={value}>
|
|
812
|
-
<SelectItem text={t('
|
|
813
|
-
{
|
|
814
|
-
|
|
815
|
-
<SelectItem key={
|
|
816
|
-
{
|
|
838
|
+
<SelectItem text={t('chooseProvider', 'Choose a provider')} value="" />
|
|
839
|
+
{providers?.providers?.length > 0 &&
|
|
840
|
+
providers?.providers?.map((provider) => (
|
|
841
|
+
<SelectItem key={provider.uuid} text={provider.display} value={provider.uuid}>
|
|
842
|
+
{provider.display}
|
|
817
843
|
</SelectItem>
|
|
818
844
|
))}
|
|
819
845
|
</Select>
|
|
@@ -821,93 +847,66 @@ const AppointmentsForm: React.FC<AppointmentsFormProps & DefaultWorkspaceProps>
|
|
|
821
847
|
/>
|
|
822
848
|
</ResponsiveWrapper>
|
|
823
849
|
</FormGroup>
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
<
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
</
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
maxDate={new Date()}
|
|
869
|
-
onBlur={field.onBlur}
|
|
870
|
-
onChange={field.onChange}
|
|
871
|
-
style={{ width: '100%' }}
|
|
872
|
-
value={field.value}
|
|
850
|
+
|
|
851
|
+
<FormGroup
|
|
852
|
+
className={styles.formGroup}
|
|
853
|
+
legendText={t('dateAppointmentScheduled', 'Date appointment scheduled')}>
|
|
854
|
+
<ResponsiveWrapper>
|
|
855
|
+
<Controller
|
|
856
|
+
name="dateAppointmentScheduled"
|
|
857
|
+
control={control}
|
|
858
|
+
render={({ field, fieldState }) => (
|
|
859
|
+
<div style={{ width: '100%' }}>
|
|
860
|
+
<OpenmrsDatePicker
|
|
861
|
+
data-testid="dateAppointmentScheduledPickerInput"
|
|
862
|
+
id="dateAppointmentScheduledPickerInput"
|
|
863
|
+
invalid={!!fieldState?.error?.message}
|
|
864
|
+
invalidText={fieldState?.error?.message}
|
|
865
|
+
labelText={t('dateAppointmentIssued', 'Date appointment issued')}
|
|
866
|
+
maxDate={new Date()}
|
|
867
|
+
onBlur={field.onBlur}
|
|
868
|
+
onChange={field.onChange}
|
|
869
|
+
style={{ width: '100%' }}
|
|
870
|
+
value={field.value}
|
|
871
|
+
/>
|
|
872
|
+
</div>
|
|
873
|
+
)}
|
|
874
|
+
/>
|
|
875
|
+
</ResponsiveWrapper>
|
|
876
|
+
</FormGroup>
|
|
877
|
+
|
|
878
|
+
<FormGroup className={styles.formGroup} legendText={t('note', 'Note')}>
|
|
879
|
+
<ResponsiveWrapper>
|
|
880
|
+
<Controller
|
|
881
|
+
name="appointmentNote"
|
|
882
|
+
control={control}
|
|
883
|
+
render={({ field: { onChange, onBlur, value, ref } }) => (
|
|
884
|
+
<TextArea
|
|
885
|
+
enableCounter
|
|
886
|
+
id="appointmentNote"
|
|
887
|
+
value={value}
|
|
888
|
+
labelText={t('appointmentNoteLabel', 'Write an additional note')}
|
|
889
|
+
placeholder={t('appointmentNotePlaceholder', 'Write any additional points here')}
|
|
890
|
+
maxCount={255}
|
|
891
|
+
onChange={onChange}
|
|
892
|
+
onBlur={onBlur}
|
|
893
|
+
ref={ref}
|
|
873
894
|
/>
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
</
|
|
878
|
-
</
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
value={value}
|
|
890
|
-
labelText={t('appointmentNoteLabel', 'Write an additional note')}
|
|
891
|
-
placeholder={t('appointmentNotePlaceholder', 'Write any additional points here')}
|
|
892
|
-
maxCount={255}
|
|
893
|
-
onChange={onChange}
|
|
894
|
-
onBlur={onBlur}
|
|
895
|
-
ref={ref}
|
|
896
|
-
/>
|
|
897
|
-
)}
|
|
898
|
-
/>
|
|
899
|
-
</ResponsiveWrapper>
|
|
900
|
-
</FormGroup>
|
|
901
|
-
</Stack>
|
|
902
|
-
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
903
|
-
<Button className={styles.button} onClick={closeWorkspace} kind="secondary">
|
|
904
|
-
{t('discard', 'Discard')}
|
|
905
|
-
</Button>
|
|
906
|
-
<Button className={styles.button} disabled={isSubmitting} type="submit">
|
|
907
|
-
{t('saveAndClose', 'Save and close')}
|
|
908
|
-
</Button>
|
|
909
|
-
</ButtonSet>
|
|
910
|
-
</Form>
|
|
895
|
+
)}
|
|
896
|
+
/>
|
|
897
|
+
</ResponsiveWrapper>
|
|
898
|
+
</FormGroup>
|
|
899
|
+
</Stack>
|
|
900
|
+
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
901
|
+
<Button className={styles.button} onClick={closeWorkspace} kind="secondary">
|
|
902
|
+
{t('discard', 'Discard')}
|
|
903
|
+
</Button>
|
|
904
|
+
<Button className={styles.button} disabled={isSubmitting} type="submit">
|
|
905
|
+
{t('saveAndClose', 'Save and close')}
|
|
906
|
+
</Button>
|
|
907
|
+
</ButtonSet>
|
|
908
|
+
</Form>
|
|
909
|
+
</Workspace2>
|
|
911
910
|
);
|
|
912
911
|
};
|
|
913
912
|
|
|
@@ -937,7 +936,7 @@ function TimeAndDuration({ t, control, errors }: TimeAndDurationProps) {
|
|
|
937
936
|
invalid={!!errors?.startTime}
|
|
938
937
|
invalidText={errors?.startTime?.message}
|
|
939
938
|
labelText={t('time', 'Time')}
|
|
940
|
-
onChange={(event) => {
|
|
939
|
+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
941
940
|
onChange(event.target.value);
|
|
942
941
|
}}
|
|
943
942
|
style={{ marginLeft: '0.125rem', flex: 'none' }}
|
|
@@ -948,7 +947,9 @@ function TimeAndDuration({ t, control, errors }: TimeAndDurationProps) {
|
|
|
948
947
|
render={({ field: { value, onChange } }) => (
|
|
949
948
|
<TimePickerSelect
|
|
950
949
|
id="time-picker-select-1"
|
|
951
|
-
onChange={(event) =>
|
|
950
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
951
|
+
onChange(event.target.value as 'AM' | 'PM')
|
|
952
|
+
}
|
|
952
953
|
value={value}
|
|
953
954
|
aria-label={t('time', 'Time')}>
|
|
954
955
|
<SelectItem value="AM" text="AM" />
|