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

Commit

Permalink
feat(settings): add navbar dropdown and settings page (#2096)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kumiko committed May 28, 2020
1 parent 1333de9 commit e5677fe
Show file tree
Hide file tree
Showing 30 changed files with 223 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -5,7 +5,7 @@
"private": false,
"license": "MIT",
"dependencies": {
"@hospitalrun/components": "^1.5.0",
"@hospitalrun/components": "~1.6.0",
"@reduxjs/toolkit": "~1.3.0",
"@types/escape-string-regexp": "~2.0.1",
"@types/pouchdb-find": "~6.3.4",
Expand Down
2 changes: 2 additions & 0 deletions src/HospitalRun.tsx
Expand Up @@ -14,6 +14,7 @@ import { ButtonBarProvider } from './page-header/ButtonBarProvider'
import ButtonToolBar from './page-header/ButtonToolBar'
import Patients from './patients/Patients'
import Appointments from './scheduling/appointments/Appointments'
import Settings from './settings/Settings'
import { RootState } from './store'

const HospitalRun = () => {
Expand Down Expand Up @@ -45,6 +46,7 @@ const HospitalRun = () => {
<PrivateRoute isAuthenticated path="/patients" component={Patients} />
<PrivateRoute isAuthenticated path="/labs" component={Labs} />
<PrivateRoute isAuthenticated path="/incidents" component={Incidents} />
<PrivateRoute isAuthenticated path="/settings" component={Settings} />
</Switch>
</div>
<Toaster autoClose={5000} hideProgressBar draggable />
Expand Down
22 changes: 22 additions & 0 deletions src/__tests__/HospitalRun.test.tsx
Expand Up @@ -17,6 +17,7 @@ import Incidents from '../incidents/Incidents'
import ViewLabs from '../labs/ViewLabs'
import Permissions from '../model/Permissions'
import Appointments from '../scheduling/appointments/Appointments'
import Settings from '../settings/Settings'
import { RootState } from '../store'

const mockStore = createMockStore<RootState, any>([thunk])
Expand Down Expand Up @@ -170,6 +171,27 @@ describe('HospitalRun', () => {
expect(wrapper.find(Dashboard)).toHaveLength(1)
})
})

describe('/settings', () => {
it('should render the Settings component when /settings is accessed', async () => {
const store = mockStore({
title: 'test',
user: { permissions: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
} as any)

const wrapper = mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/settings']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(Settings)).toHaveLength(1)
})
})
})

describe('layout', () => {
Expand Down
43 changes: 43 additions & 0 deletions src/__tests__/settings/Settings.test.tsx
@@ -0,0 +1,43 @@
import '../../__mocks__/matchMediaMock'

import { mount } from 'enzyme'
import { createMemoryHistory } from 'history'
import React from 'react'
import { Provider } from 'react-redux'
import { Router } from 'react-router-dom'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import * as titleUtil from '../../page-header/useTitle'
import Settings from '../../settings/Settings'
import { RootState } from '../../store'

const mockStore = createMockStore<RootState, any>([thunk])

describe('Settings', () => {
const setup = () => {
jest.spyOn(titleUtil, 'default')

const store = mockStore({ title: 'test' } as any)

const history = createMemoryHistory()
history.push('/settings')

const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<Settings />
</Router>
</Provider>,
)

return wrapper
}

describe('layout', () => {
it('should set the title', () => {
setup()
expect(titleUtil.default).toHaveBeenCalledWith('settings.label')
})
})
})
20 changes: 19 additions & 1 deletion src/components/Navbar.tsx
Expand Up @@ -12,7 +12,7 @@ const Navbar = () => {
variant="dark"
navItems={[
{
type: 'icon',
type: 'image',
src:
'data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53%0D%0AMy5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5r%0D%0AIiB2aWV3Qm94PSIwIDAgMjk5IDI5OSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOnVybCgjbGlu%0D%0AZWFyLWdyYWRpZW50KTt9PC9zdHlsZT48bGluZWFyR3JhZGllbnQgaWQ9ImxpbmVhci1ncmFkaWVu%0D%0AdCIgeDE9IjcyLjU4IiB5MT0iMTYuMDQiIHgyPSIyMjcuMzEiIHkyPSIyODQuMDIiIGdyYWRpZW50%0D%0AVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAuMDEiIHN0b3AtY29sb3I9IiM2%0D%0AMGQxYmIiLz48c3RvcCBvZmZzZXQ9IjAuNSIgc3RvcC1jb2xvcj0iIzFhYmM5YyIvPjxzdG9wIG9m%0D%0AZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwOWI5ZSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjx0%0D%0AaXRsZT5jcm9zcy1pY29uPC90aXRsZT48cGF0aCBpZD0iY3Jvc3MiIGNsYXNzPSJjbHMtMSIgZD0i%0D%0ATTI5Mi45NCw5Ny40NkgyMDUuM1Y3LjA2QTYuNTYsNi41NiwwLDAsMCwxOTguNzQuNUgxMDEuMjZB%0D%0ANi41Niw2LjU2LDAsMCwwLDk0LjcsNy4wNnY5MC40SDcuMDZBNi41OCw2LjU4LDAsMCwwLC41LDEw%0D%0ANFYxOTYuM2E2LjIzLDYuMjMsMCwwLDAsNi4yMyw2LjI0aDg4djkwLjRhNi41Niw2LjU2LDAsMCww%0D%0ALDYuNTYsNi41Nmg5Ny40OGE2LjU2LDYuNTYsMCwwLDAsNi41Ni02LjU2di05MC40aDg4YTYuMjMs%0D%0ANi4yMywwLDAsMCw2LjIzLTYuMjRWMTA0QTYuNTgsNi41OCwwLDAsMCwyOTIuOTQsOTcuNDZaIiB0%0D%0AcmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIi8+PC9zdmc+',
onClick: () => {
Expand Down Expand Up @@ -100,6 +100,24 @@ const Navbar = () => {
onClickButton: () => undefined,
onChangeInput: () => undefined,
},
{
type: 'link-list-icon',
alignRight: true,
children: [
{
type: 'link',
label: t('settings.label'),
onClick: () => {
history.push('/settings')
},
},
],
className: 'pl-4',
iconClassName: 'align-bottom',
label: 'Patient',
name: 'patient',
size: 'lg',
},
]}
/>
)
Expand Down
34 changes: 34 additions & 0 deletions src/components/input/LanguageSelector.tsx
@@ -0,0 +1,34 @@
import _ from 'lodash'
import React from 'react'
import { useTranslation } from 'react-i18next'

import i18n, { resources } from '../../i18n'
import SelectWithLabelFormGroup from './SelectWithLableFormGroup'

const LanguageSelector = () => {
const { t } = useTranslation()

let languageOptions = Object.keys(resources).map((abbr) => ({
label: resources[abbr].name,
value: abbr,
}))
languageOptions = _.sortBy(languageOptions, (o) => o.label)

const onLanguageChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const selected = event.target.value
i18n.changeLanguage(selected)
}

return (
<SelectWithLabelFormGroup
name="language"
value={i18n.language}
label={t('settings.language.label')}
isEditable
options={languageOptions}
onChange={onLanguageChange}
/>
)
}

export default LanguageSelector
14 changes: 13 additions & 1 deletion src/i18n.ts
Expand Up @@ -14,38 +14,49 @@ import translationPtBR from './locales/ptBr/translations'
import translationRU from './locales/ru/translations'
import translationZhCN from './locales/zhCN/translations'

const resources = {
const resources: { [language: string]: any } = {
it: {
name: 'Italian',
translation: translationIT,
},
ar: {
name: 'Arabic',
translation: translationAR,
},
de: {
name: 'German',
translation: translationDE,
},
en: {
name: 'English, American',
translation: translationEnUs,
},
es: {
name: 'Spanish',
translation: translationES,
},
fr: {
name: 'French',
translation: translationFR,
},
id: {
name: 'Indonesian',
translation: translationID,
},
ja: {
name: 'Japanese',
translation: translationJA,
},
ptBR: {
name: 'Portuguese',
translation: translationPtBR,
},
ru: {
name: 'Russian',
translation: translationRU,
},
zhCN: {
name: 'Chinese',
translation: translationZhCN,
},
}
Expand All @@ -70,3 +81,4 @@ i18n
})

export default i18n
export { resources }
2 changes: 2 additions & 0 deletions src/locales/ar/translations/index.ts
Expand Up @@ -2,10 +2,12 @@ import actions from './actions'
import dashboard from './dashboard'
import patient from './patient'
import patients from './patients'
import settings from './settings'

export default {
...actions,
...dashboard,
...patient,
...patients,
...settings,
}
3 changes: 3 additions & 0 deletions src/locales/ar/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/de/translations/index.ts
Expand Up @@ -5,6 +5,7 @@ import labs from './labs'
import patient from './patient'
import patients from './patients'
import scheduling from './scheduling'
import settings from './settings'
import sex from './sex'
import states from './states'

Expand All @@ -13,6 +14,7 @@ export default {
...dashboard,
...patient,
...patients,
...settings,
...scheduling,
...states,
...sex,
Expand Down
3 changes: 3 additions & 0 deletions src/locales/de/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/enUs/translations/index.ts
Expand Up @@ -5,6 +5,7 @@ import labs from './labs'
import patient from './patient'
import patients from './patients'
import scheduling from './scheduling'
import settings from './settings'
import sex from './sex'
import states from './states'

Expand All @@ -18,4 +19,5 @@ export default {
...sex,
...labs,
...incidents,
...settings,
}
8 changes: 8 additions & 0 deletions src/locales/enUs/translations/settings/index.ts
@@ -0,0 +1,8 @@
export default {
settings: {
label: 'Settings',
language: {
label: 'Language',
},
},
}
2 changes: 2 additions & 0 deletions src/locales/es/translations/index.ts
Expand Up @@ -3,11 +3,13 @@ import dashboard from './dashboard'
import labs from './labs'
import patient from './patient'
import patients from './patients'
import settings from './settings'

export default {
...actions,
...dashboard,
...labs,
...patient,
...patients,
...settings,
}
3 changes: 3 additions & 0 deletions src/locales/es/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/fr/translations/index.ts
Expand Up @@ -4,6 +4,7 @@ import labs from './labs'
import patient from './patient'
import patients from './patients'
import scheduling from './scheduling'
import settings from './settings'
import sex from './sex'
import states from './states'

Expand All @@ -16,4 +17,5 @@ export default {
...states,
...sex,
...labs,
...settings,
}
3 changes: 3 additions & 0 deletions src/locales/fr/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/id/translations/index.ts
Expand Up @@ -3,11 +3,13 @@ import dashboard from './dashboard'
import labs from './labs'
import patient from './patient'
import patients from './patients'
import settings from './settings'

export default {
...actions,
...dashboard,
...labs,
...patient,
...patients,
...settings,
}
3 changes: 3 additions & 0 deletions src/locales/id/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/it/translations/index.ts
Expand Up @@ -4,6 +4,7 @@ import labs from './labs'
import patient from './patient'
import patients from './patients'
import scheduling from './scheduling'
import settings from './settings'
import sex from './sex'
import states from './states'

Expand All @@ -16,4 +17,5 @@ export default {
...states,
...sex,
...labs,
...settings,
}
3 changes: 3 additions & 0 deletions src/locales/it/translations/settings/index.ts
@@ -0,0 +1,3 @@
export default {
settings: {},
}
2 changes: 2 additions & 0 deletions src/locales/ja/translations/index.ts
Expand Up @@ -3,11 +3,13 @@ import dashboard from './dashboard'
import labs from './labs'
import patient from './patient'
import patients from './patients'
import settings from './settings'

export default {
...actions,
...dashboard,
...labs,
...patient,
...patients,
...settings,
}
8 changes: 8 additions & 0 deletions src/locales/ja/translations/settings/index.ts
@@ -0,0 +1,8 @@
export default {
settings: {
label: '設定',
language: {
label: '言語',
},
},
}
2 changes: 2 additions & 0 deletions src/locales/ptBr/translations/index.ts
Expand Up @@ -4,6 +4,7 @@ import labs from './labs'
import patient from './patient'
import patients from './patients'
import scheduling from './scheduling'
import settings from './settings'
import sex from './sex'
import states from './states'

Expand All @@ -16,4 +17,5 @@ export default {
...states,
...sex,
...labs,
...settings,
}

1 comment on commit e5677fe

@vercel
Copy link

@vercel vercel bot commented on e5677fe May 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.