Added langauge localization files to use masterdata and futureproof translations.
This commit is contained in:
@@ -1,59 +1,58 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Icon, Button, Input, AutoComplete } from "antd";
|
// import { Icon, Button, Input, AutoComplete } from "antd";
|
||||||
|
|
||||||
const { Option } = AutoComplete;
|
// const { Option } = AutoComplete;
|
||||||
|
|
||||||
function onSelect(value) {
|
// function onSelect(value) {
|
||||||
console.log("onSelect", value);
|
// console.log("onSelect", value);
|
||||||
}
|
// }
|
||||||
|
|
||||||
function getRandomInt(max, min = 0) {
|
// function getRandomInt(max, min = 0) {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
|
// return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
|
||||||
}
|
// }
|
||||||
|
|
||||||
function searchResult(query) {
|
// function searchResult(query) {
|
||||||
return new Array(getRandomInt(5))
|
// return new Array(getRandomInt(5))
|
||||||
.join(".")
|
// .join(".")
|
||||||
.split(".")
|
// .split(".")
|
||||||
.map((item, idx) => ({
|
// .map((item, idx) => ({
|
||||||
query,
|
// query,
|
||||||
category: `${query}${idx}`,
|
// category: `${query}${idx}`,
|
||||||
count: getRandomInt(200, 100)
|
// count: getRandomInt(200, 100)
|
||||||
}));
|
// }));
|
||||||
}
|
// }
|
||||||
|
|
||||||
function renderOption(item) {
|
// function renderOption(item) {
|
||||||
return (
|
// return (
|
||||||
<Option key={item.category} text={item.category}>
|
// <Option key={item.category} text={item.category}>
|
||||||
<div className='global-search-item'>
|
// <div className='global-search-item'>
|
||||||
<span className='global-search-item-desc'>
|
// <span className='global-search-item-desc'>
|
||||||
Found {item.query} on
|
// Found {item.query} on
|
||||||
<a
|
// <a
|
||||||
href={`https://s.taobao.com/search?q=${item.query}`}
|
// href={`https://s.taobao.com/search?q=${item.query}`}
|
||||||
target='_blank'
|
// target='_blank'
|
||||||
rel='noopener noreferrer'>
|
// rel='noopener noreferrer'>
|
||||||
{item.category}
|
// {item.category}
|
||||||
</a>
|
// </a>
|
||||||
</span>
|
// </span>
|
||||||
<span className='global-search-item-count'>{item.count} results</span>
|
// <span className='global-search-item-count'>{item.count} results</span>
|
||||||
</div>
|
// </div>
|
||||||
</Option>
|
// </Option>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default class GlobalSearch extends React.Component {
|
export default class GlobalSearch extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
dataSource: []
|
dataSource: []
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSearch = value => {
|
// handleSearch = value => {
|
||||||
this.setState({
|
// this.setState({
|
||||||
dataSource: value ? searchResult(value) : []
|
// dataSource: value ? searchResult(value) : []
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dataSource } = this.state;
|
|
||||||
return (
|
return (
|
||||||
<div />
|
<div />
|
||||||
// <div style={{ width: 300 }}>
|
// <div style={{ width: 300 }}>
|
||||||
|
|||||||
@@ -1,27 +1,28 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { useApolloClient } from "@apollo/react-hooks";
|
||||||
import { Menu, Icon } from "antd";
|
import { Menu, Icon } from "antd";
|
||||||
import "./header.styles.scss";
|
import "./header.styles.scss";
|
||||||
|
|
||||||
import SignOut from "../sign-out/sign-out.component";
|
import SignOut from "../sign-out/sign-out.component";
|
||||||
import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component";
|
import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component";
|
||||||
import { useApolloClient } from "@apollo/react-hooks";
|
|
||||||
import GlobalSearch from "../global-search/global-search.component";
|
import GlobalSearch from "../global-search/global-search.component";
|
||||||
|
import LanguageSelector from "../language-selector/langauge-selector.component";
|
||||||
|
|
||||||
export default ({ landingHeader, navItems, selectedNavItem }) => {
|
export default ({ landingHeader, navItems, selectedNavItem }) => {
|
||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
|
|
||||||
const handleClick = e => {
|
const handleClick = e => {
|
||||||
apolloClient.writeData({ data: { selectedNavItem: e.key } });
|
apolloClient.writeData({ data: { selectedNavItem: e.key } });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
theme="dark"
|
theme='dark'
|
||||||
className="header"
|
className='header'
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
selectedKeys={selectedNavItem}
|
selectedKeys={selectedNavItem}
|
||||||
mode="horizontal"
|
mode='horizontal'>
|
||||||
>
|
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<GlobalSearch />
|
<GlobalSearch />
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
@@ -43,6 +44,8 @@ export default ({ landingHeader, navItems, selectedNavItem }) => {
|
|||||||
<ManageSignInButton />
|
<ManageSignInButton />
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{!landingHeader ? <LanguageSelector /> : null}
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { Dropdown, Menu, Icon } from "antd";
|
||||||
|
|
||||||
|
export default function LanguageSelector() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const handleMenuClick = e => {
|
||||||
|
console.log("e", e);
|
||||||
|
|
||||||
|
i18next.changeLanguage(e.key, (err, t) => {
|
||||||
|
if (err)
|
||||||
|
return console.log("Error encountered when changing languages.", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const menu = (
|
||||||
|
<Menu onClick={handleMenuClick}>
|
||||||
|
<Menu.Item key='en_us'>{t("general.languages.english")}</Menu.Item>
|
||||||
|
<Menu.Item key='fr'>{t("general.languages.french")}</Menu.Item>
|
||||||
|
<Menu.Item key='es'>{t("general.languages.spanish")}</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Dropdown overlay={menu}>
|
||||||
|
<Icon type='global' />
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Menu, Dropdown, Card, Icon, Avatar, Button } from "antd";
|
import { Menu, Dropdown, Card, Icon, Avatar } from "antd";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
export default function WhiteBoardCard({ metadata }) {
|
export default function WhiteBoardCard({ metadata }) {
|
||||||
// const {
|
// const {
|
||||||
// onClick,
|
// onClick,
|
||||||
@@ -18,31 +18,33 @@ export default function WhiteBoardCard({ metadata }) {
|
|||||||
// showDeleteButton,
|
// showDeleteButton,
|
||||||
// onDelete
|
// onDelete
|
||||||
// } = this.props;
|
// } = this.props;
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const menu = (
|
const menu = (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item key='images'>
|
<Menu.Item key='images'>
|
||||||
<Icon type='file-image' />
|
<Icon type='file-image' />
|
||||||
View Job Images
|
{t("whiteboard.viewJobImages")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='printing'>
|
<Menu.Item key='printing'>
|
||||||
<Icon type='printer' />
|
<Icon type='printer' />
|
||||||
Printing
|
{t("whiteboard.printCenter")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='notes'>
|
<Menu.Item key='notes'>
|
||||||
<Icon type='edit' />
|
<Icon type='edit' />
|
||||||
Job Notes
|
{t("whiteboard.notes")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='postinvoices'>
|
<Menu.Item key='postinvoices'>
|
||||||
<Icon type='shopping-cart' />
|
<Icon type='shopping-cart' />
|
||||||
Post Invoices
|
{t("whiteboard.postInvoices")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='receiveparts'>
|
<Menu.Item key='receiveparts'>
|
||||||
<Icon type='inbox' />
|
<Icon type='inbox' />
|
||||||
Receive Parts
|
{t("whiteboard.receiveParts")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='partstatus'>
|
<Menu.Item key='partstatus'>
|
||||||
<Icon type='tool' />
|
<Icon type='tool' />
|
||||||
Parts Status
|
{t("whiteboard.partStatus")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
import "./translations/i18n";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
|
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useSubscription } from "@apollo/react-hooks";
|
import { useSubscription } from "@apollo/react-hooks";
|
||||||
import AlertComponent from "../../components/alert/alert.component";
|
import AlertComponent from "../../components/alert/alert.component";
|
||||||
import { Col } from "antd";
|
import { Col } from "antd";
|
||||||
@@ -10,10 +10,10 @@ export default function JobsPage() {
|
|||||||
const { loading, error, data } = useSubscription(SUBSCRIPTION_ALL_OPEN_JOBS, {
|
const { loading, error, data } = useSubscription(SUBSCRIPTION_ALL_OPEN_JOBS, {
|
||||||
fetchPolicy: "network-only"
|
fetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = "new title"
|
document.title = "new title";
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (error) return <AlertComponent message={error.message} />;
|
if (error) return <AlertComponent message={error.message} />;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"welcome": {
|
|
||||||
"title": "Welcome to {{framework}}",
|
|
||||||
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
22
client/src/translations/en_us/common.json
Normal file
22
client/src/translations/en_us/common.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"translation": {
|
||||||
|
"general": {
|
||||||
|
"languages": {
|
||||||
|
"english": "English",
|
||||||
|
"french": "French",
|
||||||
|
"spanish": "Spanish"
|
||||||
|
},
|
||||||
|
"title": "Welcome to {{framework}}",
|
||||||
|
"greetings": "Hello2!",
|
||||||
|
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
||||||
|
},
|
||||||
|
"whiteboard": {
|
||||||
|
"viewJobImages": "View Job Images",
|
||||||
|
"printCenter": "Print Center",
|
||||||
|
"postInvoices": "Post Invoices",
|
||||||
|
"notes": "Job Notes",
|
||||||
|
"partStatus": "Part Status",
|
||||||
|
"receiveParts": "Receive Parts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"welcome": {
|
"translation": {
|
||||||
"title": "Welcome to {{framework}}",
|
"general": {
|
||||||
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
"title": "Hola a {{framework}}",
|
||||||
|
"greetings": "Hola!",
|
||||||
|
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,22 @@
|
|||||||
{
|
{
|
||||||
"welcome": {
|
"translation": {
|
||||||
|
"general": {
|
||||||
|
"languages": {
|
||||||
|
"english": "Anglais",
|
||||||
|
"french": "Francais",
|
||||||
|
"spanish": "Espanol"
|
||||||
|
},
|
||||||
"title": "Welcome to {{framework}}",
|
"title": "Welcome to {{framework}}",
|
||||||
|
"greetings": "Hello2!",
|
||||||
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
"intro": "To get started, edit <1><0></0></1> and save to reload."
|
||||||
|
},
|
||||||
|
"whiteboard": {
|
||||||
|
"viewJobImages": "Viewez le Job Images",
|
||||||
|
"printCenter": "Printez Centre",
|
||||||
|
"postInvoices": "Postez le Invoices",
|
||||||
|
"notes": "Le Job Notes",
|
||||||
|
"partStatus": "Status de Parts",
|
||||||
|
"receiveParts": "Receive Parts"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
client/src/translations/i18n.js
Normal file
29
client/src/translations/i18n.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import i18n from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import en_Translation from "./en_us/common.json";
|
||||||
|
import fr_Translation from "./fr/common.json";
|
||||||
|
import es_Translation from "./es/common.json";
|
||||||
|
|
||||||
|
// the translations
|
||||||
|
// (tip move them in a JSON file and import them)
|
||||||
|
const resources = {
|
||||||
|
en_us: en_Translation,
|
||||||
|
fr: fr_Translation,
|
||||||
|
es: es_Translation
|
||||||
|
};
|
||||||
|
i18n
|
||||||
|
.use(initReactI18next) // passes i18n down to react-i18next
|
||||||
|
.init({
|
||||||
|
resources,
|
||||||
|
lng: "en_us",
|
||||||
|
fallbackLng: "en-us",
|
||||||
|
debug: true,
|
||||||
|
|
||||||
|
//keySeparator: false, // we do not use keys in form messages.welcome
|
||||||
|
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false // react already safes from xss
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
Reference in New Issue
Block a user