Skip to content
This repository has been archived by the owner on Feb 21, 2019. It is now read-only.

Commit

Permalink
[tracim/tracim#1062] added browser lang detection + fixed role and pr…
Browse files Browse the repository at this point in the history
…ofil translation
  • Loading branch information
Skylsmoi committed Nov 5, 2018
1 parent afade47 commit db4b6da
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 42 deletions.
2 changes: 1 addition & 1 deletion frontend/src/component/Dashboard/UserStatus.jsx
@@ -1,5 +1,5 @@
import React from 'react'
import {ROLE} from '../../helper.js'
import { ROLE } from '../../helper.js'

require('./UserStatus.styl')

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/container/Header.jsx
Expand Up @@ -26,6 +26,14 @@ import {
import { PAGE, PROFILE } from '../helper.js'

class Header extends React.Component {
componentDidMount () {
i18n.changeLanguage(this.props.user.lang)
}

componentDidUpdate (prevProps) {
if (prevProps.user.lang !== this.props.user.lang) i18n.changeLanguage(this.props.user.lang)
}

handleClickLogo = () => {
const { props } = this

Expand Down
18 changes: 2 additions & 16 deletions frontend/src/container/Login.jsx
Expand Up @@ -14,7 +14,6 @@ import {
newFlashMessage,
setUserConnected,
setWorkspaceList,
setWorkspaceListIsOpenInSidebar,
setContentTypeList,
setAppList,
setConfig
Expand Down Expand Up @@ -120,23 +119,10 @@ class Login extends React.Component {
if (fetchGetContentTypeList.status === 200) props.dispatch(setContentTypeList(fetchGetContentTypeList.json))
}

// @FIXME Côme - 2018/08/22 - this function is duplicated from Tracim.jsx
loadWorkspaceList = async user => {
loadWorkspaceList = async () => {
const { props } = this

const fetchGetWorkspaceList = await props.dispatch(getMyselfWorkspaceList())

if (fetchGetWorkspaceList.status === 200) {
props.dispatch(setWorkspaceList(fetchGetWorkspaceList.json))

const idWorkspaceToOpen = (() =>
props.match && props.match.params.idws !== undefined && !isNaN(props.match.params.idws)
? parseInt(props.match.params.idws)
: fetchGetWorkspaceList.json[0].workspace_id
)()

props.dispatch(setWorkspaceListIsOpenInSidebar(idWorkspaceToOpen, true))
}
if (fetchGetWorkspaceList.status === 200) props.dispatch(setWorkspaceList(fetchGetWorkspaceList.json))
}

handleClickForgotPassword = async () => this.props.history.push(PAGE.FORGOT_PASSWORD)
Expand Down
38 changes: 26 additions & 12 deletions frontend/src/helper.js
@@ -1,7 +1,10 @@
import i18n from './i18n.js'
import i18n, { getBrowserLang } from './i18n.js'

const configEnv = require('../configEnv.json')

// this function is declared in i18n to avoid cyclic imports and reexported here for consistency
export { getBrowserLang }

export const FETCH_CONFIG = {
headers: {
'Accept': 'application/json',
Expand Down Expand Up @@ -49,25 +52,29 @@ export const ROLE = [{
slug: 'workspace-manager',
faIcon: 'gavel',
hexcolor: '#ed0007',
label: i18n.t('Shared space manager')
tradKey: i18n.t('Shared space manager'), // trad key allow the parser to generate an entry in the json file
label: 'Shared space manager' // label must be used in components
}, {
id: 4,
slug: 'content-manager',
faIcon: 'graduation-cap',
hexcolor: '#f2af2d',
label: i18n.t('Content manager')
tradKey: i18n.t('Content manager'), // trad key allow the parser to generate an entry in the json file
label: 'Content manager' // label must be used in components
}, {
id: 2,
slug: 'contributor',
faIcon: 'pencil',
hexcolor: '#3145f7',
label: i18n.t('Contributor')
tradKey: i18n.t('Contributor'), // trad key allow the parser to generate an entry in the json file
label: 'Contributor' // label must be used in components
}, {
id: 1,
slug: 'reader',
faIcon: 'eye',
hexcolor: '#15d948',
label: i18n.t('Reader')
tradKey: i18n.t('Reader'), // trad key allow the parser to generate an entry in the json file
label: 'Reader' // label must be used in components
}]

export const findIdRoleUserWorkspace = (idUser, memberList, roleList) => {
Expand All @@ -82,28 +89,32 @@ export const ROLE2 = {
sluf: 'reader',
faIcon: 'eye',
hexcolor: '#15D948',
label: i18n.t('Reader')
tradKey: i18n.t('Reader'), // trad key allow the parser to generate an entry in the json file
label: 'Reader' // label must be used in components
},
contributor: {
id: 2,
slug: 'contributor',
faIcon: 'pencil',
hexcolor: '#3145f7',
label: i18n.t('Contributor')
tradKey: i18n.t('Contributor'), // trad key allow the parser to generate an entry in the json file
label: 'Contributor' // label must be used in components
},
contentManager: {
id: 4,
slug: 'content-manager',
faIcon: 'graduation-cap',
hexcolor: '#f2af2d',
label: i18n.t('Content manager')
tradKey: i18n.t('Content manager'), // trad key allow the parser to generate an entry in the json file
label: 'Content manager' // label must be used in components
},
workspaceManager: {
id: 8,
slug: 'workspace-manager',
faIcon: 'gavel',
hexcolor: '#ed0007',
label: i18n.t('Shared space manager')
tradKey: i18n.t('Shared space manager'), // trad key allow the parser to generate an entry in the json file
label: 'Shared space manager' // label must be used in components
}
}

Expand All @@ -113,21 +124,24 @@ export const PROFILE = {
slug: 'administrators',
faIcon: 'shield',
hexcolor: '#ed0007',
label: i18n.t('Administrator')
tradKey: i18n.t('Administrator'), // trad key allow the parser to generate an entry in the json file
label: 'Administrator' // label must be used in components
},
MANAGER: {
id: 2,
slug: 'trusted-users',
faIcon: 'graduation-cap',
hexcolor: '#f2af2d',
label: i18n.t('Trusted user')
tradKey: i18n.t('Trusted user'), // trad key allow the parser to generate an entry in the json file
label: 'Trusted user' // label must be used in components
},
USER: {
id: 4,
slug: 'users',
faIcon: 'user',
hexcolor: '#3145f7',
label: i18n.t('User')
tradKey: i18n.t('User'), // trad key allow the parser to generate an entry in the json file
label: 'User' // label must be used in components
}
}

Expand Down
11 changes: 10 additions & 1 deletion frontend/src/i18n.js
Expand Up @@ -19,10 +19,19 @@ const wsAdvancedFrTranslation = require('../dist/app/workspace_advanced_fr_trans
const wsEnTranslation = require('../dist/app/workspace_en_translation.json')
const wsFrTranslation = require('../dist/app/workspace_fr_translation.json')

export const getBrowserLang = () => {
const browserLang = navigator.language

if (['en', 'fr'].includes(browserLang)) return browserLang
if (browserLang.includes('fr')) return 'fr' // for fr-XX

return 'en'
}

i18n
.use(reactI18nextModule)
.init({
fallbackLng: 'en',
fallbackLng: getBrowserLang(),
// have a common namespace used around the full app
ns: ['translation'], // namespace
defaultNS: 'translation',
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/reducer/user.js
Expand Up @@ -8,6 +8,7 @@ import {
USER_EMAIL
} from '../action-creator.sync.js'
import { generateAvatarFromPublicName } from 'tracim_frontend_lib'
import { getBrowserLang } from '../helper.js'

const defaultUser = {
user_id: -1,
Expand All @@ -24,7 +25,7 @@ const defaultUser = {
avatar_url: null,
created: '',
public_name: '',
lang: 'en'
lang: getBrowserLang()
}

export default function user (state = defaultUser, action) {
Expand All @@ -33,7 +34,7 @@ export default function user (state = defaultUser, action) {
return {
...state,
...action.user,
lang: action.user.lang ? action.user.lang : 'en',
lang: action.user.lang ? action.user.lang : state.lang,
avatar_url: action.user.avatar_url
? action.user.avatar_url
: action.user.public_name ? generateAvatarFromPublicName(action.user.public_name) : ''
Expand Down
6 changes: 3 additions & 3 deletions frontend_lib/i18next.scanner/en/translation.json
Expand Up @@ -7,12 +7,10 @@
"Rich text": "Rich text",
"Send": "Send",
"Your message...": "Your message...",
"Edit": "Edit",
"validate the title": "validate the title",
"edit title": "edit title",
"Archive": "Archive",
"Delete": "Delete",
"Create an account": "Create an account",
"Choose the role of the member": "Choose the role of the member",
"Validate": "Validate",
"Status": "Status",
Expand All @@ -32,5 +30,7 @@
"Email notifications are disabled, you can't create new users from here": "Email notifications are disabled, you can't create new users from here",
"Send an invitational email to this user": "Send an invitational email to this user",
"I know this user exist": "I know this user exist",
"Unexpected error, please inform an administrator": "Unexpected error, please inform an administrator"
"Unexpected error, please inform an administrator": "Unexpected error, please inform an administrator",
"Cancel": "Cancel",
"Name or email": "Name or email"
}
6 changes: 3 additions & 3 deletions frontend_lib/i18next.scanner/fr/translation.json
Expand Up @@ -7,12 +7,10 @@
"Rich text": "Texte riche",
"Send": "Envoyer",
"Your message...": "Votre message ...",
"Edit": "Modifier",
"validate the title": "valider le titre",
"edit title": "modifier le titre",
"Archive": "archiver",
"Delete": "supprimer",
"Create an account": "Créer un compte",
"Choose the role of the member": "Choissir le role du membre",
"Validate": "Valider",
"Status": "Statut ",
Expand All @@ -32,5 +30,7 @@
"Email notifications are disabled, you can't create new users from here": "Les notifications par email sont désactivées, vous ne pouvez pas créer d'utilisateur à partir d'ici",
"Send an invitational email to this user": "Envoyer un email d'invitation à cet utilisateur",
"I know this user exist": "Je sais que cet utilisateur existe",
"Unexpected error, please inform an administrator": "Erreur inattendue, veuillez contacter un administrateur"
"Unexpected error, please inform an administrator": "Erreur inattendue, veuillez contacter un administrateur",
"Cancel": "Annuler",
"Name or email": "Nom ou email"
}
7 changes: 4 additions & 3 deletions frontend_lib/src/component/Input/TextAreaApp/TextAreaApp.jsx
@@ -1,5 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import Radium from 'radium'

require('./TextAreaApp.styl')
Expand Down Expand Up @@ -29,7 +30,7 @@ export const TextAreaApp = props =>
}}
key='TextAreaApp__cancel'
>
Annuler
{props.t('Cancel')}
</button>

<button
Expand All @@ -47,12 +48,12 @@ export const TextAreaApp = props =>
}}
key='TextAreaApp__validate'
>
Valider
{props.t('Validate')}
</button>
</div>
</form>

export default Radium(TextAreaApp)
export default translate()(Radium(TextAreaApp))

TextAreaApp.propTypes = {
text: PropTypes.string.isRequired,
Expand Down
2 changes: 1 addition & 1 deletion frontend_lib/src/component/NewMemberForm/NewMemberForm.jsx
Expand Up @@ -24,7 +24,7 @@ export const NewMemberForm = props => {
type='text'
className='name__input form-control'
id='addmember'
placeholder='Nom ou Email'
placeholder={props.t('Name or email')}
value={props.nameOrEmail}
onChange={e => props.onChangeNameOrEmail(e.target.value)}
autoComplete='off'
Expand Down

0 comments on commit db4b6da

Please sign in to comment.