Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

feat: Added new proposed links to the sidebar #1956

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
120 changes: 120 additions & 0 deletions src/__tests__/components/Sidebar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,66 @@ describe('Sidebar', () => {
})
})

describe('patients_list link', () => {
it('should render the patients_list link', () => {
const wrapper = setup('/patients')

const listItems = wrapper.find(ListItem)

expect(listItems.at(4).text().trim()).toEqual('patients.patientsList')
})

it('should be active when the current path is /patients', () => {
const wrapper = setup('/patients')

const listItems = wrapper.find(ListItem)

expect(listItems.at(4).prop('active')).toBeTruthy()
})

it('should navigate to /patients when the patients link is clicked', () => {
const wrapper = setup('/patients')

const listItems = wrapper.find(ListItem)

act(() => {
;(listItems.at(4).prop('onClick') as any)()
})

expect(history.location.pathname).toEqual('/patients')
})
})

describe('new_patient link', () => {
it('should render the new_patient link', () => {
const wrapper = setup('/patients')

const listItems = wrapper.find(ListItem)

expect(listItems.at(3).text().trim()).toEqual('patients.newPatient')
})

it('should be active when the current path is /patients/new', () => {
const wrapper = setup('/patients/new')

const listItems = wrapper.find(ListItem)

expect(listItems.at(3).prop('active')).toBeTruthy()
})

it('should navigate to /patients/new when the patients link is clicked', () => {
const wrapper = setup('/patients')

const listItems = wrapper.find(ListItem)

act(() => {
;(listItems.at(3).prop('onClick') as any)()
})

expect(history.location.pathname).toEqual('/patients/new')
})
})

