From 38b5953add5268596166c12ab10d8cb99846315b Mon Sep 17 00:00:00 2001 From: jabahum Date: Fri, 1 Nov 2024 15:04:11 +0300 Subject: [PATCH 1/5] remove unnecessary code --- ...ctive-visits-reception-table.component.tsx | 3 +- .../advanced-search.component.tsx | 192 ------------------ .../src/patient-search/advanced-search.scss | 154 -------------- .../patient-search/advanced-search.test.tsx | 29 --- .../patient-search/basic-search.component.tsx | 113 ----------- .../src/patient-search/basic-search.scss | 139 ------------- .../src/patient-search/basic-search.test.tsx | 23 --- .../empty-data-illustration.component.tsx | 41 ---- .../src/patient-search/hooks/usePatients.tsx | 25 --- .../hooks/useQueueLocations.tsx | 20 -- .../search-illustration.component.tsx | 27 --- .../search-results.component.tsx | 75 ------- .../src/patient-search/search-results.scss | 80 -------- .../patient-search/search-results.test.tsx | 77 ------- .../src/patient-search/search.resource.ts | 10 - 15 files changed, 2 insertions(+), 1006 deletions(-) delete mode 100644 packages/esm-patient-queues-app/src/patient-search/advanced-search.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/advanced-search.scss delete mode 100644 packages/esm-patient-queues-app/src/patient-search/advanced-search.test.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/basic-search.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/basic-search.scss delete mode 100644 packages/esm-patient-queues-app/src/patient-search/basic-search.test.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/empty-data-illustration.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/hooks/usePatients.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/hooks/useQueueLocations.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/search-illustration.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/search-results.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/search-results.scss delete mode 100644 packages/esm-patient-queues-app/src/patient-search/search-results.test.tsx delete mode 100644 packages/esm-patient-queues-app/src/patient-search/search.resource.ts diff --git a/packages/esm-patient-queues-app/src/active-visits/active-visits-patients-reception/active-visits-reception-table.component.tsx b/packages/esm-patient-queues-app/src/active-visits/active-visits-patients-reception/active-visits-reception-table.component.tsx index a02ab06f..e16e5b07 100644 --- a/packages/esm-patient-queues-app/src/active-visits/active-visits-patients-reception/active-visits-reception-table.component.tsx +++ b/packages/esm-patient-queues-app/src/active-visits/active-visits-patients-reception/active-visits-reception-table.component.tsx @@ -30,8 +30,9 @@ import { SearchTypes } from '../../types'; import { usePatientQueuesList } from './active-visits-reception.resource'; import styles from './active-visits-reception.scss'; import { useParentLocation } from '../patient-queues.resource'; -import PatientSearch from '../../patient-search/patient-search.component'; +// import PatientSearch from '../../patient-search/patient-search.component'; import QueueLauncher from '../../queue-launcher/queue-launcher.component'; +import PatientSearch from '../../patient-search/patient-search.component'; function ActiveVisitsReceptionTable() { const { t } = useTranslation(); diff --git a/packages/esm-patient-queues-app/src/patient-search/advanced-search.component.tsx b/packages/esm-patient-queues-app/src/patient-search/advanced-search.component.tsx deleted file mode 100644 index 05812206..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/advanced-search.component.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import React, { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { - Button, - ButtonSet, - Column, - ContentSwitcher, - DatePicker, - DatePickerInput, - Form, - FormGroup, - Layer, - Stack, - Switch, - TextInput, -} from '@carbon/react'; -import { ArrowLeft } from '@carbon/react/icons'; -import { useLayoutType } from '@openmrs/esm-framework'; -import { SearchTypes } from '../types'; -import styles from './advanced-search.scss'; - -interface PatientSearchProps { - toggleSearchType: (searchMode: SearchTypes) => void; -} - -enum fieldMatcherRange { - ANY = 'any', - ALL = 'all', -} - -enum genders { - ANY = 'any', - MALE = 'male', - FEMALE = 'female', -} - -const AdvancedSearch: React.FC = ({ toggleSearchType }) => { - const { t } = useTranslation(); - const isTablet = useLayoutType() === 'tablet'; - const [firstName, setFirstName] = useState(''); - const [middleName, setMiddleName] = useState(''); - const [lastName, setLastName] = useState(''); - const [gender, setGender] = useState(''); - const [dateOfBirth, setDateOfBirth] = useState(''); - const [phoneNumber, setPhoneNumber] = useState(''); - const [postCode, setPostCode] = useState(''); - const [lastVisitDate, setLastVisitDate] = useState(''); - const [fieldMatcherRangeSwitcherValue, setFieldMatcherRangeSwitcherValue] = useState(0); - const [genderSwitcherValue, setGenderSwitcherValue] = useState(0); - const [searchParams, setSearchParams] = useState([]); - - const handleSearch = () => { - setSearchParams([firstName, middleName, lastName, gender, dateOfBirth, phoneNumber, postCode, lastVisitDate]); - }; - - return ( -
-
-
- -
- - -
- {t('match', 'Match')} - setFieldMatcherRangeSwitcherValue(index)} - > - - - - {t('fields', 'of the following fields')}: -
-
- - -

