diff --git a/package.json b/package.json index f8f8b7d3ee..8193f2552b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/HospitalRun.tsx b/src/HospitalRun.tsx index df0a8f7d43..96ce24a194 100644 --- a/src/HospitalRun.tsx +++ b/src/HospitalRun.tsx @@ -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 = () => { @@ -45,6 +46,7 @@ const HospitalRun = () => { + diff --git a/src/__tests__/HospitalRun.test.tsx b/src/__tests__/HospitalRun.test.tsx index 049e966179..31a05117b3 100644 --- a/src/__tests__/HospitalRun.test.tsx +++ b/src/__tests__/HospitalRun.test.tsx @@ -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([thunk]) @@ -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( + + + + + , + ) + + expect(wrapper.find(Settings)).toHaveLength(1) + }) + }) }) describe('layout', () => { diff --git a/src/__tests__/settings/Settings.test.tsx b/src/__tests__/settings/Settings.test.tsx new file mode 100644 index 0000000000..d4820d513b --- /dev/null +++ b/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([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( + + + + + , + ) + + return wrapper + } + + describe('layout', () => { + it('should set the title', () => { + setup() + expect(titleUtil.default).toHaveBeenCalledWith('settings.label') + }) + }) +}) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index ebf576ae79..2283873055 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -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: () => { @@ -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', + }, ]} /> ) diff --git a/src/components/input/LanguageSelector.tsx b/src/components/input/LanguageSelector.tsx new file mode 100644 index 0000000000..5fc90334b6 --- /dev/null +++ b/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) => { + const selected = event.target.value + i18n.changeLanguage(selected) + } + + return ( + + ) +} + +export default LanguageSelector diff --git a/src/i18n.ts b/src/i18n.ts index 2115141842..430d64046b 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -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, }, } @@ -70,3 +81,4 @@ i18n }) export default i18n +export { resources } diff --git a/src/locales/ar/translations/index.ts b/src/locales/ar/translations/index.ts index e948f4340c..62cbb42d7b 100644 --- a/src/locales/ar/translations/index.ts +++ b/src/locales/ar/translations/index.ts @@ -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, } diff --git a/src/locales/ar/translations/settings/index.ts b/src/locales/ar/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/ar/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/de/translations/index.ts b/src/locales/de/translations/index.ts index 6afd27431e..425c94d1a3 100644 --- a/src/locales/de/translations/index.ts +++ b/src/locales/de/translations/index.ts @@ -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' @@ -13,6 +14,7 @@ export default { ...dashboard, ...patient, ...patients, + ...settings, ...scheduling, ...states, ...sex, diff --git a/src/locales/de/translations/settings/index.ts b/src/locales/de/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/de/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/enUs/translations/index.ts b/src/locales/enUs/translations/index.ts index 6afd27431e..ae9f29343f 100644 --- a/src/locales/enUs/translations/index.ts +++ b/src/locales/enUs/translations/index.ts @@ -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' @@ -18,4 +19,5 @@ export default { ...sex, ...labs, ...incidents, + ...settings, } diff --git a/src/locales/enUs/translations/settings/index.ts b/src/locales/enUs/translations/settings/index.ts new file mode 100644 index 0000000000..5b8a935324 --- /dev/null +++ b/src/locales/enUs/translations/settings/index.ts @@ -0,0 +1,8 @@ +export default { + settings: { + label: 'Settings', + language: { + label: 'Language', + }, + }, +} diff --git a/src/locales/es/translations/index.ts b/src/locales/es/translations/index.ts index 5307ce625c..0a23abd324 100644 --- a/src/locales/es/translations/index.ts +++ b/src/locales/es/translations/index.ts @@ -3,6 +3,7 @@ import dashboard from './dashboard' import labs from './labs' import patient from './patient' import patients from './patients' +import settings from './settings' export default { ...actions, @@ -10,4 +11,5 @@ export default { ...labs, ...patient, ...patients, + ...settings, } diff --git a/src/locales/es/translations/settings/index.ts b/src/locales/es/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/es/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/fr/translations/index.ts b/src/locales/fr/translations/index.ts index 5235352afc..887398b139 100644 --- a/src/locales/fr/translations/index.ts +++ b/src/locales/fr/translations/index.ts @@ -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' @@ -16,4 +17,5 @@ export default { ...states, ...sex, ...labs, + ...settings, } diff --git a/src/locales/fr/translations/settings/index.ts b/src/locales/fr/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/fr/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/id/translations/index.ts b/src/locales/id/translations/index.ts index 5307ce625c..0a23abd324 100644 --- a/src/locales/id/translations/index.ts +++ b/src/locales/id/translations/index.ts @@ -3,6 +3,7 @@ import dashboard from './dashboard' import labs from './labs' import patient from './patient' import patients from './patients' +import settings from './settings' export default { ...actions, @@ -10,4 +11,5 @@ export default { ...labs, ...patient, ...patients, + ...settings, } diff --git a/src/locales/id/translations/settings/index.ts b/src/locales/id/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/id/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/it/translations/index.ts b/src/locales/it/translations/index.ts index 5235352afc..887398b139 100644 --- a/src/locales/it/translations/index.ts +++ b/src/locales/it/translations/index.ts @@ -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' @@ -16,4 +17,5 @@ export default { ...states, ...sex, ...labs, + ...settings, } diff --git a/src/locales/it/translations/settings/index.ts b/src/locales/it/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/it/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/ja/translations/index.ts b/src/locales/ja/translations/index.ts index 5307ce625c..0a23abd324 100644 --- a/src/locales/ja/translations/index.ts +++ b/src/locales/ja/translations/index.ts @@ -3,6 +3,7 @@ import dashboard from './dashboard' import labs from './labs' import patient from './patient' import patients from './patients' +import settings from './settings' export default { ...actions, @@ -10,4 +11,5 @@ export default { ...labs, ...patient, ...patients, + ...settings, } diff --git a/src/locales/ja/translations/settings/index.ts b/src/locales/ja/translations/settings/index.ts new file mode 100644 index 0000000000..ea2539d3fe --- /dev/null +++ b/src/locales/ja/translations/settings/index.ts @@ -0,0 +1,8 @@ +export default { + settings: { + label: '設定', + language: { + label: '言語', + }, + }, +} diff --git a/src/locales/ptBr/translations/index.ts b/src/locales/ptBr/translations/index.ts index 5235352afc..887398b139 100644 --- a/src/locales/ptBr/translations/index.ts +++ b/src/locales/ptBr/translations/index.ts @@ -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' @@ -16,4 +17,5 @@ export default { ...states, ...sex, ...labs, + ...settings, } diff --git a/src/locales/ptBr/translations/settings/index.ts b/src/locales/ptBr/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/ptBr/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/ru/translations/index.ts b/src/locales/ru/translations/index.ts index 5307ce625c..0a23abd324 100644 --- a/src/locales/ru/translations/index.ts +++ b/src/locales/ru/translations/index.ts @@ -3,6 +3,7 @@ import dashboard from './dashboard' import labs from './labs' import patient from './patient' import patients from './patients' +import settings from './settings' export default { ...actions, @@ -10,4 +11,5 @@ export default { ...labs, ...patient, ...patients, + ...settings, } diff --git a/src/locales/ru/translations/settings/index.ts b/src/locales/ru/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/ru/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/locales/zhCN/translations/index.ts b/src/locales/zhCN/translations/index.ts index 5307ce625c..0a23abd324 100644 --- a/src/locales/zhCN/translations/index.ts +++ b/src/locales/zhCN/translations/index.ts @@ -3,6 +3,7 @@ import dashboard from './dashboard' import labs from './labs' import patient from './patient' import patients from './patients' +import settings from './settings' export default { ...actions, @@ -10,4 +11,5 @@ export default { ...labs, ...patient, ...patients, + ...settings, } diff --git a/src/locales/zhCN/translations/settings/index.ts b/src/locales/zhCN/translations/settings/index.ts new file mode 100644 index 0000000000..683884e258 --- /dev/null +++ b/src/locales/zhCN/translations/settings/index.ts @@ -0,0 +1,3 @@ +export default { + settings: {}, +} diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx new file mode 100644 index 0000000000..74df245d45 --- /dev/null +++ b/src/settings/Settings.tsx @@ -0,0 +1,24 @@ +import { Row, Column } from '@hospitalrun/components' +import React from 'react' +import { useTranslation } from 'react-i18next' + +import LanguageSelector from '../components/input/LanguageSelector' +import useTitle from '../page-header/useTitle' + +const Settings = () => { + const { t } = useTranslation() + useTitle(t('settings.label')) + + return ( + <> + + + + + + + + ) +} + +export default Settings