Adding support for internationalization

4.x.x
megala21 7 years ago
parent f441976c3d
commit 9a61cf87f5

@ -46,6 +46,7 @@
"mocha": "^3.4.1",
"mock-local-storage": "^1.0.2",
"node-sass": "^4.5.3",
"react-intl": "^2.4.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.1",
"webpack": "^2.7.0"

@ -0,0 +1,43 @@
{
"Title" : "Title",
"Description" : "Description",
"Category" : "Category",
"Visibility" : "Visibility",
"Devices" : "Devices",
"Roles" : "Roles",
"Groups" : "Groups",
"Tags" : "Tags",
"Platform" : "Platform",
"Platforms" : "Platfomrs",
"No.Platform" : "No Platforms",
"Screenshots" : "Screenshots",
"Icon" : "Icon",
"Banner" : "Banner",
"Create.Application" : "Create Application",
"Back" : "Back",
"Cancel" : "Cancel",
"Finish" : "Finish",
"Continue" : "Continue",
"Application.Name" : "Application Name",
"General" : "General",
"App.Releases" : "Application Releases",
"Package.Manager" : "Package Manager",
"Save" : "Save",
"Create.Release" : "Create Release",
"Release" : "Release",
"New.Release.For" : "New Release for",
"Upload.Package.File" : "Upload Package File",
"Upload" : "Upload",
"Select.from.package.library" : "Select from package library",
"Release.Name" : "Release Name",
"Release.Notes" : "Release Notes",
"Send.for.Review" : "Send for Review",
"Production.Releases" : "Production Releases",
"Beta.Releases" : "Beta Releases",
"Alpha.Releases" : "Alpha Releases",
"Version" : "Version",
"Status" : "Status",
"App.Publisher" : "Application Publisher"
}

@ -43,5 +43,13 @@ export default class Constants {
REFRESH_TOKEN_URL: "",
WSO2_USER: 'wso2_user',
PARTIAL_TOKEN: 'WSO2_IOT_TOKEN'
};
static hostConstants = {
baseURL : window.location.origin,
appContext : window.location.pathname.split("/")[1]
}
static defaultLocale = "en";
}

@ -23,6 +23,7 @@ import AuthHandler from "../../api/authHandler";
import ApplicationCreate from '../Application/Create/ApplicationCreate';
import {Col, Container, Input, Row,} from 'reactstrap';
import FloatingButton from "../UIComponents/FloatingButton/FloatingButton";
import {FormattedMessage} from 'react-intl';
/**
* Base Layout:
@ -75,7 +76,7 @@ class BaseLayout extends Component {
<div id="header-content">
<div id="header">
<span id="header-text">
WSO2 IoT App Publisher
WSO2 IoT <FormattedMessage id="App.Publisher" defaultMessage="Application Publisher"/>
</span>
<div id="header-btn-container">
<i className="fw fw-notification btn-header"></i>

@ -21,6 +21,7 @@ import {withRouter} from 'react-router-dom';
import {Button, Col, Row, Table} from 'reactstrap';
import Drawer from '../UIComponents/Drawer/Drawer';
import ApplicationView from './View/ApplicationView';
import {FormattedMessage} from 'react-intl';
/**
* The App Create Component.
@ -242,7 +243,9 @@ class ApplicationListing extends Component {
<Row>
<Col xs="3 offset-9">
<div className="platform-link-placeholder">
<Button><i className="fw fw-settings"></i> Platforms</Button>
<Button><i className="fw fw-settings"></i>
<FormattedMessage id="Platforms" defaultMessage="Platforms"/>
</Button>
</div>
</Col>
</Row>
@ -255,11 +258,12 @@ class ApplicationListing extends Component {
{/* TODO: Remove console.log and add sort method. */}
<th onClick={() => {
console.log("sort")
}}>Application Name
}}>
<FormattedMessage id="Application.Name" defaultMessage="Application Name"/>
</th>
<th>Category</th>
<th>Platform</th>
<th>Status</th>
<th><FormattedMessage id="Category" defaultMessage="Category"/></th>
<th><FormattedMessage id="Platform" defaultMessage="Platform"/></th>
<th><FormattedMessage id="Status" defaultMessage="Status"/></th>
<th></th>
</tr>
</thead>

