diff --git a/.eslintrc b/.eslintrc index b524b88050..838bfca319 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,7 @@ "ecmaFeatures": { "jsx": true, "classes": true, - "modules": true, + "modules": true }, "env": { // I write for browser diff --git a/.gitignore b/.gitignore index e4ddc366af..241c386cae 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,9 @@ artifact_node.sh # GitBook _book/ + +# Use yarn.lock +package-lock.json + +# Ignore old translation files +locales/*/*_old.json diff --git a/app/bootstrap.js b/app/bootstrap.js index 10aab3015a..08e39a2bfe 100644 --- a/app/bootstrap.js +++ b/app/bootstrap.js @@ -18,6 +18,7 @@ import { render } from 'react-dom'; import bows from 'bows'; import _ from 'lodash'; +import './core/language'; // Set the language before loading components import blipCreateStore from './redux/store'; import AppRoot from './redux/containers/Root'; @@ -42,10 +43,10 @@ var appContext = { config: config }; -// This anonymous function must remain in ES5 format because +// This anonymous function must remain in ES5 format because // the argument parameter used is not bound when using arrow functions // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions -appContext.trackMetric = function() { +appContext.trackMetric = function() { var args = Array.prototype.slice.call(arguments); return appContext.api.metrics.track.apply(appContext.api.metrics, args); }; @@ -84,7 +85,7 @@ appContext.init = callback => { * This renders the AppComponent into the DOM providing appContext * as the context for AppComponent so that the required dependencies * are passed in! - * + * */ appContext.start = () => { diff --git a/app/components/chart/trends.js b/app/components/chart/trends.js index d0e3cc64df..71aac3ffdd 100644 --- a/app/components/chart/trends.js +++ b/app/components/chart/trends.js @@ -22,6 +22,7 @@ import bows from 'bows'; import React, { PropTypes, PureComponent } from 'react'; import ReactDOM from 'react-dom'; import sundial from 'sundial'; +import { translate } from 'react-i18next'; import Header from './header'; import SubNav from './trendssubnav'; @@ -35,7 +36,7 @@ const TrendsContainer = viz.containers.TrendsContainer; const reshapeBgClassesToBgBounds = viz.utils.reshapeBgClassesToBgBounds; const Loader = viz.components.Loader; -class Trends extends PureComponent { +const Trends = translate()(class extends PureComponent { static propTypes = { bgPrefs: PropTypes.object.isRequired, chartPrefs: PropTypes.object.isRequired, @@ -105,7 +106,7 @@ class Trends extends PureComponent { } formatDate(datetime) { - const timePrefs = this.props.timePrefs + const { timePrefs, t } = this.props; let timezone; if (!timePrefs.timezoneAware) { timezone = 'UTC'; @@ -113,7 +114,7 @@ class Trends extends PureComponent { else { timezone = timePrefs.timezoneName || 'UTC'; } - return sundial.formatInTimezone(datetime, timezone, 'MMM D, YYYY'); + return sundial.formatInTimezone(datetime, timezone, t('MMM D, YYYY')); } getNewDomain(current, extent) { @@ -500,6 +501,6 @@ class Trends extends PureComponent { focusedPoint={this.props.trendsState[currentPatientInViewId].focusedSmbg} /> ); } -} +}); export default Trends; diff --git a/app/components/chart/weekly.js b/app/components/chart/weekly.js index afc2866383..a3b990a659 100644 --- a/app/components/chart/weekly.js +++ b/app/components/chart/weekly.js @@ -20,6 +20,7 @@ var bows = require('bows'); var React = require('react'); var ReactDOM = require('react-dom'); var sundial = require('sundial'); +import { translate } from 'react-i18next'; // tideline dependencies & plugins var tidelineBlip = require('tideline/plugins/blip'); @@ -150,7 +151,7 @@ var WeeklyChart = React.createClass({ } }); -var Weekly = React.createClass({ +var Weekly = translate()(React.createClass({ chartType: 'weekly', log: bows('Weekly View'), propTypes: { @@ -297,8 +298,9 @@ var Weekly = React.createClass({ }, formatDate: function(datetime) { + const { t } = this.props; // even when timezoneAware, labels should be generated as if UTC; just trust me (JEB) - return sundial.formatInTimezone(datetime, 'UTC', 'MMM D, YYYY'); + return sundial.formatInTimezone(datetime, 'UTC', t('MMM D, YYYY')); }, getTitle: function(datetimeLocationEndpoints) { @@ -411,6 +413,6 @@ var Weekly = React.createClass({ } this.setState({showingValues: !this.state.showingValues}); } -}); +})); module.exports = Weekly; diff --git a/app/components/loginnav/loginnav.js b/app/components/loginnav/loginnav.js index abc334512b..56a03b6cd5 100644 --- a/app/components/loginnav/loginnav.js +++ b/app/components/loginnav/loginnav.js @@ -15,9 +15,10 @@ */ var React = require('react'); +import { translate } from 'react-i18next'; var Link = require('react-router').Link; -var LoginNav = React.createClass({ +var LoginNav = translate()(React.createClass({ propTypes: { page: React.PropTypes.string, hideLinks: React.PropTypes.bool, @@ -45,12 +46,13 @@ var LoginNav = React.createClass({ return null; } + var self = this; - var page = this.props.page; + const {page, t} = this.props; var href = '/signup'; var className = 'js-signup-link'; var icon = 'icon-add'; - var text = 'Sign up'; + var text = t('Sign up'); var handleClick = function() { self.props.trackMetric('Clicked Sign Up Link'); }; @@ -59,7 +61,7 @@ var LoginNav = React.createClass({ href = '/login'; className = 'js-login-link'; icon = 'icon-login'; - text = 'Log in'; + text = t('Log in'); handleClick = function() { self.props.trackMetric('Clicked Log In Link'); }; @@ -71,6 +73,6 @@ var LoginNav = React.createClass({ className={className}>{' ' + text} ); } -}); +})); -module.exports = LoginNav; \ No newline at end of file +module.exports = LoginNav; diff --git a/app/components/navbar/navbar.js b/app/components/navbar/navbar.js index 57260cecf3..825610c4f8 100644 --- a/app/components/navbar/navbar.js +++ b/app/components/navbar/navbar.js @@ -17,6 +17,7 @@ var React = require('react'); var IndexLink = require('react-router').IndexLink; var Link = require('react-router').Link; +import { translate } from 'react-i18next'; var _ = require('lodash'); var cx = require('classnames'); @@ -26,7 +27,7 @@ var NavbarPatientCard = require('../../components/navbarpatientcard'); var logoSrc = require('./images/tidepool-logo-408x46.png'); -var Navbar = React.createClass({ +export default translate('translation', {withRef: true})(React.createClass({ propTypes: { currentPage: React.PropTypes.string, user: React.PropTypes.object, @@ -128,7 +129,7 @@ var Navbar = React.createClass({ renderMenuSection: function() { var currentPage = (this.props.currentPage && this.props.currentPage[0] === '/') ? this.props.currentPage.slice(1) : this.props.currentPage; - var user = this.props.user; + const {user, t} = this.props; if (_.isEmpty(user)) { return
; @@ -180,7 +181,7 @@ var Navbar = React.createClass({