Skip to content

Commit

Permalink
Add i18n library to Linkerd dashboard (#4803)
Browse files Browse the repository at this point in the history
This PR adds the LinguiJS project to the Linkerd dashboard for i18n and 
translation. It is a precursor to adding translations to the dashboard. Only 
two components have been translated in this PR, to allow reviewers to evaluate 
the ease of use; A second PR will add translations for the remaining components.
  • Loading branch information
Carol A. Scott authored Jul 30, 2020
1 parent 4ffea3b commit eec8905
Show file tree
Hide file tree
Showing 11 changed files with 907 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ tmp.discovery
**/node_modules
web/web
web/app/dist
web/app/js/locales/_build
web/app/js/locales/**/*.js
web/app/yarn-error.log
vendor
**/*.gogen*
Expand Down
2 changes: 1 addition & 1 deletion bin/web
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ dev() {

build() {
cd "$ROOT"/web/app
yarn webpack
yarn lingui compile && yarn webpack
}

get-pod() {
Expand Down
2 changes: 1 addition & 1 deletion web/app/.babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"plugins": ["@babel/plugin-proposal-class-properties"],
"plugins": ["@babel/plugin-proposal-class-properties", "macros"],
"env": {
"production": {
"plugins": ["transform-react-remove-prop-types"]
Expand Down
5 changes: 5 additions & 0 deletions web/app/.linguirc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"localeDir": "js/locales/",
"srcPathDirs": ["js/"],
"format": "minimal"
}
14 changes: 3 additions & 11 deletions web/app/js/components/EmptyCard.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import PropTypes from 'prop-types';
import React from 'react';
import { Trans } from '@lingui/macro';
import Typography from '@material-ui/core/Typography';
import { withStyles } from '@material-ui/core/styles';

Expand All @@ -12,24 +12,16 @@ const styles = () => ({
},
});

const EmptyCard = ({ content, classes }) => {
const EmptyCard = ({ classes }) => {
return (
<Card className={classes.card} elevation={3}>
<CardContent>
<Typography>
{content}
<Trans>No data to display</Trans>
</Typography>
</CardContent>
</Card>
);
};

EmptyCard.propTypes = {
content: PropTypes.string,
};

EmptyCard.defaultProps = {
content: 'No data to display',
};

export default withStyles(styles)(EmptyCard);
27 changes: 12 additions & 15 deletions web/app/js/components/util/CopyUtils.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import React from 'react';
import { Trans } from '@lingui/macro';
import Typography from '@material-ui/core/Typography';

/*
* Instructions for adding resources to service mesh
*/
export const incompleteMeshMessage = name => {
if (name) {
return (
<Typography variant="body2">
Add {name} to the k8s.yml file<br /><br />
Then run <code>linkerd inject k8s.yml | kubectl apply -f -</code> to add it to the service mesh
</Typography>
);
} else {
return (
<Typography variant="body2">
Add one or more resources to the k8s.yml file<br /><br />
Then run <code>linkerd inject k8s.yml | kubectl apply -f -</code> to add them to the service mesh
</Typography>
);
}
const unspecifiedResources = <Trans>one or more resources</Trans>;
const inject = <code>linkerd inject k8s.yml | kubectl apply -f -</code>;

return (
<Typography variant="body2">
<Trans>
Add {name || unspecifiedResources } to the k8s.yml file<br /><br />
Then run {inject} to add it to the service mesh
</Trans>
</Typography>
);
};
21 changes: 20 additions & 1 deletion web/app/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import '../css/styles.css';
import '../img/favicon.png'; // needs to be referenced somewhere so webpack bundles it

import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom';
import { DETECTORS, LocaleResolver, TRANSFORMERS } from 'locales-detector';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';

import ApiHelpers from './components/util/ApiHelpers.jsx';
import AppContext from './components/util/AppContext.jsx';
import Community from './components/Community.jsx';
import CssBaseline from '@material-ui/core/CssBaseline';
import Gateway from './components/Gateway.jsx';
import { I18nProvider } from '@lingui/react';
import Namespace from './components/Namespace.jsx';
import Navigation from './components/Navigation.jsx';
import NoMatch from './components/NoMatch.jsx';
Expand All @@ -21,6 +23,10 @@ import ServiceMesh from './components/ServiceMesh.jsx';
import Tap from './components/Tap.jsx';
import Top from './components/Top.jsx';
import TopRoutes from './components/TopRoutes.jsx';
import _find from 'lodash/find';
import _isEmpty from 'lodash/isEmpty';
import catalogEn from './locales/en/messages.js';
import catalogEs from './locales/es/messages.js';
import { dashboardTheme } from './components/util/theme.js';

const appMain = document.getElementById('main');
Expand All @@ -45,6 +51,15 @@ if (pathArray[0] === '' && pathArray[1] === 'namespaces' && pathArray[2]) {
defaultNamespace = '_all';
}

const detectedLocales = new LocaleResolver(
[new DETECTORS.NavigatorDetector()],
[new TRANSFORMERS.FallbacksTransformer()],
).getLocales();
const catalogOptions = { en: catalogEn, es: catalogEs };
const selectedLocale =
_find(detectedLocales, l => !_isEmpty(catalogOptions[l])) || 'en';
const selectedCatalog = catalogOptions[selectedLocale] || catalogEn;

class App extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -74,7 +89,11 @@ class App extends React.Component {
render() {
return (
<AppContext.Provider value={this.state}>
<AppHTML />
<I18nProvider
language={selectedLocale}
catalogs={{ [selectedLocale]: selectedCatalog }}>
<AppHTML />
</I18nProvider>
</AppContext.Provider>
);
}
Expand Down
5 changes: 5 additions & 0 deletions web/app/js/locales/en/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Add {0} to the k8s.yml file<0/><1/>Then run {inject} to add it to the service mesh": "Add {0} to the k8s.yml file<0/><1/>Then run {inject} to add it to the service mesh",
"No data to display": "No data to display",
"one or more resources": "one or more resources"
}
5 changes: 5 additions & 0 deletions web/app/js/locales/es/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Add {0} to the k8s.yml file<0/><1/>Then run {inject} to add it to the service mesh": "Agregue {0} a la k8s.yml file<0/><1/>Luego ejecuta {inject} para inyectarla en la malla de servicios",
"No data to display": "No hay datos que mostrar",
"one or more resources": "uno más recursos más"
}
8 changes: 7 additions & 1 deletion web/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"@fortawesome/free-regular-svg-icons": "5.13.0",
"@fortawesome/free-solid-svg-icons": "5.13.0",
"@fortawesome/react-fontawesome": "0.1.9",
"@lingui/macro": "2.9.1",
"@lingui/react": "2.9.1",
"@material-ui/core": "4.9.11",
"@material-ui/icons": "4.9.1",
"@material-ui/lab": "^4.0.0-alpha.50",
Expand All @@ -18,6 +20,7 @@
"d3-format": "1.4.4",
"d3-selection": "1.4.1",
"date-fns": "2.12.0",
"locales-detector": "2.26.0",
"lodash": "4.17.19",
"path": "0.12.7",
"prop-types": "15.7.2",
Expand All @@ -33,19 +36,22 @@
"whatwg-fetch": "3.0.0"
},
"devDependencies": {
"@babel/core": "7.9.0",
"@babel/core": "7.10.5",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/preset-env": "7.9.5",
"@babel/preset-react": "7.9.4",
"@babel/runtime": "7.9.2",
"@lingui/cli": "2.9.1",
"@wdio/cli": "6.1.2",
"@wdio/local-runner": "6.1.2",
"@wdio/mocha-framework": "6.1.0",
"@wdio/sync": "6.1.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "10.1.0",
"babel-jest": "25.4.0",
"babel-loader": "8.1.0",
"babel-plugin-import": "1.13.0",
"babel-plugin-macros": "2.8.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"chai": "4.2.0",
"chai-webdriverio": "1.0.0",
Expand Down
Loading

0 comments on commit eec8905

Please sign in to comment.