Skip to content

Commit

Permalink
fix(i18n): make sure i18n.t is called after the locale has been set
Browse files Browse the repository at this point in the history
  • Loading branch information
HendrikThePendric authored May 7, 2020
2 parents 325470f + 47761cf commit f1709d9
Show file tree
Hide file tree
Showing 21 changed files with 214 additions and 138 deletions.
6 changes: 3 additions & 3 deletions src/components/AsyncAutoComplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ const baseState = {
errorStyle: styles.error.info,
}

const defaultAutoCompleteProps = {
const getDefaultAutoCompleteProps = () => ({
floatingLabelText: i18n.t('Search'),
hintText: i18n.t('Enter search term'),
fullWidth: true,
type: 'search',
filter: () => true,
}
})

/**
* Generic component that renders a MUI AutoComplete. It can execute an async query and show a list of results.
Expand Down Expand Up @@ -137,7 +137,7 @@ class AsyncAutoComplete extends Component {
render() {
const { autoCompleteProps } = this.props
const mergedAutoCompleteProps = {
...defaultAutoCompleteProps,
...getDefaultAutoCompleteProps(),
...autoCompleteProps,
}
const {
Expand Down
11 changes: 7 additions & 4 deletions src/components/AuthorityEditor/AuthorityEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import createHumanErrorMessage from '../../utils/createHumanErrorMessage'
import api from '../../api'
import AuthorityFilter from './AuthorityFilter'
import FilteredAuthoritySections from './FilteredAuthoritySections'
import { EMPTY_GROUPED_AUTHORITIES } from './utils/groupAuthorities'
import { getEmptyGroupedAuthorities } from './utils/groupAuthorities'

/**
* This is the parent component of the authorities section in the RoleForm.
Expand All @@ -18,7 +18,7 @@ class AuthorityEditor extends Component {
constructor(props) {
super(props)
this.state = {
allGroupedAuthorities: EMPTY_GROUPED_AUTHORITIES,
allGroupedAuthorities: getEmptyGroupedAuthorities(),
}
// This lookup may be updated without triggering re-renders
this.selectedItemsLookup = props.initiallySelected.reduce(
Expand Down Expand Up @@ -58,9 +58,12 @@ class AuthorityEditor extends Component {
i18n.t('There was a problem retreiving the available authorities.')
)
const allGroupedAuthorities = Object.keys(
EMPTY_GROUPED_AUTHORITIES
getEmptyGroupedAuthorities()
).reduce((total, key) => {
total[key] = { ...EMPTY_GROUPED_AUTHORITIES[key], items: errorMsg }
total[key] = {
...getEmptyGroupedAuthorities()[key],
items: errorMsg,
}
return total
}, {})
this.setState({ allGroupedAuthorities })
Expand Down
139 changes: 76 additions & 63 deletions src/components/AuthorityEditor/utils/authorityGroupNames.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,78 @@
import i18n from '@dhis2/d2-i18n'

export default new Map([
['ALL', i18n.t('All (Full authority)')],
['F_ANALYTICSTABLEHOOK', i18n.t('Analytics Table Hook')],
['F_ATTRIBUTE', i18n.t('Attribute')],
['F_CATEGORY_COMBO', i18n.t('Category Combo')],
['F_CATEGORY', i18n.t('Category')],
['F_CATEGORY_OPTION', i18n.t('Category Option')],
['F_CATEGORY_OPTION_GROUP', i18n.t('Category Option Group')],
['F_CATEGORY_OPTION_GROUP_SET', i18n.t('Category Option Group Set')],
['F_COLOR_SET', i18n.t('Color Set')],
['F_CONSTANT', i18n.t('Constant')],
['F_DASHBOARD', i18n.t('Dashboard')],
['F_DATAELEMENTGROUPSET', i18n.t('Data Element Group Sets')],
['F_DATAELEMENTGROUP', i18n.t('Data Element Groups')],
['F_DATAELEMENT', i18n.t('Data Element')],
['F_DATAELEMENT_MINMAX', i18n.t('Min/max rule')],
['F_DATASET', i18n.t('Data Set')],
['F_DATAVALUE', i18n.t('Data Value')],
['F_DOCUMENT', i18n.t('Document')],
['F_EVENTCHART', i18n.t('Event Chart')],
['F_EVENTREPORT', i18n.t('Event Report')],
['F_EXTERNAL_MAP_LAYER', i18n.t('External Map Layer')],
['F_INDICATORGROUPSET', i18n.t('Indicator Group Sets')],
['F_INDICATORGROUP', i18n.t('Indicator Group')],
['F_INDICATORTYPE', i18n.t('Indicator Type')],
['F_INDICATOR', i18n.t('Indicator')],
['F_LEGEND_SET', i18n.t('Legend Set')],
['F_MAP', i18n.t('Map')],
['F_MINMAX_DATAELEMENT', i18n.t('Min-Max Data Element')],
['F_OPTIONGROUPSET', i18n.t('Option Group Set')],
['F_OPTIONGROUP', i18n.t('Option Group')],
['F_OPTIONSET', i18n.t('Option Set')],
['F_ORGANISATIONUNIT', i18n.t('Organisation Unit')],
['F_ORGUNITGROUPSET', i18n.t('Organisation Unit Group Set')],
['F_ORGUNITGROUP', i18n.t('Organisation Unit Group')],
['F_PREDICTOR', i18n.t('Predictor')],
['F_PROGRAMSTAGE', i18n.t('Program Stage')],
['F_PROGRAM', i18n.t('Program')],
['F_PROGRAM_INDICATOR', i18n.t('Program Indicator')],
['F_PROGRAM_INDICATOR_GROUP', i18n.t('Program Indicator Group')],
['F_PROGRAM_RULE', i18n.t('Program Rule')],
[
'F_PROGRAM_TRACKED_ENTITY_ATTRIBUTE_GROUP',
i18n.t('Program Tracked Entity Attribute Group'),
],
['F_PUSH_ANALYSIS', i18n.t('Push Analysis')],
['F_RELATIONSHIPTYPE', i18n.t('Relationship Type')],
['F_REPORT', i18n.t('Report')],
['F_SECTION', i18n.t('Section')],
['F_SQLVIEW', i18n.t('SQL View')],
['F_TRACKED_ENTITY', i18n.t('Tracked Entity')],
['F_TRACKED_ENTITY_ATTRIBUTE', i18n.t('Tracked Entity Attribute')],
['F_TRACKED_ENTITY_DATAVALUE', i18n.t('Tracked Entity Data Value')],
['F_TRACKED_ENTITY_INSTANCE', i18n.t('Tracked Entity Instance')],
['F_USERGROUP', i18n.t('User Group')],
['F_USERROLE', i18n.t('User Role')],
['F_USER', i18n.t('User')],
['F_VALIDATIONRULEGROUP', i18n.t('Validation Rule Group')],
['F_VALIDATIONRULE', i18n.t('Validation Rule')],
['F_PREDICTORGROUP', i18n.t('Data predictor group')],
['F_SKIP_DATA_IMPORT_AUDIT', i18n.t('Skip data import audit')],
['F_VISUALIZATION', i18n.t('Visualization')],
])
const createNameLookup = () => {
return new Map([
['ALL', i18n.t('All (Full authority)')],
['F_ANALYTICSTABLEHOOK', i18n.t('Analytics Table Hook')],
['F_ATTRIBUTE', i18n.t('Attribute')],
['F_CATEGORY_COMBO', i18n.t('Category Combo')],
['F_CATEGORY', i18n.t('Category')],
['F_CATEGORY_OPTION', i18n.t('Category Option')],
['F_CATEGORY_OPTION_GROUP', i18n.t('Category Option Group')],
['F_CATEGORY_OPTION_GROUP_SET', i18n.t('Category Option Group Set')],
['F_COLOR_SET', i18n.t('Color Set')],
['F_CONSTANT', i18n.t('Constant')],
['F_DASHBOARD', i18n.t('Dashboard')],
['F_DATAELEMENTGROUPSET', i18n.t('Data Element Group Sets')],
['F_DATAELEMENTGROUP', i18n.t('Data Element Groups')],
['F_DATAELEMENT', i18n.t('Data Element')],
['F_DATAELEMENT_MINMAX', i18n.t('Min/max rule')],
['F_DATASET', i18n.t('Data Set')],
['F_DATAVALUE', i18n.t('Data Value')],
['F_DOCUMENT', i18n.t('Document')],
['F_EVENTCHART', i18n.t('Event Chart')],
['F_EVENTREPORT', i18n.t('Event Report')],
['F_EXTERNAL_MAP_LAYER', i18n.t('External Map Layer')],
['F_INDICATORGROUPSET', i18n.t('Indicator Group Sets')],
['F_INDICATORGROUP', i18n.t('Indicator Group')],
['F_INDICATORTYPE', i18n.t('Indicator Type')],
['F_INDICATOR', i18n.t('Indicator')],
['F_LEGEND_SET', i18n.t('Legend Set')],
['F_MAP', i18n.t('Map')],
['F_MINMAX_DATAELEMENT', i18n.t('Min-Max Data Element')],
['F_OPTIONGROUPSET', i18n.t('Option Group Set')],
['F_OPTIONGROUP', i18n.t('Option Group')],
['F_OPTIONSET', i18n.t('Option Set')],
['F_ORGANISATIONUNIT', i18n.t('Organisation Unit')],
['F_ORGUNITGROUPSET', i18n.t('Organisation Unit Group Set')],
['F_ORGUNITGROUP', i18n.t('Organisation Unit Group')],
['F_PREDICTOR', i18n.t('Predictor')],
['F_PROGRAMSTAGE', i18n.t('Program Stage')],
['F_PROGRAM', i18n.t('Program')],
['F_PROGRAM_INDICATOR', i18n.t('Program Indicator')],
['F_PROGRAM_INDICATOR_GROUP', i18n.t('Program Indicator Group')],
['F_PROGRAM_RULE', i18n.t('Program Rule')],
[
'F_PROGRAM_TRACKED_ENTITY_ATTRIBUTE_GROUP',
i18n.t('Program Tracked Entity Attribute Group'),
],
['F_PUSH_ANALYSIS', i18n.t('Push Analysis')],
['F_RELATIONSHIPTYPE', i18n.t('Relationship Type')],
['F_REPORT', i18n.t('Report')],
['F_SECTION', i18n.t('Section')],
['F_SQLVIEW', i18n.t('SQL View')],
['F_TRACKED_ENTITY', i18n.t('Tracked Entity')],
['F_TRACKED_ENTITY_ATTRIBUTE', i18n.t('Tracked Entity Attribute')],
['F_TRACKED_ENTITY_DATAVALUE', i18n.t('Tracked Entity Data Value')],
['F_TRACKED_ENTITY_INSTANCE', i18n.t('Tracked Entity Instance')],
['F_USERGROUP', i18n.t('User Group')],
['F_USERROLE', i18n.t('User Role')],
['F_USER', i18n.t('User')],
['F_VALIDATIONRULEGROUP', i18n.t('Validation Rule Group')],
['F_VALIDATIONRULE', i18n.t('Validation Rule')],
['F_PREDICTORGROUP', i18n.t('Data predictor group')],
['F_SKIP_DATA_IMPORT_AUDIT', i18n.t('Skip data import audit')],
['F_VISUALIZATION', i18n.t('Visualization')],
])
}

// returns cached results after first call
export default (() => {
let map = null
return () => {
if (!map) {
map = createNameLookup()
}
return map
}
})()
32 changes: 21 additions & 11 deletions src/components/AuthorityEditor/utils/groupAuthorities.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import i18n from '@dhis2/d2-i18n'
import startsWith from 'lodash.startswith'
import endsWith from 'lodash.endswith'
import sortBy from 'lodash.sortby'
import nameLookup from './authorityGroupNames'
import getNameLookup from './authorityGroupNames'

// The next 3 constants are exported so they can be used by the AuthorityEditor component

// The target object to which the allAuths array will be mapped
export const EMPTY_GROUPED_AUTHORITIES = {
const createEmptyGroupedAuthorities = () => ({
metadata: {
name: 'Metadata',
items: null,
Expand Down Expand Up @@ -40,7 +37,20 @@ export const EMPTY_GROUPED_AUTHORITIES = {
items: null,
headers: ['Name'],
},
}
})

// The next 3 constants are exported so they can be used by the AuthorityEditor component

// The target object to which the allAuths array will be mapped
export const getEmptyGroupedAuthorities = (() => {
let emptyGroupedAuthorities = null
return () => {
if (!emptyGroupedAuthorities) {
emptyGroupedAuthorities = createEmptyGroupedAuthorities()
}
return emptyGroupedAuthorities
}
})()

// Suffixes and prefixes
export const PUBLIC_ADD_SUFFIX = '_PUBLIC_ADD'
Expand Down Expand Up @@ -147,12 +157,12 @@ const groupAuthorities = authorities => {
return lookup
}, new Map())

// The initial state of items in EMPTY_GROUPED_AUTHORITIES is null, which makes the authority sections render a loader
// The initial state of items in emptyGroupedAuthorities is null, which makes the authority sections render a loader
// but the accumulator object passed into the reduce function below expects items to be empty arrays
const emptyGroupedAuthorities = Object.keys(
EMPTY_GROUPED_AUTHORITIES
getEmptyGroupedAuthorities()
).reduce((groupedBase, key) => {
groupedBase[key] = { ...EMPTY_GROUPED_AUTHORITIES[key], items: [] }
groupedBase[key] = { ...getEmptyGroupedAuthorities()[key], items: [] }
return groupedBase
}, {})

Expand Down Expand Up @@ -256,7 +266,7 @@ const createMetadataGroup = (auth, lookup) => {
ALL_METADATA_SUFFIXES.forEach(suffix => lookup.delete(baseName + suffix))

return {
name: nameLookup.get(baseName) || baseName,
name: getNameLookup().get(baseName) || baseName,
items: [publicAddAuth, privateAddAuth, deleteAuth, externalAccessAuth],
}
}
Expand All @@ -274,7 +284,7 @@ const addToAuthoritySection = (auth, groupedAuthorities, lookup) => {
) || 'system'

if (auth.id === 'ALL') {
auth.name = nameLookup.get(auth.id)
auth.name = getNameLookup().get(auth.id)
}

groupedAuthorities[groupKey].items.push(auth)
Expand Down
4 changes: 2 additions & 2 deletions src/components/CardLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CardText from 'material-ui/Card/CardText'
import CardActions from 'material-ui/Card/CardActions'
import IconButton from 'material-ui/IconButton/IconButton'
import navigateTo from '../utils/navigateTo'
import { SECTIONS } from '../constants/routeConfig'
import { getSections } from '../constants/routeConfig'

const cardStyle = {
padding: '0',
Expand Down Expand Up @@ -102,7 +102,7 @@ class CardLinks extends Component {
}

render() {
const cards = SECTIONS.map(this.renderCard)
const cards = getSections().map(this.renderCard)

if (cards.length === 0) {
return (
Expand Down
4 changes: 2 additions & 2 deletions src/components/SectionLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Switch, Route, withRouter } from 'react-router-dom'
import { initCurrentUser } from '../actions'
import LoadingMask from 'd2-ui/lib/loading-mask/LoadingMask.component'
import ErrorMessage from './ErrorMessage'
import ROUTE_CONFIG from '../constants/routeConfig'
import getRouteConfig from '../constants/routeConfig'
import SideNav from './SideNav'
import navigateTo from '../utils/navigateTo'

Expand Down Expand Up @@ -64,7 +64,7 @@ class SectionLoader extends Component {
setRouteConfig(currentUser) {
this.routeConfig = !currentUser
? null
: ROUTE_CONFIG.reduce(
: getRouteConfig().reduce(
(routeConfig, configItem) => {
const { routes, sections } = routeConfig
if (this.userHasAuthorities(configItem, currentUser)) {
Expand Down
14 changes: 7 additions & 7 deletions src/constants/detailFieldConfigs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import i18n from '@dhis2/d2-i18n'

const BASE_FIELDS = [
const getBaseFields = () => [
{
key: 'displayName',
label: i18n.t('Display name'),
Expand All @@ -11,8 +11,8 @@ const BASE_FIELDS = [
},
]

export const USER_PROFILE = [
...BASE_FIELDS,
export const getUserProfile = () => [
...getBaseFields(),
{
key: 'userCredentials',
nestedPropselector: ['lastLogin'],
Expand Down Expand Up @@ -91,16 +91,16 @@ export const USER_PROFILE = [
},
]

export const USER_ROLE_DETAILS = [
...BASE_FIELDS,
export const getUserRoleDetails = () => [
...getBaseFields(),
{
key: 'users',
label: i18n.t('Members'),
count: true,
},
]
export const USER_GROUP_DETAILS = [
...BASE_FIELDS,
export const getUserGroupDetails = () => [
...getBaseFields(),
{
key: 'users',
label: i18n.t('Number of users'),
Expand Down
9 changes: 7 additions & 2 deletions src/constants/queryFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ export const USER_DETAILS = [
'twitter',
]

export const USER_ROLE_DETAILS = [':owner', 'authorities', 'displayName']
export const USER_ROLE_DETAILS = [
':owner',
'access',
'authorities',
'displayName',
]

export const USER_GROUP_DETAILS = [':owner', 'displayName']
export const USER_GROUP_DETAILS = [':owner', 'access', 'displayName']

export const CURRENT_USER_ORG_UNITS_FIELDS = {
fields: [
Expand Down
Loading

0 comments on commit f1709d9

Please sign in to comment.