describe('appointments link', () => {
it('should render the scheduling link', () => {
const wrapper = setup('/appointments')
Expand Down Expand Up @@ -118,4 +178,64 @@ describe('Sidebar', () => {
expect(history.location.pathname).toEqual('/appointments')
})
})

describe('appointment_schedule link', () => {
it('should render the appointment_schedule link', () => {
const wrapper = setup('/appointments')

const listItems = wrapper.find(ListItem)

expect(listItems.at(5).text().trim()).toEqual('scheduling.appointments.schedule')
})

it('should be active when the current path is /appointments', () => {
const wrapper = setup('/appointments')

const listItems = wrapper.find(ListItem)

expect(listItems.at(5).prop('active')).toBeTruthy()
})

it('should navigate to /appointments when the appointments_schedule link is clicked', () => {
const wrapper = setup('/appointments')

const listItems = wrapper.find(ListItem)

act(() => {
;(listItems.at(5).prop('onClick') as any)()
})

expect(history.location.pathname).toEqual('/appointments')
})
})

describe('new_appointment link', () => {
it('should render the new_appointment link', () => {
const wrapper = setup('/appointments/new')

const listItems = wrapper.find(ListItem)

expect(listItems.at(4).text().trim()).toEqual('scheduling.appointments.new')
})

it('should be active when the current path is /appointments/new', () => {
const wrapper = setup('/appointments/new')

const listItems = wrapper.find(ListItem)

expect(listItems.at(4).prop('active')).toBeTruthy()
})

it('should navigate to /appointments/new when the new_appointment link is clicked', () => {
const wrapper = setup('/appointments')

const listItems = wrapper.find(ListItem)

act(() => {
;(listItems.at(4).prop('onClick') as any)()
})

expect(history.location.pathname).toEqual('/appointments/new')
})
})
})
4 changes: 2 additions & 2 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const Navbar = () => {
{
type: 'link-list',
label: t('patients.label'),
className: 'patients-link-list',
className: 'patients-link-list d-md-none d-block',
children: [
{
type: 'link',
Expand All @@ -52,7 +52,7 @@ const Navbar = () => {
{
type: 'link-list',
label: t('scheduling.label'),
className: 'scheduling-link-list',
className: 'scheduling-link-list d-md-none d-block',
children: [
{
type: 'link',
Expand Down
134 changes: 128 additions & 6 deletions src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { CSSProperties } from 'react'
import React, { useState, CSSProperties } from 'react'
import { List, ListItem, Icon } from '@hospitalrun/components'
import { useTranslation } from 'react-i18next'
import { useLocation, useHistory } from 'react-router'
Expand All @@ -14,6 +14,7 @@ const Sidebar = () => {
const path = useLocation()
const history = useHistory()
const { pathname } = path
const splittedPath = pathname.split('/')

const navigateTo = (location: string) => {
history.push(location)
Expand All @@ -23,6 +24,53 @@ const Sidebar = () => {
cursor: 'pointer',
}

const expandibleArrow: CSSProperties = {
marginRight: '20px',
}

const iconMargin: CSSProperties = {
marginRight: '10px',
}

const [expandedItem, setExpandedItem] = useState(
splittedPath[1].includes('patients')
? 'patient'
: splittedPath[1].includes('appointments')
? 'appointment'
: 'none',
)

const setExpansion = (item: string) => {
if (expandedItem === item) {
setExpandedItem('none')
return
}

setExpandedItem(item.toString())
}

const listSubItemStyleNew: CSSProperties = {
cursor: 'pointer',
fontSize: 'small',
borderBottomWidth: 0,
color:
(splittedPath[1].includes('patients') || splittedPath[1].includes('appointments')) &&
splittedPath.length > 2
? 'white'
: 'black',
}

const listSubItemStyle: CSSProperties = {
cursor: 'pointer',
fontSize: 'small',
borderBottomWidth: 0,
color:
(splittedPath[1].includes('patients') || splittedPath[1].includes('appointments')) &&
splittedPath.length < 3
? 'white'
: 'black',
}

return (
<nav
className="col-md-2 d-none d-md-block bg-light sidebar"
Expand All @@ -42,28 +90,102 @@ const Sidebar = () => {
</ListItem>
<ListItem
active={pathname === '/'}
onClick={() => navigateTo('/')}
onClick={() => {
navigateTo('/')
setExpansion('none')
}}
className="nav-item"
style={listItemStyle}
>
<Icon icon="dashboard" /> {!sidebarCollapsed && t('dashboard.label')}
</ListItem>
<ListItem
active={pathname.split('/')[1].includes('patient')}
onClick={() => navigateTo('/patients')}
active={splittedPath[1].includes('patient')}
onClick={() => {
navigateTo('/patients')
if (expandedItem === 'patient') {
setExpandedItem('none')
return
}

setExpandedItem('patient')
}}
className="nav-item"
style={listItemStyle}
>
<Icon
icon={
splittedPath[1].includes('patient') && expandedItem === 'patient'
? 'down-arrow'
: 'right-arrow'
}
style={expandibleArrow}
/>
<Icon icon="patients" /> {!sidebarCollapsed && t('patients.label')}
</ListItem>
{splittedPath[1].includes('patient') && expandedItem === 'patient' && (
<List layout="flush">
<ListItem
className="nav-item"
style={listSubItemStyleNew}
onClick={() => navigateTo('/patients/new')}
active={splittedPath[1].includes('patients') && splittedPath.length > 2}
>
<Icon icon="patient-add" style={iconMargin} />
{!sidebarCollapsed && t('patients.newPatient')}
</ListItem>
<ListItem
className="nav-item"
style={listSubItemStyle}
onClick={() => navigateTo('/patients')}
active={splittedPath[1].includes('patients') && splittedPath.length < 3}
>
<Icon icon="incident" style={iconMargin} />
{!sidebarCollapsed && t('patients.patientsList')}
</ListItem>
</List>
)}
<ListItem
active={pathname.split('/')[1].includes('appointments')}
onClick={() => navigateTo('/appointments')}
active={splittedPath[1].includes('appointments')}
onClick={() => {
navigateTo('/appointments')
setExpansion('appointment')
}}
className="nav-item"
style={listItemStyle}
>
<Icon
icon={
splittedPath[1].includes('appointments') && expandedItem === 'appointment'
? 'down-arrow'
: 'right-arrow'
}
style={expandibleArrow}
/>
<Icon icon="appointment" /> {!sidebarCollapsed && t('scheduling.label')}
</ListItem>
{splittedPath[1].includes('appointment') && expandedItem === 'appointment' && (
<List layout="flush" className="nav flex-column">
<ListItem
className="nav-item"
style={listSubItemStyleNew}
onClick={() => navigateTo('/appointments/new')}
active={splittedPath[1].includes('appointments') && splittedPath.length > 2}
>
<Icon icon="appointment-add" style={iconMargin} />
{!sidebarCollapsed && t('scheduling.appointments.new')}
</ListItem>
<ListItem
className="nav-item"
style={listSubItemStyle}
onClick={() => navigateTo('/appointments')}
active={splittedPath[1].includes('appointments') && splittedPath.length < 3}
>
<Icon icon="incident" style={iconMargin} />
{!sidebarCollapsed && t('scheduling.appointments.schedule')}
</ListItem>
</List>
)}
</List>
</div>
</nav>
Expand Down
4 changes: 2 additions & 2 deletions src/locales/enUs/translations/patients/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export default {
patients: {
label: 'Patients',
patientsList: 'Patients List',
viewPatients: 'View Patients',
editPatient: 'Edit Patient',
viewPatient: 'View Patient',
newPatient: 'New Patient',
successfullyCreated: 'Successfully created patient',
successfullyAddedRelatedPerson: 'Successfully added a new related person',
successfullyAddedRelatedPerson: 'Successfully added the new related person',
},
}
7 changes: 1 addition & 6 deletions src/locales/enUs/translations/scheduling/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ export default {
appointments: {
label: 'Appointments',
new: 'New Appointment',
deleteAppointment: 'Delete Appointment',
viewAppointment: 'Appointment',
editAppointment: 'Edit Appointment',
schedule: 'Appointment Schedule',
},
appointment: {
startDate: 'Start Date',
Expand All @@ -20,16 +18,13 @@ export default {
routine: 'Routine',
walkIn: 'Walk In',
},
successfullyCreated: 'Appointment successfully created.',
errors: {
patientRequired: 'Patient is required.',
errorCreatingAppointment: 'Error Creating Appointment!',
startDateMustBeBeforeEndDate: 'Start Time must be before End Time.',
},
reason: 'Reason',
patient: 'Patient',
successfullyDeleted: 'Appointment successfully deleted.',
deleteConfirmationMessage: 'Are you sure you want to delete this appointment?',
},
},
}