{t('name', 'Name')}

- - setFirstName(event.target.value)} - value={firstName} - /> - - - setMiddleName(event.target.value)} - value={middleName} - /> - - - setLastName(event.target.value)} - value={lastName} - /> - -
- - - -

{t('personalDetails', 'Personal details')}

- - setGenderSwitcherValue(index)} - > - - - - - - - - setDateOfBirth(event.target.value)} - type="date" - /> - - - - setPhoneNumber(event.target.value)} - value={phoneNumber} - /> - - - setPostCode(event.target.value)} - value={postCode} - /> - -
- - - -

{t('lastVisit', 'Last visit')}

- - - setLastVisitDate(event.target.value)} - type="date" - width={'120px'} - /> - - -
-
-
- - - - -
- ); -}; - -export default AdvancedSearch; diff --git a/packages/esm-patient-queues-app/src/patient-search/advanced-search.scss b/packages/esm-patient-queues-app/src/patient-search/advanced-search.scss deleted file mode 100644 index 96ad58ac..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/advanced-search.scss +++ /dev/null @@ -1,154 +0,0 @@ -@use '@carbon/styles/scss/spacing'; -@use '@carbon/styles/scss/type'; -@import '~@openmrs/esm-styleguide/src/vars'; - -.form { - display: flex; - flex-direction: column; - justify-content: space-between; - height: calc(100vh - 6rem); -} - -.grid { - margin: 0 1rem; - padding: 0rem; -} - -.row { - margin: 0; - - :global(.cds--col) { - :global(.cds--form-item) { - &:not(:first-of-type):not(:last-of-type) { - margin: 1rem 0; - } - } - - :global(.cds--fieldset) { - margin: 0; - } - - :global(.cds--date-picker.cds--date-picker--single .cds--date-picker__input) { - width: 10rem; - } - } -} - -.heading { - @include type.type-style('heading-compact-02'); - margin-bottom: 0.5rem; -} - -.spacer { - margin-top: 2rem; - display: inline-block; -} - -.backButton { - align-items: center; - display: flex; - justify-content: flex-start; - margin: spacing.$spacing-03 0; - padding: 0; - @include type.type-style('body-compact-01'); - - button { - display: flex; - - svg { - order: 1; - margin-right: 0.5rem; - margin-left: 0rem !important; - } - - span { - order: 2; - } - } -} - -.advancePatientSearchContainer { - margin: 0 spacing.$spacing-05; - - & .backButton { - margin: 0; - } - - & > button { - padding-left: 0; - } -} - -.label01 { - @include type.type-style('label-01'); - color: $text-02; - margin: spacing.$spacing-03 0; -} - -.formTextInput { - margin-bottom: spacing.$spacing-04; -} - -.contentSwitcherContainer { - display: flex; - align-items: center; - height: spacing.$spacing-09; - margin-bottom: spacing.$spacing-05; - - & > span { - @include type.type-style('heading-compact-01'); - color: $text-02; - } -} - -.formTitle { - font-weight: bold; - @include type.type-style('heading-compact-02'); - margin-bottom: spacing.$spacing-02; -} - -.fieldRangeSwitcher { - width: 8rem; - margin: 0 spacing.$spacing-03 0; -} - -.genderSwitcher { - width: 18rem; - margin: 0.25rem 0 1rem; -} - -.button { - height: 4rem; - display: flex; - align-content: flex-start; - align-items: baseline; - min-width: 50%; -} - -.tablet { - padding: 1.5rem 1rem; - background-color: $ui-02; -} - -.desktop { - padding: 0rem; - margin-top: spacing.$spacing-05; -} - -/* Desktop */ -:global(.omrs-breakpoint-gt-tablet) { - .form { - height: calc(100vh - 6rem); - } -} - -/* Tablet */ -:global(.omrs-breakpoint-lt-desktop) { - .form { - height: calc(100vh - 3rem); - } -} - -.input { - width: 13.5rem; -} diff --git a/packages/esm-patient-queues-app/src/patient-search/advanced-search.test.tsx b/packages/esm-patient-queues-app/src/patient-search/advanced-search.test.tsx deleted file mode 100644 index a26389fa..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/advanced-search.test.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import AdvancedSearch from './advanced-search.component'; - -describe('AdvancedSearch: ', () => { - test('renders the advanced patient search in an overlay', () => { - renderAdvancedSearch(); - - expect(screen.getByRole('button', { name: /back to simple search/i })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: /^search$/i })).toBeInTheDocument(); - expect(screen.findAllByText(/any/i)); - expect(screen.getByRole('tab', { name: /^male$/i })).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: /^female$/i })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: /name/i })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: /personal details/i })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: /last visit/i })).toBeInTheDocument(); - expect(screen.getByRole('textbox', { name: /first name/i })).toBeInTheDocument(); - expect(screen.getByRole('textbox', { name: /middle name/i })).toBeInTheDocument(); - expect(screen.getByRole('textbox', { name: /last name/i })).toBeInTheDocument(); - expect(screen.getByRole('textbox', { name: /phone number/i })).toBeInTheDocument(); - expect(screen.getByRole('textbox', { name: /post code/i })).toBeInTheDocument(); - }); -}); - -function renderAdvancedSearch() { - const toggleSearchType = jest.fn(); - render(); -} diff --git a/packages/esm-patient-queues-app/src/patient-search/basic-search.component.tsx b/packages/esm-patient-queues-app/src/patient-search/basic-search.component.tsx deleted file mode 100644 index 3b3203b0..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/basic-search.component.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import React, { useMemo, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import debounce from 'lodash-es/debounce'; -import { Search, Button, InlineLoading, Layer, Tile } from '@carbon/react'; -import { Search as SearchIcon } from '@carbon/react/icons'; -import EmptyDataIllustration from './empty-data-illustration.component'; -import SearchIllustration from './search-illustration.component'; -import SearchResults from './search-results.component'; -import usePatients from './hooks/usePatients'; -import { SearchTypes } from '../types'; -import styles from './basic-search.scss'; - -interface BasicSearchProps { - toggleSearchType: (searchMode: SearchTypes) => void; -} - -const searchTimeoutInMs = 300; - -const BasicSearch: React.FC = ({ toggleSearchType }) => { - const { t } = useTranslation(); - const [searchTerm, setSearchTerm] = useState(''); - const [query, setQuery] = useState(null); - const { patients, isLoading } = usePatients(query); - - const handleSearch = useMemo(() => debounce((searchTerm) => setSearchTerm(searchTerm), searchTimeoutInMs), []); - - const performSearch = () => setQuery(searchTerm); - - return ( -
-
- - handleSearch(event.target.value)} - onClear={() => setQuery(null)} - /> - - -
- { - <> - {query === null && ( -
-
- - - -
-

{t('primaryHelperText', 'Search for a patient')}

-

- {t('secondaryHelperText', "Type the patient's name or unique ID number")} -

-
-
-
-
-

{t('or', 'or')}

-
- -
-
- )} - {isLoading && ( -
- -
- )} - - {patients.length > 0 && } - - {patients.length === 0 && query !== null && !isLoading && ( -
-
-

{t('noResultsFound', 'No results found')}

- - - -

- {t('noPatientFoundMessage', 'Sorry, no patient has been found')} -

-

- - {t('trySearchWithPatientUniqueID', "Try searching with the patient's unique ID number")} - -
- {t('orPatientName', "OR the patient's name(s)")} -

-
-
-
-
- )} - - } -
- ); -}; - -export default BasicSearch; diff --git a/packages/esm-patient-queues-app/src/patient-search/basic-search.scss b/packages/esm-patient-queues-app/src/patient-search/basic-search.scss deleted file mode 100644 index 2aa722e2..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/basic-search.scss +++ /dev/null @@ -1,139 +0,0 @@ -@use '@carbon/styles/scss/spacing'; -@use '@carbon/styles/scss/type'; -@import '~@openmrs/esm-styleguide/src/vars'; - -.searchboxContainer { - display: flex; - align-items: center; - margin-bottom: spacing.$spacing-05; -} - -.searchboxLayer { - flex-grow: 1; -} - -.tileContainer { - :global(.omrs-breakpoint-gt-tablet) & { - margin: 0 1.5rem 0; - } - - :global(.omrs-breakpoint-lt-desktop) & { - width: 60%; - margin: auto; - } -} - -.tile { - display: flex; - flex-flow: column wrap; - align-items: center; - justify-content: center; - padding: 2rem 0 1.5rem; - text-align: center; - border: 1px solid $ui-03; -} - -.helperText { - margin-top: 1.25rem; - color: $text-02; - - .primaryText { - @include type.type-style('heading-compact-01'); - } - - .secondaryText { - width: 12rem; - margin-top: 0.25rem; - @include type.type-style('body-01'); - } -} - -.separator { - @include type.type-style('heading-03'); - color: $text-02; - width: 12rem; - margin: 3rem auto; - overflow: hidden; - text-align: center; - - &::before, - &::after { - background-color: $text-03; - content: ''; - display: inline-block; - height: 1px; - position: relative; - vertical-align: middle; - width: 50%; - } - - &::before { - right: 1rem; - margin-left: -50%; - } - - &::after { - left: 1rem; - margin-right: -50%; - } -} - -.buttonContainer { - display: flex; - align-items: center; - justify-content: center; -} - -.resultsContainer { - height: 100vh; -} - -.lightBackground { - @extend .resultsContainer; - background-color: white; -} - -.loadingContainer { - height: 80vh; - display: flex; - justify-content: center; - align-items: center; - - & > div { - width: fit-content !important; - } -} - -.helperText { - color: var(--omrs-color-ink-medium-contrast); - margin-left: 2.375rem; -} - -.resultsText { - @include type.type-style('label-01'); - color: $text-02; - border-bottom: 0.063rem solid $ui-03; - padding: spacing.$spacing-03 0rem; -} - -.emptyResultText { - @include type.type-style('heading-compact-01'); - color: $text-02; - margin-top: spacing.$spacing-05; - margin-bottom: 0.313rem; -} - -.actionText { - @include type.type-style('body-01'); - color: $text-02; -} - -.emptySearchResultsTile { - text-align: center; - margin-top: spacing.$spacing-05; - padding: spacing.$spacing-09 0rem; -} - -:global(.omrs-breakpoint-gt-tablet) .emptySearchResultsTile { - background-color: $ui-02; -} diff --git a/packages/esm-patient-queues-app/src/patient-search/basic-search.test.tsx b/packages/esm-patient-queues-app/src/patient-search/basic-search.test.tsx deleted file mode 100644 index 180b9423..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/basic-search.test.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import BasicSearch from './basic-search.component'; - -describe('BasicSearch: ', () => { - test('renders the basic patient search in an overlay', () => { - renderBasicSearch(); - - const searchbox = screen.getByRole('searchbox', { name: /search for a patient/i }); - const searchButton = screen.getByRole('button', { name: /^search$/i }); - expect(searchbox).toBeInTheDocument(); - expect(searchButton).toBeInTheDocument(); - expect(screen.getByPlaceholderText(/search for a patient name or id number/i)).toBeInTheDocument(); - expect(screen.getByRole('button', { name: /advanced search/i })).toBeDisabled(); - expect(screen.getByText('or')).toBeInTheDocument(); - expect(screen.getByText(/type the patient's name or unique id number/i)).toBeInTheDocument(); - }); -}); - -function renderBasicSearch() { - const toggleSearchType = jest.fn(); - render(); -} diff --git a/packages/esm-patient-queues-app/src/patient-search/empty-data-illustration.component.tsx b/packages/esm-patient-queues-app/src/patient-search/empty-data-illustration.component.tsx deleted file mode 100644 index 42e93e03..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/empty-data-illustration.component.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as React from 'react'; - -const EmptyDataIllustration = ({ width = '61', height = '59' }) => { - return ( - - Empty data illustration - - - - - - - - - - - - - - ); -}; - -export default EmptyDataIllustration; diff --git a/packages/esm-patient-queues-app/src/patient-search/hooks/usePatients.tsx b/packages/esm-patient-queues-app/src/patient-search/hooks/usePatients.tsx deleted file mode 100644 index 990e95f8..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/hooks/usePatients.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useMemo } from 'react'; -import useSWR from 'swr'; -import { fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework'; - -interface FHIRResponse { - entry: Array<{ resource: fhir.Patient }>; - total: number; - type: string; - resourceType: string; -} - -const usePatients = (searchTerm: string) => { - const apiUrl = `${fhirBaseUrl}/Patient?name=${searchTerm}&_summary=data`; - - const { data, error, isLoading } = useSWR<{ data: FHIRResponse }>(searchTerm !== null ? apiUrl : null, openmrsFetch); - - const searchedPatients = useMemo( - () => data?.data?.entry?.map((response) => response.resource) ?? [], - [data?.data?.entry], - ); - - return { patients: searchedPatients, isLoading: isLoading && searchTerm !== null, error }; -}; - -export default usePatients; diff --git a/packages/esm-patient-queues-app/src/patient-search/hooks/useQueueLocations.tsx b/packages/esm-patient-queues-app/src/patient-search/hooks/useQueueLocations.tsx deleted file mode 100644 index 6da8e801..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/hooks/useQueueLocations.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useMemo } from 'react'; -import useSWR from 'swr'; -import { fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework'; - -interface FHIRResponse { - entry: Array<{ resource: fhir.Location }>; - total: number; - type: string; - resourceType: string; -} -export function useQueueLocations() { - const apiUrl = `${fhirBaseUrl}/Location?_summary=data&_tag=queue location`; - const { data, error, isLoading } = useSWR<{ data: FHIRResponse }>(apiUrl, openmrsFetch); - - const queueLocations = useMemo( - () => data?.data?.entry?.map((response) => response.resource) ?? [], - [data?.data?.entry], - ); - return { queueLocations: queueLocations ? queueLocations : [], isLoading, error }; -} diff --git a/packages/esm-patient-queues-app/src/patient-search/search-illustration.component.tsx b/packages/esm-patient-queues-app/src/patient-search/search-illustration.component.tsx deleted file mode 100644 index a838cae7..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/search-illustration.component.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -export default function SearchIllustration({ width = '62', height = '48' }) { - return ( - - - - - - - - - - - - - - - ); -} diff --git a/packages/esm-patient-queues-app/src/patient-search/search-results.component.tsx b/packages/esm-patient-queues-app/src/patient-search/search-results.component.tsx deleted file mode 100644 index 96ef7af8..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/search-results.component.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useMemo, useState } from 'react'; -import { Dropdown } from '@carbon/react'; -import { useTranslation } from 'react-i18next'; -import { SearchTypes } from '../types'; -import PatientInfo from '../patient-info/patient-info.component'; -import styles from './search-results.scss'; - -interface SearchResultsProps { - patients: Array; - hidePanel?: any; - toggleSearchType: (searchMode: SearchTypes, patientUuid: string) => void; -} - -type SortingCriteria = 'firstNameFirst' | 'lastNameFirst' | 'oldest' | 'youngest'; - -const SearchResults: React.FC = ({ patients, toggleSearchType }) => { - const { t } = useTranslation(); - const [selectedSortingCriteria, setSelectedSortingCriteria] = useState('firstNameFirst'); - - const sortedPatient = useMemo(() => { - return patients.sort((patientA, patientB) => { - if (selectedSortingCriteria === 'oldest') { - return new Date(patientA.birthDate).getTime() - new Date(patientB.birthDate).getTime(); - } - if (selectedSortingCriteria === 'youngest') { - return new Date(patientB.birthDate).getTime() - new Date(patientA.birthDate).getTime(); - } - if (selectedSortingCriteria === 'firstNameFirst') { - return patientA.name?.[0].given?.join('') < patientB.name?.[0].given?.join('') ? -1 : 0; - } - if (selectedSortingCriteria === 'lastNameFirst') { - return patientA?.name?.[0].family < patientB?.name?.[0].family ? -1 : 0; - } - }); - }, [patients, selectedSortingCriteria]); - - const sortingCriteria = [ - { id: 'firstNameFirst', label: t('firstNameSort', 'First name (a-z)') }, - { id: 'lastNameFirst', label: t('lastNameSort', 'Last name (a-z)') }, - { id: 'oldest', label: t('oldest', 'Oldest first') }, - { id: 'youngest', label: t('youngest', 'Youngest first') }, - ]; - - return ( - <> -
- setSelectedSortingCriteria(selectedItem.id as SortingCriteria)} - /> -
- {sortedPatient.map((patient, index) => ( -
-
- { - toggleSearchType(SearchTypes.SCHEDULED_VISITS, patient.id); - }} - /> -
-
- ))} - - ); -}; - -export default SearchResults; diff --git a/packages/esm-patient-queues-app/src/patient-search/search-results.scss b/packages/esm-patient-queues-app/src/patient-search/search-results.scss deleted file mode 100644 index 50172e9d..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/search-results.scss +++ /dev/null @@ -1,80 +0,0 @@ -@use '@carbon/styles/scss/spacing'; -@use '@carbon/styles/scss/type'; -@import '~@openmrs/esm-styleguide/src/vars'; - -.patientChart { - text-decoration: none; -} - -:global(.omrs-breakpoint-gt-tablet) .patientChart { - background-color: $ui-02; -} - -.container { - & .patientBanner { - background-color: red !important; - } -} - -.patientBanner { - display: flex; -} - -.patientName { - @include type.type-style('heading-03'); -} - -.patientAvatar { - width: spacing.$spacing-11; - height: spacing.$spacing-11; - margin: spacing.$spacing-05 spacing.$spacing-05 0; - border-radius: 1px; -} - -.patientInfo { - width: 100%; - display: flex; - flex-flow: column wrap; - margin: spacing.$spacing-05 0; - cursor: pointer; -} - -.demographics { - @include type.type-style('body-compact-02'); - color: $text-02; - margin: 0.3rem 0; -} - -.identifiers { - @include type.type-style('body-compact-02'); - color: $ui-04; -} - -.actionsContainer { - padding-top: spacing.$spacing-03; - margin-top: spacing.$spacing-05; -} - -.sortingCriteriaSelect { - display: flex; - width: 100%; - justify-content: flex-end; - @include type.type-style('body-compact-02'); - width: 100%; - - :global(.cds--dropdown__wrapper--inline) { - gap: 0; - } - - :global(.cds--list-box__menu-icon) { - height: spacing.$spacing-05; - } - - :global(.cds--list-box__menu) { - left: -7.5rem; - } - - :global(.cds--label) { - margin-right: spacing.$spacing-02; - } -} diff --git a/packages/esm-patient-queues-app/src/patient-search/search-results.test.tsx b/packages/esm-patient-queues-app/src/patient-search/search-results.test.tsx deleted file mode 100644 index ef8f04b6..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/search-results.test.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; -import { screen, render } from '@testing-library/react'; -import { age } from '@openmrs/esm-framework'; -import SearchResults from './search-results.component'; - -const mockAge = age as jest.Mock; - -jest.mock('@openmrs/esm-framework', () => { - const originalModule = jest.requireActual('@openmrs/esm-framework'); - return { - ...originalModule, - age: jest.fn(), - }; -}); - -const patients = [ - { - id: 'b73bee73-7bf0-4872-9657-ba9de0d93478', - name: [{ given: ['John'], family: 'Smith' }], - person: { - gender: 'Male', - age: 2, - birthdate: '2020-02-01T00:00:00.000+0000', - birthdateEstimated: true, - personName: { - display: 'John Smith', - uuid: '27698bff-4056-430c-824c-cb18cf9329d8', - givenName: 'John', - middleName: null, - familyName: 'Smith', - familyName2: null, - voided: false, - }, - addresses: [ - { - display: 'Bom Jesus Street', - uuid: '7eab94da-4b33-4da9-b352-da21a571221a', - preferred: true, - address1: 'Bom Jesus Street', - address2: null, - cityVillage: 'Recife', - stateProvince: 'Pernambuco', - country: 'Brazil', - postalCode: '50030-310', - countyDistrict: null, - }, - ], - display: 'John Smith', - dead: false, - deathDate: null, - }, - gender: 'Male', - birthDate: '2020-02-01T00:00:00.000+0000', - deceasedDateTime: null, - identifier: [{ value: '10001F0' }], - address: [{ city: 'Recife', country: 'Brazil', postalCode: '50030-310', state: 'Pernambuco', use: 'home' }], - telecom: [], - patientIdentifier: { identifier: [{ value: '10001F0' }] }, - }, -]; - -const mockToggleSearchType = jest.fn(); - -describe('Search Results', () => { - it('should search results page', () => { - mockAge.mockReturnValue(35); - renderSearchResults(); - expect(screen.getByText(/John Smith/)).toBeInTheDocument(); - expect(screen.getByText(/35/)).toBeInTheDocument(); - expect(screen.getByText(/Male/)).toBeInTheDocument(); - expect(screen.getByText(/01 — Feb — 2020/i)).toBeInTheDocument(); - }); -}); - -const renderSearchResults = () => { - render(); -}; diff --git a/packages/esm-patient-queues-app/src/patient-search/search.resource.ts b/packages/esm-patient-queues-app/src/patient-search/search.resource.ts deleted file mode 100644 index f0af94b7..00000000 --- a/packages/esm-patient-queues-app/src/patient-search/search.resource.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; - -export function findPatients(query: string, objectVersion: string, controller: AbortController, includeDead: boolean) { - const url = `${restBaseUrl}/patient?q=${query}&v=${objectVersion}&includeDead=${includeDead}`; - - return openmrsFetch(url, { - method: 'GET', - signal: controller.signal, - }); -} From 37a36e243d314195b90fd66a3a0f2bf7a57ee7c4 Mon Sep 17 00:00:00 2001 From: jabahum Date: Fri, 1 Nov 2024 15:54:15 +0300 Subject: [PATCH 2/5] initial commit --- .../visit-form/queue.resource.ts | 11 +++ .../visit-form/visit-form.component.tsx | 16 +++-- .../start-visit-dialog.component.tsx | 67 ------------------- .../visit-prompt/start-visit-dialog.scss | 11 --- .../patient-search.component.tsx | 22 +----- 5 files changed, 23 insertions(+), 104 deletions(-) delete mode 100644 packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.component.tsx delete mode 100644 packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.scss diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts b/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts index 8acc0677..d99b6f92 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts @@ -55,3 +55,14 @@ export async function getCurrentPatientQueueByPatientUuid(patientUuid: string, c }, }); } + +export function getCurrentVisit(patient: string, date: string) { + const apiUrl = `${restBaseUrl}/visit?patient=${patient}&includeInactive=false&fromStartDate=${date}&v=default&limit=1`; + const abortController = new AbortController(); + return openmrsFetch(apiUrl, { + signal: abortController.signal, + headers: { + 'Content-Type': 'application/json', + }, + }); +} diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx index 9a710660..deb27a3e 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx @@ -30,21 +30,20 @@ import dayjs from 'dayjs'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import styles from './visit-form.scss'; -import { useProviders } from './queue.resource'; -import { NewVisitPayload, SearchTypes } from '../../types'; +import { getCurrentVisit, useProviders } from './queue.resource'; +import { NewVisitPayload } from '../../types'; import { amPm, convertTime12to24 } from '../../helpers/time-helpers'; import { useQueueRoomLocations } from '../../hooks/useQueueRooms'; import { addQueueEntry } from '../active-visits-table.resource'; import { first } from 'rxjs/operators'; interface VisitFormProps { - toggleSearchType: (searchMode: SearchTypes, patientUuid) => void; patientUuid: string; closePanel: () => void; mode: boolean; } -const StartVisitForm: React.FC = ({ patientUuid, toggleSearchType, closePanel, mode }) => { +const StartVisitForm: React.FC = ({ patientUuid, closePanel, mode }) => { const { t } = useTranslation(); const isTablet = useLayoutType() === 'tablet'; const sessionUser = useSession(); @@ -55,7 +54,6 @@ const StartVisitForm: React.FC = ({ patientUuid, toggleSearchTyp const [timeFormat, setTimeFormat] = useState(new Date().getHours() >= 12 ? 'PM' : 'AM'); const [visitDate, setVisitDate] = useState(new Date()); const [visitTime, setVisitTime] = useState(dayjs(new Date()).format('hh:mm')); - const state = useMemo(() => ({ patientUuid }), [patientUuid]); const allVisitTypes = useVisitTypes(); const [ignoreChanges, setIgnoreChanges] = useState(true); const [selectedLocation, setSelectedLocation] = useState(''); @@ -66,7 +64,7 @@ const StartVisitForm: React.FC = ({ patientUuid, toggleSearchTyp const { queueRoomLocations, mutate } = useQueueRoomLocations(sessionUser?.sessionLocation?.uuid); const [selectedNextQueueLocation, setSelectedNextQueueLocation] = useState(''); const [selectedProvider, setSelectedProvider] = useState(''); - const { patient, isLoading } = usePatient(patientUuid); + const { isLoading } = usePatient(patientUuid); const [upcomingAppointment, setUpcomingAppointment] = useState(null); const upcomingAppointmentState = useMemo(() => ({ patientUuid, setUpcomingAppointment }), [patientUuid]); @@ -108,6 +106,12 @@ const StartVisitForm: React.FC = ({ patientUuid, toggleSearchTyp : [], ); + // check for a current visit before starting a visit + getCurrentVisit('', '').then( + (resp) => {}, + (error) => {}, + ); + // Check if selectedNextQueueLocation has a value selected const isFormValid = selectedNextQueueLocation; diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.component.tsx b/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.component.tsx deleted file mode 100644 index cde2485e..00000000 --- a/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.component.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useState } from 'react'; -import { Button, Layer, ModalBody, ModalFooter, ModalHeader, Select, SelectItem } from '@carbon/react'; -import { useLayoutType, useSession } from '@openmrs/esm-framework'; -import { useTranslation } from 'react-i18next'; - -import styles from './start-visit-dialog.scss'; -import { MappedPatientQueueEntry } from '../patient-queues.resource'; -import { useQueueRoomLocations } from '../../hooks/useQueueRooms'; - -interface StartVisitDialogProps { - queueEntry: MappedPatientQueueEntry; - closeModal: () => void; - launchPatientChart?: boolean; -} - -const StartVisitDialog: React.FC = ({ queueEntry, closeModal }) => { - const isTablet = useLayoutType() === 'tablet'; - const sessionUser = useSession(); - const { queueRoomLocations } = useQueueRoomLocations(sessionUser?.sessionLocation?.uuid); - - const [selectedNextQueueLocation, setSelectedNextQueueLocation] = useState(queueRoomLocations[0]?.uuid); - const { t } = useTranslation(); - - return ( -
- Patient : {queueEntry?.name} - -
- -
-
{t('nextServicePoint', 'Next Service Point')}
- - - -
-
- - - - -
- ); -}; -function ResponsiveWrapper({ children, isTablet }) { - return isTablet ? {children} :
{children}
; -} -export default StartVisitDialog; diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.scss b/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.scss deleted file mode 100644 index 6b4fb579..00000000 --- a/packages/esm-patient-queues-app/src/active-visits/visit-prompt/start-visit-dialog.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use '@carbon/styles/scss/type'; -@import '~@openmrs/esm-styleguide/src/vars'; - - -.header { - @include type.type-style("heading-03"); -} - -.body { - @include type.type-style("body-01"); -} diff --git a/packages/esm-patient-queues-app/src/patient-search/patient-search.component.tsx b/packages/esm-patient-queues-app/src/patient-search/patient-search.component.tsx index b7bdc821..56bd0bea 100644 --- a/packages/esm-patient-queues-app/src/patient-search/patient-search.component.tsx +++ b/packages/esm-patient-queues-app/src/patient-search/patient-search.component.tsx @@ -18,19 +18,8 @@ const PatientSearch: React.FC = ({ closePanel, view, viewSta const { t } = useTranslation(); const { selectedPatientUuid } = viewState; const { patient } = usePatient(selectedPatientUuid); - const [searchType, setSearchType] = useState( - view === 'queue_service_form' - ? SearchTypes.QUEUE_SERVICE_FORM - : view === 'queue_room_form' - ? SearchTypes.QUEUE_ROOM_FORM - : SearchTypes.VISIT_FORM, - ); - const [newVisitMode, setNewVisitMode] = useState(false); - const toggleSearchType = (searchType: SearchTypes, mode: boolean = false) => { - setSearchType(searchType); - setNewVisitMode(mode); - }; + const [newVisitMode, setNewVisitMode] = useState(false); return ( <> @@ -46,14 +35,7 @@ const PatientSearch: React.FC = ({ closePanel, view, viewSta /> )}
- {searchType === SearchTypes.VISIT_FORM ? ( - - ) : null} +
From 981a7661ec529ede87dc30a2bc0b9c19c6c5fb4d Mon Sep 17 00:00:00 2001 From: jabahum Date: Sun, 3 Nov 2024 13:27:50 +0300 Subject: [PATCH 3/5] check current visit before submission --- .../visit-form/queue.resource.ts | 4 ++-- .../visit-form/visit-form.component.tsx | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts b/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts index d99b6f92..73678070 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/queue.resource.ts @@ -56,10 +56,10 @@ export async function getCurrentPatientQueueByPatientUuid(patientUuid: string, c }); } -export function getCurrentVisit(patient: string, date: string) { +export async function getCurrentVisit(patient: string, date: string) { const apiUrl = `${restBaseUrl}/visit?patient=${patient}&includeInactive=false&fromStartDate=${date}&v=default&limit=1`; const abortController = new AbortController(); - return openmrsFetch(apiUrl, { + return await openmrsFetch(apiUrl, { signal: abortController.signal, headers: { 'Content-Type': 'application/json', diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx index deb27a3e..779ab900 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx @@ -65,6 +65,7 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod const [selectedNextQueueLocation, setSelectedNextQueueLocation] = useState(''); const [selectedProvider, setSelectedProvider] = useState(''); const { isLoading } = usePatient(patientUuid); + const [visitExist, setVisitExist] = useState(false); const [upcomingAppointment, setUpcomingAppointment] = useState(null); const upcomingAppointmentState = useMemo(() => ({ patientUuid, setUpcomingAppointment }), [patientUuid]); @@ -107,16 +108,17 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod ); // check for a current visit before starting a visit - getCurrentVisit('', '').then( - (resp) => {}, - (error) => {}, - ); + async function checkCurrentVisit(patientUuid) { + const date = dayjs().format('YYYY-MM-DD'); + const resp = await getCurrentVisit(patientUuid, date); + setVisitExist(resp.data === null); + } // Check if selectedNextQueueLocation has a value selected const isFormValid = selectedNextQueueLocation; const handleSubmit = useCallback( - (event) => { + async (event) => { event.preventDefault(); // retrieve values from queue extension @@ -124,6 +126,17 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod const status = 'pending'; const comment = event?.target['nextNotes']?.value; + // Check for an existing visit before proceeding + await checkCurrentVisit(patientUuid); + if (visitExist) { + showNotification({ + title: t('visitExists', 'Visit already exists'), + kind: 'info', + description: t('activeVisitExists', 'An active visit already exists for this patient.'), + }); + return; + } + if (!visitType) { setIsMissingVisitType(true); return; From 470952ada53d998a568fd15734fad4eed620f551 Mon Sep 17 00:00:00 2001 From: jabahum Date: Sun, 3 Nov 2024 17:58:53 +0300 Subject: [PATCH 4/5] fix build error --- .../src/active-visits/visit-form/visit-form.component.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx index 779ab900..7a720542 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx @@ -225,6 +225,7 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod visitDate, visitTime, visitType, + visitExist, ], ); From bbdc0a494c6ccf9a1e3692606964e5c43de2c112 Mon Sep 17 00:00:00 2001 From: jabahum Date: Sun, 3 Nov 2024 18:43:56 +0300 Subject: [PATCH 5/5] update check currentvist --- .../active-visits/visit-form/visit-form.component.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx index 7a720542..b4c145dc 100644 --- a/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx +++ b/packages/esm-patient-queues-app/src/active-visits/visit-form/visit-form.component.tsx @@ -65,7 +65,6 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod const [selectedNextQueueLocation, setSelectedNextQueueLocation] = useState(''); const [selectedProvider, setSelectedProvider] = useState(''); const { isLoading } = usePatient(patientUuid); - const [visitExist, setVisitExist] = useState(false); const [upcomingAppointment, setUpcomingAppointment] = useState(null); const upcomingAppointmentState = useMemo(() => ({ patientUuid, setUpcomingAppointment }), [patientUuid]); @@ -111,7 +110,7 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod async function checkCurrentVisit(patientUuid) { const date = dayjs().format('YYYY-MM-DD'); const resp = await getCurrentVisit(patientUuid, date); - setVisitExist(resp.data === null); + return resp.data?.results !== null && resp.data?.results.length > 0; } // Check if selectedNextQueueLocation has a value selected @@ -127,8 +126,9 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod const comment = event?.target['nextNotes']?.value; // Check for an existing visit before proceeding - await checkCurrentVisit(patientUuid); - if (visitExist) { + const existingVisit = await checkCurrentVisit(patientUuid); + + if (existingVisit) { showNotification({ title: t('visitExists', 'Visit already exists'), kind: 'info', @@ -225,7 +225,6 @@ const StartVisitForm: React.FC = ({ patientUuid, closePanel, mod visitDate, visitTime, visitType, - visitExist, ], );