@ -22,6 +22,7 @@ import AuthHandler from "../../../api/authHandler";
import {Step1, Step2, Step3, Step4} from './CreateSteps/index';
import ApplicationMgtApi from '../../../api/applicationMgtApi';
import {Button, Col, Modal, ModalBody, ModalFooter, ModalHeader, Row} from 'reactstrap';
import {FormattedMessage} from 'react-intl';
/**
* The App Create Component.
@ -210,7 +211,9 @@ class ApplicationCreate extends Component {
<div id="create-application-modal">
<Modal isOpen={this.state.open} toggle={this.toggle} id="app-create-modal"
backdrop={'static'}>
<ModalHeader toggle={this.toggle}>Create Application</ModalHeader>
<ModalHeader toggle={this.toggle}>
<FormattedMessage id="Create.Application" defaultMessage="Create Application"/>
</ModalHeader>
<ModalBody id="modal-body-content">
<Row>
<Col>
@ -227,11 +230,19 @@ class ApplicationCreate extends Component {
</ModalBody>
<ModalFooter>
{stepIndex === 0 ? <div/> :
<Button color="primary" onClick={this.onPrevClick}>Back</Button>}
<Button color="secondary" onClick={this.onClose}>Cancel</Button>
<Button color="primary" onClick={this.onPrevClick}>
<FormattedMessage id="Back" defaultMessage="Back"/>
</Button>}
<Button color="secondary" onClick={this.onClose}>
<FormattedMessage id="Cancel" defaultMessage="Cancel"/>
</Button>
{finished ?
<Button color="primary" onClick={this.onSubmit}>Finish</Button> :
<Button color="primary" onClick={this.onNextClick}>Continue</Button>}
<Button color="primary" onClick={this.onSubmit}>
<FormattedMessage id="Finish" defaultMessage="Finish" />
</Button> :
<Button color="primary" onClick={this.onNextClick}>
<FormattedMessage id="Continue" defaultMessage="Continue"/>
</Button>}
</ModalFooter>
</Modal>
</div>);

@ -19,6 +19,7 @@
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Badge, FormGroup, Input, Label} from 'reactstrap';
import {FormattedMessage} from 'react-intl';
/**
* The Second step of application create wizard.
@ -131,47 +132,37 @@ class Step1 extends Component {
<div>
<div>
<FormGroup>
<Label for="app-title">Title*</Label>
<Input
required
type="text"
name="appName"
id="app-title"
/>
<Label for="app-title">
<FormattedMessage id='Title' defaultMessage='Title'/>*
</Label>
<Input required type="text" name="appName" id="app-title"/>
</FormGroup>
<FormGroup>
<Label for="app-description">Description*</Label>
<Input
required
type="textarea"
name="appDescription"
id="app-description"
/>
<Label for="app-description">
<FormattedMessage id='Description' defaultMessage='Description'/>*
</Label>
<Input required type="textarea" name="appDescription" id="app-description"/>
</FormGroup>
<FormGroup>
<Label for="app-category">Category</Label>
<Input
type="select"
name="category"
id="app-category"
>
<Label for="app-category">
<FormattedMessage id='Category' defaultMessage='Category'/>
</Label>
<Input type="select" name="category" id="app-category">
<option>Business</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="app-visibility">Visibility</Label>
<Input
type="select"
name="visibility"
id="app-visibility"
>
<option>Devices</option>
<option>Roles</option>
<option>Groups</option>
<Label for="app-visibility">
<FormattedMessage id='Visibility' defaultMessage='Visibility'/>
</Label>
<Input type="select" name="visibility" id="app-visibility">
<option><FormattedMessage id='Devices' defaultMessage='Devices'/></option>
<option><FormattedMessage id='Roles' defaultMessage='Roles'/></option>
<option><FormattedMessage id='Groups' defaultMessage='Groups'/></option>
</Input>
</FormGroup>
<FormGroup>
<Label for="app-tags">Tags*</Label>
<Label for="app-tags"><FormattedMessage id='Tags' defaultMessage='Tags'/>*</Label>
<Input
required
type="text"

@ -21,6 +21,7 @@ import React, {Component} from 'react';
import AuthHandler from "../../../../api/authHandler";
import PlatformMgtApi from "../../../../api/platformMgtApi";
import {FormGroup, Input, Label} from 'reactstrap';
import {FormattedMessage} from 'react-intl';
/**
* The first step of the application creation wizard.
@ -114,30 +115,21 @@ class Step2 extends Component {
<FormGroup>
<Label for="store">Store Type</Label>
<Input
type="select"
name="store"
className="input-custom"
onChange={this.onChangeStore.bind(this)}
>
<Input type="select" name="store" className="input-custom" onChange={this.onChangeStore.bind(this)}>
<option>Enterprise</option>
<option>Public</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="store">Platform</Label>
<Input
type="select"
name="store"
onChange={this.onChangePlatform.bind(this)}
>
<Label for="store"><FormattedMessage id='Platform' defaultMessage='Platform'/></Label>
<Input type="select" name="store" onChange={this.onChangePlatform.bind(this)}>
{this.state.platforms.length > 0 ? this.state.platforms.map(platform => {
return (
<option value={platform.identifier}>
{platform.name}
</option>
)
}) : <option>No Platforms</option>}
}) : <option><FormattedMessage id='No.Platform' defaultMessage='No Platforms'/></option>}
</Input>
</FormGroup>
</div>

@ -17,13 +17,11 @@
*/
import PropTypes from 'prop-types';
import Chip from 'material-ui/Chip';
import Dropzone from 'react-dropzone';
import React, {Component} from 'react';
import MenuItem from 'material-ui/MenuItem';
import SelectField from 'material-ui/SelectField';
import {FormGroup, Label} from 'reactstrap';
import AppImage from "../../../UIComponents/AppImage/AppImage";
import {FormattedMessage} from 'react-intl';
/**
* The Third step of application create wizard.
@ -111,7 +109,9 @@ class Step3 extends Component {
<div className="createStep2Content">
<div>
<FormGroup>
<Label for="app-screenshots">Screenshots*</Label>
<Label for="app-screenshots">
<FormattedMessage id='Screenshots' defaultMessage='Screenshots'/>*
</Label>
<span className="image-sub-title"> (600 X 800 32 bit PNG)</span>
<div id="screenshot-container">
{this.state.screenshots.map((tile) => (
@ -140,7 +140,9 @@ class Step3 extends Component {
<div style={{display: 'flex'}}>
<div style={{float: 'left', marginRight: '15px'}}>
<FormGroup>
<Label for="app-icon">Icon*</Label>
<Label for="app-icon">
<FormattedMessage id='Screenshots' defaultMessage='Screenshots'/>*
</Label>
<span className="image-sub-title"> (512 X 512 32 bit PNG)</span>
<div id="app-icon-container">
{this.state.icon.map((tile) => (
@ -164,7 +166,9 @@ class Step3 extends Component {
</div>
<div style={{marginLeft: '15px'}}>
<FormGroup>
<Label for="app-banner">Banner*</Label>
<Label for="app-banner">
<FormattedMessage id='Icon' defaultMessage='Icon'/>*
</Label>
<span className="image-sub-title"> (1000 X 400 32 bit PNG)</span>
<div id="app-banner-container">
{this.state.banner.map((tile) => (

@ -20,6 +20,7 @@ import {Col, Row} from "reactstrap";
import React, {Component} from 'react';
import GeneralInfo from "../GenenralInfo/GeneralInfo";
import ReleaseManager from '../../Release/ReleaseMgtBase/ReleaseManager';
import {FormattedMessage} from 'react-intl';
class ApplicationEdit extends Component {
@ -85,21 +86,20 @@ class ApplicationEdit extends Component {
</a>
</Col>
<Col>
Application Name
<FormattedMessage id="Application.Name" defaultMessage="Application Name"/>
</Col>
</Row>
<Row id="application-edit-main-container">
<Col xs="3">
<div className="tab">
<button className={this.state.general} value={1} onClick={this.handleTabClick.bind(this)}>
General
<FormattedMessage id="General" defaultMessage="General"/>
</button>
<button className={this.state.release} value={2} onClick={this.handleTabClick.bind(this)}>
App
Releases
<FormattedMessage id="App.Releases" defaultMessage="Application Releases"/>
</button>
<button className={this.state.pkgmgt} value={3} onClick={this.handleTabClick.bind(this)}>
Package Manager
<FormattedMessage id="Package.Manager" defaultMessage="Package Manager"/>
</button>
</div>
</Col>

@ -19,6 +19,7 @@
import React, {Component} from 'react';
import {Badge, Button, FormGroup, Input, Label, Row} from 'reactstrap';
import Dropzone from 'react-dropzone';
import {FormattedMessage} from 'react-intl';
class GeneralInfo extends Component {
@ -40,7 +41,9 @@ class GeneralInfo extends Component {
<Row>
<form>
<FormGroup>
<Label for="app-title">Title*</Label>
<Label for="app-title">
<FormattedMessage id="Title" defaultMessage="Title"/>*
</Label>
<Input
required
type="text"
@ -49,46 +52,34 @@ class GeneralInfo extends Component {
/>
</FormGroup>
<FormGroup>
<Label for="app-title">Description*</Label>
<Input
required
type="textarea"
multiline
name="appName"
id="app-title"
/>
<Label for="app-title">
<FormattedMessage id="Description" defaultMessage="Description"/>*
</Label>
<Input required type="textarea" multiline name="appName" id="app-title"/>
</FormGroup>
<FormGroup>
<Label for="app-category">Category</Label>
<Input
type="select"
name="category"
id="app-category"
>
<Label for="app-category">
<FormattedMessage id="Category" defaultMessage="Category"/>
</Label>
<Input type="select" name="category" id="app-category">
<option>Business</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="app-visibility">Visibility</Label>
<Input
type="select"
name="visibility"
id="app-visibility"
>
<option>Devices</option>
<option>Roles</option>
<option>Groups</option>
<Label for="app-visibility">
<FormattedMessage id="Visibility" defaultMessage="Visibility"/>
</Label>
<Input type="select" name="visibility" id="app-visibility">
<option><FormattedMessage id="Devices" defaultMessage="Devices"/></option>
<option><FormattedMessage id="Roles" defaultMessage="Roles"/></option>
<option><FormattedMessage id="Groups" defaultMessage="Groups"/></option>
</Input>
</FormGroup>
<FormGroup>
<Label for="app-tags">Tags*</Label>
<Input
required
type="text"
value={this.state.defValue}
name="app-tags"
id="app-tags"
/>
<Label for="app-tags">
<FormattedMessage id="Tags" defaultMessage="Tags"/>*
</Label>
<Input required type="text" value={this.state.defValue} name="app-tags" id="app-tags"/>
<div id="batch-content">
{this.state.tags.map(tag => {
return (
@ -105,7 +96,9 @@ class GeneralInfo extends Component {
</FormGroup>
<div>
<FormGroup>
<Label for="app-screenshots">Screenshots*</Label>
<Label for="app-screenshots">
<FormattedMessage id="Screenshots" defaultMessage="Screenshots"/>*
</Label>
<span className="image-sub-title"> (600 X 800 32 bit PNG)</span>
<div id="screenshot-container">
{this.state.screenshots.map((tile) => (
@ -138,7 +131,9 @@ class GeneralInfo extends Component {
<div style={{display: 'flex'}}>
<div style={{float: 'left', marginRight: '15px'}}>
<FormGroup>
<Label for="app-icon">Icon*</Label>
<Label for="app-icon">
<FormattedMessage id="Icon" defaultMessage="Icon"/>*
</Label>
<span className="image-sub-title"> (512 X 512 32 bit PNG)</span>
<div id="app-icon-container">
{this.state.icon.map((tile) => (
@ -163,7 +158,9 @@ class GeneralInfo extends Component {
</div>
<div style={{marginLeft: '15px'}}>
<FormGroup>
<Label for="app-banner">Banner*</Label>
<Label for="app-banner">
<FormattedMessage id="Banner" defaultMessage="Banner"/>*
</Label>
<span className="image-sub-title"> (1000 X 400 32 bit PNG)</span>
<div id="app-banner-container">
{this.state.banner.map((tile) => (
@ -189,7 +186,9 @@ class GeneralInfo extends Component {
</div>
</div>
<div className="save-info">
<Button>Save</Button>
<Button>
<FormattedMessage id="Save" defaultMessage="Save"/>
</Button>
</div>
</form>
</Row>

@ -20,6 +20,7 @@ import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Button, FormGroup, FormText, Input, Label, Row} from "reactstrap";
import UploadPackage from "./UploadPackage";
import {FormattedMessage} from 'react-intl';
class CreateRelease extends Component {
constructor() {
@ -74,7 +75,7 @@ class CreateRelease extends Component {
<div className="release-header">
<a onClick={this.onBackClick}>{"<-"}</a>
<span id="create-release-header">
<strong>{channel} Release</strong>
<strong>{channel} <FormattedMessage id="Release" defaultMessage="Release"/></strong>
</span>
</div>
</Row>
@ -82,7 +83,7 @@ class CreateRelease extends Component {
<div className="release-create">
<div>
<span>
<strong>Create Release</strong>
<strong><FormattedMessage id="Create.Release" defaultMessage="Create Release"/></strong>
</span>
<p>
{channel === 'Production' ? "" :
@ -148,7 +149,9 @@ class CreateRelease extends Component {
</FormText>
</FormGroup>
<div>
<Button className="form-btn">Save</Button>
<Button className="form-btn">
<FormattedMessage id="Save" defaultMessage="Save"/>
</Button>
</div>
</form>
</div>

@ -19,6 +19,7 @@
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Button, Col, FormGroup, Input, Label, Row} from "reactstrap";
import {FormattedMessage} from 'react-intl';
class UploadPackage extends Component {
@ -39,44 +40,53 @@ class UploadPackage extends Component {
<div className="release-header">
<a onClick={this.handleBack}>{"<-"}</a>
<span id="create-release-header">
<strong>New Release for {selectedChannel}</strong>
<strong>
<FormattedMessage id="New.Release.For" defaultMessage="New Release For"/> {selectedChannel}
</strong>
</span>
</div>
</Row>
<Row>
<div className="release-header">
<span id="create-release-header">
<strong>Upload Package File</strong>
<strong>
<FormattedMessage id="Upload.Package.File" defaultMessage="Upload Package File"/>
</strong>
</span>
</div>
</Row>
<Row>
<Col xs="3">
<Button>Upload</Button>
<Button>
<FormattedMessage id="Upload" defaultMessage="Upload"/>
</Button>
</Col>
<Col xs="3">
<Button>Select from package library</Button>
<Button>
<FormattedMessage id="Select.from.package.library"
defaultMessage="Select from package library"/>
</Button>
</Col>
</Row>
<Row>
<div className="release-detail-content">
<form>
<FormGroup>
<Label>Release Name *</Label>
<Input
required
type="text"
/>
<Label>
<FormattedMessage id="Release.Name" defaultMessage="Release Name"/> *
</Label>
<Input required type="text"/>
</FormGroup>
<FormGroup>
<Label>Release Notes *</Label>
<Input
required
type="textarea"
/>
<Label>
<FormattedMessage id="Release.Notes" defaultMessage="Release Notes"/> *
</Label>
<Input required type="textarea"/>
</FormGroup>
<div className="form-btn">
<Button>Send for Review</Button>
<Button>
<FormattedMessage id="Send.for.Review" defaultMessage="Send for Review"/>
</Button>
</div>
</form>
</div>

@ -16,10 +16,10 @@
* under the License.
*/
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Button, Col, Row} from "reactstrap";
import CreateRelease from "../Create/CreateRelease";
import {FormattedMessage} from 'react-intl';
class ReleaseManager extends Component {
@ -82,7 +82,7 @@ class ReleaseManager extends Component {
<Row>
<Col sm="12">
<div className="release" id="production">
<span>Production Releases</span>
<FormattedMessage id="Production.Releases" defaultMessage="Production Releases"/>
<div className="release-content">
<div className="release-inner">
{this.getNoReleaseContent("Production")}
@ -94,7 +94,7 @@ class ReleaseManager extends Component {
<Row>
<Col sm="12">
<div className="release" id="beta">
<span>Beta Releases</span>
<FormattedMessage id="Beta.Releases" defaultMessage="Beta Releases"/>
<div className="release-content">
<div className="release-inner">
{this.getNoReleaseContent("Beta")}
@ -106,7 +106,7 @@ class ReleaseManager extends Component {
<Row>
<Col sm="12">
<div className="release" id="alpha">
<span>Alpha Releases</span>
<FormattedMessage id="Alpha.Releases" defaultMessage="Alpha Releases"/>
<div className="release-content">
<div className="release-inner">
{this.getNoReleaseContent("Alpha")}

@ -19,6 +19,7 @@
import React, {Component} from 'react';
import {withRouter} from 'react-router-dom';
import {Col, Row} from "reactstrap";
import {FormattedMessage} from 'react-intl';
/**
* Application view component.
@ -90,7 +91,9 @@ class ApplicationView extends Component {
<div id="application-view-row">
<Row>
<Col>
<span><strong>Description: </strong></span>
<span><strong>
<FormattedMessage id="Description" defaultMessage="Description"/>:
</strong></span>
</Col>
<Col>
<p>sdfjlkdsjfsjdfjsdf sfjdslkjfdsflkjdsfslkdjfl j</p>
@ -98,7 +101,9 @@ class ApplicationView extends Component {
</Row>
<Row>
<Col>
<span><strong>Tags: </strong></span>
<span><strong>
<FormattedMessage id="Tags" defaultMessage="Tags"/>:
</strong></span>
</Col>
<Col>
<p>[list of tags...]</p>
@ -106,7 +111,9 @@ class ApplicationView extends Component {
</Row>
<Row>
<Col>
<span><strong>Release: </strong></span>
<span><strong>
<FormattedMessage id="Release" defaultMessage="Release"/>:
</strong></span>
</Col>
<Col>
<p>Production</p>
@ -114,7 +121,9 @@ class ApplicationView extends Component {
</Row>
<Row>
<Col>
<span><strong>Version: </strong></span>
<span><strong>
<FormattedMessage id="Version" defaultMessage="Version"/>:
</strong></span>
</Col>
<Col>
<p>v1.0</p>

@ -21,9 +21,37 @@ import Publisher from './App';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import registerServiceWorker from './registerServiceWorker';
import {IntlProvider, addLocaleData, defineMessages} from 'react-intl';
import Axios from 'axios';
import Constants from './common/constants';
const possibleLocale = navigator.language.split("-")[0];
let loadLocaleFile = Axios.create({
baseURL: Constants.hostConstants.baseURL + "/" + Constants.hostConstants.appContext + "/locales/"
+ possibleLocale + ".json"
}).get();
/**
* This is the base js file of the app. All the content will be rendered in the root element.
* */
ReactDOM.render(<Publisher/>, document.getElementById('root'));
registerServiceWorker();
loadLocaleFile.then(response => {
const messages = defineMessages(response.data);
addLocaleData(require('react-intl/locale-data/' + possibleLocale));
ReactDOM.render(<IntlProvider locale={possibleLocale}
messages={messages}><Publisher/></IntlProvider>, document.getElementById('root'));
registerServiceWorker();
}).catch(error => {
addLocaleData(require('react-intl/locale-data/' + Constants.defaultLocale));
let defaultLocale = axios.create({
baseURL: Constants.hostConstants.baseURL + "/" + Constants.hostConstants.appContext + "/locales"
+ Constants.defaultLocale + ".json"
}).get();
defaultLocale.then(response => {
const messages = defineMessages(response.data);
ReactDOM.render(<IntlProvider locale={possibleLocale}
messages={messages}><Publisher/></IntlProvider>, document.getElementById('root'));
registerServiceWorker();
}).catch(error => {
});
});

@ -64,7 +64,6 @@ const config = {
]
},
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['.jsx', '.js', '.ttf', '.woff', '.woff2', '.svg']
}

Loading…
Cancel
Save