import React, { useState, useCallback, useMemo } from 'react'; import styles from './clinical-view-form.component.scss'; import debounce from 'lodash-es/debounce'; import isEmpty from 'lodash-es/isEmpty'; import cloneDeep from 'lodash-es/cloneDeep'; import set from 'lodash-es/set'; import { Search, Checkbox, Button, StructuredListSkeleton, ButtonSet } from 'carbon-components-react'; import { useTranslation } from 'react-i18next'; import { detach, temporaryConfigStore, TemporaryConfigStore } from '@openmrs/esm-framework'; import { useClinicalView } from '../store'; interface ClinicalViewFormProps { isTablet: boolean; } interface View { slotName: string; slot: string; checked: boolean; } const ClinicalViewForm: React.FC = ({ isTablet }) => { const { t } = useTranslation(); const { views, clinicalViews } = useClinicalView(); const moduleName = '@openmrs/esm-patient-clinical-view-app'; const path = useMemo(() => [moduleName, 'clinicalViews'], []); const [searchTerm, setSearchTerm] = React.useState(''); const [searchResults, setSearchResult] = React.useState>([]); const [tempConfig, setTempConfig] = useState(null); const [isPending, setIsPending] = useState(true); React.useEffect(() => { if (!isEmpty(views)) { setSearchResult(views); setIsPending(false); } }, [views]); React.useEffect(() => { const results = views.filter( (view) => view.slotName.toLocaleLowerCase().search(searchTerm.toLocaleLowerCase()) !== -1, ); setSearchResult(results); }, [searchTerm, views]); const handleSearch = useMemo(() => debounce((searchTerm) => setSearchTerm(searchTerm), 300), []); const closeClinicalViewForm = useCallback(() => { detach('patient-chart-workspace-slot', 'patient-clinical-view-form-workspace'); }, []); const addClinicalView = useCallback( (slot: string, slotName: string) => { const results = searchResults.map((view) => (view.slot === slotName ? { ...view, checked: true } : view)); setSearchResult(results); const viewConfig = tempConfig ? tempConfig.config[moduleName].clinicalViews : clinicalViews; const updateClinicalViews = [...viewConfig, { slot: slot, slotName: slotName }]; const tempConfigUpdate = set( cloneDeep(temporaryConfigStore.getState()), ['config', ...path], updateClinicalViews, ); setTempConfig(tempConfigUpdate); }, [clinicalViews, path, searchResults, tempConfig], ); const removeClinicalView = useCallback( (slot: string, slotName: string) => { const slotIndex = clinicalViews.findIndex((view: View) => view.slotName === slotName); clinicalViews.splice(slotIndex, 1); const tempConfigUpdate = set(cloneDeep(temporaryConfigStore.getState()), ['config', ...path], clinicalViews); setTempConfig(tempConfigUpdate); const results = searchResults.map((view) => (view.slot === slotName ? { ...view, checked: false } : view)); setSearchResult(results); }, [clinicalViews, path, searchResults], ); const handleChange = useCallback( (slot: string, slotName: string, checked: boolean) => { checked ? addClinicalView(slot, slotName) : removeClinicalView(slot, slotName); }, [addClinicalView, removeClinicalView], ); const handleSave = useCallback(() => { temporaryConfigStore.setState(tempConfig); closeClinicalViewForm(); }, [tempConfig, closeClinicalViewForm]); const handleReset = useCallback(() => { const tempConfigUpdate = set(cloneDeep(temporaryConfigStore.getState()), ['config', ...path], clinicalViews); setTempConfig(tempConfigUpdate); setSearchResult(views); }, [clinicalViews, path, views]); return ( <> {isPending && } {!isPending && (
handleSearch(event.target.value)} labelText="" light={isTablet} size="xl" />
{searchResults?.map((view) => ( handleChange(view.slotName, view.slot, checked)} /> ))}
)} ); }; export default ClinicalViewForm;