import React, { useCallback, useEffect, useMemo, useState } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { Layer, TimePicker } from '@carbon/react'; import { OpenmrsDatePicker } from '@openmrs/esm-framework'; import { formatDateAsDisplayString } from '../../../utils/common-utils'; import { isEmpty } from '../../../validators/form-validator'; import { isTrue } from '../../../utils/boolean-utils'; import { shouldUseInlineLayout } from '../../../utils/form-helper'; import { useFormProviderContext } from '../../../provider/form-provider'; import { type FormFieldInputProps } from '../../../types'; import FieldLabel from '../../field-label/field-label.component'; import FieldValueView from '../../value/view/field-value-view.component'; import styles from './date.scss'; const DateField: React.FC = ({ field, value: dateValue, errors, warnings, setFieldValue }) => { const { t } = useTranslation(); const [time, setTime] = useState(''); const { layoutType, sessionMode, workspaceLayout } = useFormProviderContext(); const isInline = useMemo(() => { if (['view', 'embedded-view'].includes(sessionMode) || isTrue(field.readonly)) { return shouldUseInlineLayout(field.inlineRendering, layoutType, workspaceLayout, sessionMode); } return false; }, [sessionMode, field.readonly, field.inlineRendering, layoutType, workspaceLayout]); const onDateChange = useCallback( (date: Date) => { setTimeIfPresent(date, time); setFieldValue(date); }, [setFieldValue, time], ); const setTimeIfPresent = useCallback((date: Date, time: string) => { if (!isEmpty(time)) { const [hours, minutes] = time.split(':').map(Number); date.setHours(hours ?? 0, minutes ?? 0); } }, []); const onTimeChange = useCallback( (event) => { const time = event.target.value; setTime(time); // TODO: Confirm if a new date should be instantiated when the date picker format is 'timer' // If the underlying concept's datatype is 'Time', then the backend expects a time string const date = field.datePickerFormat === 'timer' ? new Date() : new Date(dateValue); setTimeIfPresent(date, time); setFieldValue(date); }, [setFieldValue, setTimeIfPresent, dateValue], ); useEffect(() => { if (dateValue) { if (dateValue instanceof Date) { const hours = dateValue.getHours() < 10 ? `0${dateValue.getHours()}` : `${dateValue.getHours()}`; const minutes = dateValue.getMinutes() < 10 ? `0${dateValue.getMinutes()}` : `${dateValue.getMinutes()}`; setTime([hours, minutes].join(':')); } } }, [dateValue]); const timePickerLabel = useMemo( () => field.datePickerFormat === 'timer' ? ( ) : ( ), [field.datePickerFormat, field.label, t], ); return sessionMode == 'view' || sessionMode == 'embedded-view' || isTrue(field.readonly) ? ( ) : ( !field.isHidden && (
{(field.datePickerFormat === 'calendar' || field.datePickerFormat === 'both') && (
} isDisabled={field.isDisabled} isReadOnly={isTrue(field.readonly)} isRequired={field.isRequired ?? false} isInvalid={errors.length > 0} invalidText={errors[0]?.message} value={dateValue} /> {warnings.length > 0 ?
{warnings[0]?.message}
: null}
)} {field.datePickerFormat === 'both' || field.datePickerFormat === 'timer' ? (
0} invalidText={errors[0]?.message} readOnly={isTrue(field.readonly)} warning={warnings.length > 0} warningText={warnings[0]?.message} value={ time ? time : dateValue instanceof Date ? dateValue.toLocaleDateString(window.navigator.language) : dateValue } onChange={onTimeChange} />
) : null}
) ); }; export default DateField;