diff --git a/.gitignore b/.gitignore index 739d132..cb7f040 100644 --- a/.gitignore +++ b/.gitignore @@ -65,9 +65,10 @@ typings/ dist/ -# Intellij integration +# IDE integration *.iml .idea/* +.vscode/ # ignores for Yarn v3 w/o PNP .pnp.* diff --git a/src/components/search-by-concepts/search-by-concepts.component.tsx b/src/components/search-by-concepts/search-by-concepts.component.tsx index d90b109..8d0ec1c 100644 --- a/src/components/search-by-concepts/search-by-concepts.component.tsx +++ b/src/components/search-by-concepts/search-by-concepts.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import { DatePicker, DatePickerInput, Column, Dropdown, NumberInput, Switch, ContentSwitcher } from '@carbon/react'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; @@ -69,7 +69,7 @@ const SearchByConcepts: React.FC = ({ onSubmit }) => { const [searchText, setSearchText] = useState(''); const [isLoading, setIsLoading] = useState(false); - const observationOptions = [ + const observationOptions = useMemo(() => [ { id: 'option-0', label: t('haveObservations', 'Patients who have these observations'), @@ -80,9 +80,9 @@ const SearchByConcepts: React.FC = ({ onSubmit }) => { label: t('haveNoObservations', 'Patients who do not have these observations'), value: 'NO', }, - ]; + ], [t]); - const whichObservation = [ + const whichObservation = useMemo(() => [ { id: 'option-0', label: t('any', 'Any'), @@ -118,9 +118,9 @@ const SearchByConcepts: React.FC = ({ onSubmit }) => { label: t('average', 'Average'), value: 'AVG', }, - ]; + ], [t]); - const handleReset = () => { + const handleReset = useCallback(() => { setConcept(null); setLastDays(0); setSearchText(''); @@ -130,15 +130,15 @@ const SearchByConcepts: React.FC = ({ onSubmit }) => { setOperatorValue(0); setOperator('LESS_THAN'); setTimeModifier('ANY'); - }; + }, []); - const getOnOrBefore = () => { + const getOnOrBefore = useCallback(() => { if (lastDays > 0 || lastMonths > 0) { return dayjs().subtract(lastDays, 'days').subtract(lastMonths, 'months').format(); } - }; + }, [lastDays, lastMonths]); - const handleSubmit = async () => { + const handleSubmit = useCallback(async () => { if (!concept) { return; } @@ -165,7 +165,7 @@ const SearchByConcepts: React.FC = ({ onSubmit }) => { }); await onSubmit(composeJson(params), queryDescriptionBuilder(observations, concept.name)); setIsLoading(false); - }; + }, [concept, operator, operatorValue, getOnOrBefore, onOrBefore, onOrAfter, timeModifier, onSubmit]); return ( <> diff --git a/src/components/search-by-demographics/search-by-demographics.component.tsx b/src/components/search-by-demographics/search-by-demographics.component.tsx index 7aa6af7..1fd0945 100644 --- a/src/components/search-by-demographics/search-by-demographics.component.tsx +++ b/src/components/search-by-demographics/search-by-demographics.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import classNames from 'classnames'; import dayjs from 'dayjs'; import { Column, ContentSwitcher, DatePicker, DatePickerInput, NumberInput, Switch } from '@carbon/react'; @@ -18,7 +18,7 @@ const SearchByDemographics: React.FC = ({ onSubmit }) => { const [maxAge, setMaxAge] = useState(0); const [isLoading, setIsLoading] = useState(false); - const genders = [ + const genders = useMemo(() => [ { id: 0, label: t('all', 'All'), @@ -34,9 +34,9 @@ const SearchByDemographics: React.FC = ({ onSubmit }) => { label: t('females', 'Female'), value: 'females', }, - ]; + ], [t]); - const livingStatuses = [ + const livingStatuses = useMemo(() => [ { id: 0, label: t('alive', 'Alive'), @@ -47,16 +47,16 @@ const SearchByDemographics: React.FC = ({ onSubmit }) => { label: t('dead', 'Dead'), value: 'dead', }, - ]; + ], [t]); - const reset = () => { + const reset = useCallback(() => { setMaxAge(0); setMinAge(0); setBirthDayEndDate(''); setBirthDayStartDate(''); - }; + }, []); - const submit = async () => { + const submit = useCallback(async () => { setIsLoading(true); const demographics = { gender, @@ -68,7 +68,7 @@ const SearchByDemographics: React.FC = ({ onSubmit }) => { }; await onSubmit(getQueryDetails(demographics), getDescription(demographics)); setIsLoading(false); - }; + }, [gender, minAge, maxAge, birthDayStartDate, birthDayEndDate, livingStatus, onSubmit]); return ( <> diff --git a/src/components/search-by-enrollments/search-by-enrollments.component.tsx b/src/components/search-by-enrollments/search-by-enrollments.component.tsx index 2624fcf..fd5d1b2 100644 --- a/src/components/search-by-enrollments/search-by-enrollments.component.tsx +++ b/src/components/search-by-enrollments/search-by-enrollments.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import dayjs from 'dayjs'; import { Column, DatePicker, DatePickerInput, MultiSelect } from '@carbon/react'; import { showSnackbar } from '@openmrs/esm-framework'; @@ -40,15 +40,15 @@ const SearchByEnrollments: React.FC = ({ onSubmit }) => { }); } - const handleResetInputs = () => { + const handleResetInputs = useCallback(() => { setSelectedPrograms(null); setEnrolledOnOrAfter(''); setEnrolledOnOrBefore(''); setCompletedOnOrAfter(''); setCompletedOnOrBefore(''); - }; + }, []); - const submit = async () => { + const submit = useCallback(async () => { setIsLoading(true); const searchParams = { enrolledOnOrAfter, @@ -60,7 +60,7 @@ const SearchByEnrollments: React.FC = ({ onSubmit }) => { }; await onSubmit(getQueryDetails(searchParams), getDescription(searchParams)); setIsLoading(false); - }; + }, [enrolledOnOrAfter, enrolledOnOrBefore, completedOnOrAfter, completedOnOrBefore, selectedPrograms, selectedLocations, onSubmit]); return ( <> diff --git a/src/components/search-by-location/search-by-location.component.tsx b/src/components/search-by-location/search-by-location.component.tsx index d89f003..fb135ae 100644 --- a/src/components/search-by-location/search-by-location.component.tsx +++ b/src/components/search-by-location/search-by-location.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import { Column, Dropdown, MultiSelect } from '@carbon/react'; import { showSnackbar } from '@openmrs/esm-framework'; @@ -11,7 +11,7 @@ import styles from './search-by-location.style.scss'; const SearchByLocation: React.FC = ({ onSubmit }) => { const { t } = useTranslation(); - const methods = [ + const methods = useMemo(() => [ { id: 0, label: t('anyEncounter', 'Any Encounter'), @@ -27,7 +27,7 @@ const SearchByLocation: React.FC = ({ onSubmit }) => { label: t('earliestEncounter', 'Earliest Encounter'), value: 'FIRST', }, - ]; + ], [t]); const { locations, locationsError } = useLocations(); const [selectedLocations, setSelectedLocations] = useState(null); const [selectedMethod, setSelectedMethod] = useState(methods[0]); @@ -42,19 +42,19 @@ const SearchByLocation: React.FC = ({ onSubmit }) => { }); } - const handleResetInputs = () => { + const handleResetInputs = useCallback(() => { setSelectedLocations(null); setSelectedMethod(null); - }; + }, []); - const submit = async () => { + const submit = useCallback(async () => { setIsLoading(true); await onSubmit( getQueryDetails(selectedMethod.value, selectedLocations), getDescription(selectedMethod.label, selectedLocations), ); setIsLoading(false); - }; + }, [selectedMethod, selectedLocations, onSubmit]); return ( <>