import React, { useMemo } from 'react'; import classNames from 'classnames'; import { Field } from 'formik'; import { useTranslation } from 'react-i18next'; import { InlineNotification, Layer, Select, SelectItem } from '@carbon/react'; import { OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework'; import { type ConceptResponse } from '../../patient-registration.types'; import { type FieldDefinition, type RegistrationConfig } from '../../../config-schema'; import { Input } from '../../input/basic-input/input/input.component'; import { useConcept, useConceptAnswers } from '../field.resource'; import { usePatientRegistrationContext } from '../../patient-registration-context'; import styles from './../field.scss'; export interface ObsFieldProps { fieldDefinition: FieldDefinition; } export function ObsField({ fieldDefinition }: ObsFieldProps) { const { t } = useTranslation(); const { data: concept, isLoading } = useConcept(fieldDefinition.uuid); const config = useConfig(); if (!config.registrationObs.encounterTypeUuid) { console.error( 'The registration form has been configured to have obs fields, ' + 'but no registration encounter type has been configured. Obs fields ' + 'will not be displayed.', ); return null; } if (isLoading) { return null; } switch (concept.datatype.display) { case 'Text': return ( ); case 'Numeric': return ( ); case 'Date': return ( ); case 'Coded': return ( ); default: return ( {t( 'obsFieldUnknownDatatype', `Concept for obs field '{{fieldDefinitionId}}' has unknown datatype '{{datatypeName}}'`, { fieldDefinitionId: fieldDefinition.id, datatypeName: concept.datatype.display }, )} ); } } interface TextObsFieldProps { concept: ConceptResponse; validationRegex: string; label: string; required?: boolean; } function TextObsField({ concept, validationRegex, label, required }: TextObsFieldProps) { const { t } = useTranslation(); const validateInput = (value: string) => { if (!value || !validationRegex || validationRegex === '' || typeof validationRegex !== 'string' || value === '') { return; } const regex = new RegExp(validationRegex); if (regex.test(value)) { return; } else { return t('invalidInput', 'Invalid Input'); } }; const fieldName = `obs.${concept.uuid}`; return (
{({ field, form: { touched, errors }, meta }) => { return ( ); }}
); } interface NumericObsFieldProps { concept: ConceptResponse; label: string; required?: boolean; } function NumericObsField({ concept, label, required }: NumericObsFieldProps) { const fieldName = `obs.${concept.uuid}`; return (
{({ field, form: { touched, errors }, meta }) => { return ( ); }}
); } interface DateObsFieldProps { concept: ConceptResponse; label: string; required?: boolean; allowPastDates?: boolean; allowFutureDates?: boolean; } function DateObsField({ concept, label, required, allowPastDates, allowFutureDates }: DateObsFieldProps) { const { t } = useTranslation(); const fieldName = `obs.${concept.uuid}`; const { setFieldValue } = usePatientRegistrationContext(); const futureDatesAllowed = allowFutureDates ?? true; const pastDatesAllowed = allowPastDates ?? true; const onDateChange = (date: Date) => { setFieldValue(fieldName, date); }; return (
{({ field, form: { touched, errors }, meta }) => { return ( <> ); }}
); } interface CodedObsFieldProps { concept: ConceptResponse; answerConceptSetUuid?: string; label?: string; required?: boolean; customConceptAnswers: Array<{ uuid: string; label?: string }>; } function CodedObsField({ concept, answerConceptSetUuid, label, required, customConceptAnswers }: CodedObsFieldProps) { const { t } = useTranslation(); const fieldName = `obs.${concept.uuid}`; const { data: conceptAnswers, isLoading: isLoadingConceptAnswers } = useConceptAnswers( customConceptAnswers.length ? '' : answerConceptSetUuid ?? concept.uuid, ); const answers = useMemo( () => customConceptAnswers.length ? customConceptAnswers : isLoadingConceptAnswers ? [] : conceptAnswers.map((answer) => ({ ...answer, label: answer.display })), [customConceptAnswers, conceptAnswers, isLoadingConceptAnswers], ); return (
{!isLoadingConceptAnswers ? ( {({ field, form: { touched, errors }, meta }) => { return ( ); }} ) : null}
); }