import React, { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ModalHeader, ModalBody, ModalFooter, Form, FormGroup, Stack, InlineLoading, InlineNotification, Dropdown, CheckboxGroup, Checkbox, RadioButtonGroup, RadioButton, Button, } from '@carbon/react'; import { showSnackbar } from '@openmrs/esm-framework'; import { useForms } from '@hooks/useForms'; import { useClobdata } from '@hooks/useClobdata'; import type { FormPage, FormSection, FormField } from '@openmrs/esm-form-engine-lib'; import type { Form as FormType, Schema } from '@types'; import styles from './add-form-reference.scss'; interface AddFormReferenceModalProps { closeModal: () => void; pageIndex: number; schema: Schema; onSchemaChange: (schema: Schema) => void; mode?: string; sectionIndex?: number; } const AddFormReferenceModal: React.FC = ({ closeModal, pageIndex, schema, onSchemaChange, mode, sectionIndex, }) => { const { t } = useTranslation(); const [selectedForm, setSelectedForm] = useState(null); const [pages, setPages] = useState([]); const [selectedPage, setSelectedPage] = useState(null); const [selectedSection, setSelectedSection] = useState(null); const [excludedQuestions, setExcludedQuestions] = useState([]); const { forms, error, isLoading } = useForms(); const { clobdata, isLoadingClobdata, clobdataError } = useClobdata(selectedForm); const selectForm = useCallback(({ selectedItem }: { selectedItem: FormType }) => { setSelectedForm(selectedItem); setSelectedPage(null); setSelectedSection(null); setExcludedQuestions([]); }, []); useEffect(() => { if (clobdata) { setPages(clobdata.pages); } }, [clobdata]); const handleSelectedPage = useCallback(({ selectedItem }: { selectedItem: FormPage }) => { setSelectedPage(selectedItem); setSelectedSection(null); setExcludedQuestions([]); }, []); const handleSelectedSections = useCallback((section: FormSection) => { setSelectedSection(section); setExcludedQuestions([]); }, []); const handleExcludedQuestions = useCallback((question: FormField, checked: boolean) => { setExcludedQuestions((prev) => { if (!checked) { return prev.some((q) => q === question.id) ? prev : [...prev, question.id]; } else { return prev.filter((q) => q !== question.id); } }); }, []); const handleUpdateSchema = () => { updateSchema(); closeModal(); }; const updateSchema = () => { try { if (mode === 'edit' && sectionIndex !== undefined) { schema.pages[pageIndex].sections[sectionIndex].reference.excludeQuestions = excludedQuestions; onSchemaChange({ ...schema }); showSnackbar({ title: t('success', 'Success!'), kind: 'success', isLowContrast: true, subtitle: t('questionsUpdated', 'Questions updated'), }); return; } if (!schema.referencedForms?.some((form) => form.formName === selectedForm.name)) { if (schema.referencedForms) { schema.referencedForms.push({ formName: selectedForm.name, alias: selectedForm.name, }); } else { schema.referencedForms = [ { formName: selectedForm.name, alias: selectedForm.name, }, ]; } } schema.pages[pageIndex].sections.push({ label: selectedSection.label, isExpanded: 'true', questions: [], reference: { form: selectedForm.name, page: selectedPage.label, section: selectedSection.label, excludeQuestions: excludedQuestions, }, }); onSchemaChange({ ...schema }); showSnackbar({ title: t('success', 'Success!'), kind: 'success', isLowContrast: true, subtitle: t('componentadded', 'Component added'), }); } catch (error) { if (error instanceof Error) { showSnackbar({ title: t('errorAddingComponent', 'Error adding component'), kind: 'error', subtitle: error?.message, }); } } }; useEffect(() => { if (mode !== 'edit' || sectionIndex === undefined || !forms) return; const sectionRef = schema.pages[pageIndex].sections[sectionIndex].reference; const form = forms.find((f) => f.name === sectionRef.form); if (form) { setSelectedForm(form); } }, [mode, sectionIndex, forms, schema, pageIndex]); useEffect(() => { if (mode !== 'edit' || !selectedForm || !clobdata || sectionIndex === undefined) return; const sectionRef = schema.pages[pageIndex].sections[sectionIndex].reference; const page = clobdata.pages.find((p) => p.label === sectionRef.page); if (page) { setSelectedPage(page); const section = page.sections.find((s) => s.label === sectionRef.section); if (section) { setSelectedSection(section); } setExcludedQuestions(sectionRef.excludeQuestions); } }, [mode, selectedForm, clobdata, schema, pageIndex, sectionIndex]); return ( <>
{isLoading ? ( ) : error ? ( {t('errorLoadingForms', 'Error loading forms')} ) : forms.length === 0 ? ( {t('noFormsAvailable', 'No forms available')} ) : !mode ? ( ({ uuid: form.uuid, name: form.name, resources: form.resources, }))} itemToString={(item: FormType) => (item ? item.name : '')} onChange={selectForm} /> ) : null} {isLoadingClobdata ? ( ) : clobdataError ? ( {t('errorLoadingForm', 'Error loading form')} ) : pages && pages.length > 0 && !mode ? ( <> ({ label: page.label, sections: page.sections, }))} itemToString={(item: FormPage) => (item ? item.label : '')} onChange={handleSelectedPage} selectedItem={selectedPage} /> {selectedPage ? ( {selectedPage.sections.map((section) => ( handleSelectedSections(section)} /> ))} ) : null} ) : null} {selectedSection ? ( {selectedSection.questions.map((question) => ( , { checked }) => handleExcludedQuestions(question, checked) } /> ))} ) : null}
); }; export default AddFormReferenceModal;