mirror of https://github.com/linkerd/linkerd2.git
Add i18n library to Linkerd dashboard (#4803)
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.
This commit is contained in:
parent
4ffea3ba08
commit
eec8905660
|
@ -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*
|
||||
|
|
2
bin/web
2
bin/web
|
@ -55,7 +55,7 @@ dev() {
|
|||
|
||||
build() {
|
||||
cd "$ROOT"/web/app
|
||||
yarn webpack
|
||||
yarn lingui compile && yarn webpack
|
||||
}
|
||||
|
||||
get-pod() {
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"localeDir": "js/locales/",
|
||||
"srcPathDirs": ["js/"],
|
||||
"format": "minimal"
|
||||
}
|
|
@ -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';
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
@ -9,6 +10,7 @@ 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';
|
||||
|
@ -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');
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -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,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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue