Added translation and utils scripts
parent
5be2561abb
commit
0586f20d52
|
@ -3493,6 +3493,37 @@
|
||||||
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz",
|
||||||
"integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ=="
|
"integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ=="
|
||||||
},
|
},
|
||||||
|
"axios": {
|
||||||
|
"version": "0.19.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||||
|
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||||
|
"requires": {
|
||||||
|
"follow-redirects": "1.5.10"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"follow-redirects": {
|
||||||
|
"version": "1.5.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||||
|
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "=3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"axobject-query": {
|
"axobject-query": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
|
||||||
|
@ -4904,6 +4935,21 @@
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cross-fetch": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "6.0.5",
|
"version": "6.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||||
|
@ -7799,6 +7845,14 @@
|
||||||
"terser": "^4.6.3"
|
"terser": "^4.6.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"html-parse-stringify": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
|
||||||
|
"requires": {
|
||||||
|
"void-elements": "3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"html-webpack-plugin": {
|
"html-webpack-plugin": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz",
|
||||||
|
@ -8058,6 +8112,30 @@
|
||||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||||
},
|
},
|
||||||
|
"i18next": {
|
||||||
|
"version": "19.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-19.9.2.tgz",
|
||||||
|
"integrity": "sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-browser-languagedetector": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-KIToAzf8zwWvacgnRwJp63ase26o24AuNUlfNVJ5YZAFmdGhsJpmFClxXPuk9rv1FMI4lnc8zLSqgZPEZMrW4g==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-http-backend": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-NeNNRofj+rR6Cw+/Elf8bCVaCiqWg2Y6F+CrmDvHiPzAW2Dtxxlk8O0na2et/rr1n3ST6rJr4nMXH/QOFuhaeA==",
|
||||||
|
"requires": {
|
||||||
|
"cross-fetch": "3.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.6.2",
|
"version": "0.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
||||||
|
@ -10915,6 +10993,11 @@
|
||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||||
|
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
@ -13321,6 +13404,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
||||||
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
|
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
|
||||||
},
|
},
|
||||||
|
"react-flags": {
|
||||||
|
"version": "0.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-flags/-/react-flags-0.1.18.tgz",
|
||||||
|
"integrity": "sha512-fa8D6DIZS6DWRqLcmKGIHVT13r4viHAfIRth9cFO7cDyxEPfTBbZei6p0Xeao6of4C/K4XU/j35aMjPC15ePIg==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.5.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-google-maps": {
|
"react-google-maps": {
|
||||||
"version": "9.4.5",
|
"version": "9.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-google-maps/-/react-google-maps-9.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-google-maps/-/react-google-maps-9.4.5.tgz",
|
||||||
|
@ -13339,6 +13430,25 @@
|
||||||
"warning": "^3.0.0"
|
"warning": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-i18next": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-p1jHmoyJgDFQmyubUEjrx6kCsr1izW/C8i9pOiJy+9lJqLYwNA8sElVplm0VAnop3kH68edT0/g3wB3UvAcRCQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.14.5",
|
||||||
|
"html-parse-stringify": "^3.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.14.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
|
||||||
|
"integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "17.0.1",
|
"version": "17.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz",
|
||||||
|
@ -16182,6 +16292,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
|
||||||
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
|
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
|
||||||
},
|
},
|
||||||
|
"void-elements": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||||
|
"integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
|
||||||
|
},
|
||||||
"w3c-hr-time": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||||
|
|
|
@ -26,8 +26,15 @@
|
||||||
"react-scripts": "4.0.1",
|
"react-scripts": "4.0.1",
|
||||||
"react-syntax-highlighter": "^15.4.3",
|
"react-syntax-highlighter": "^15.4.3",
|
||||||
"react-toastify": "^7.0.3",
|
"react-toastify": "^7.0.3",
|
||||||
|
"react-i18next": "^11.4.0",
|
||||||
|
"react-flags": "^0.1.18",
|
||||||
"recharts": "^2.0.4",
|
"recharts": "^2.0.4",
|
||||||
"tinycolor2": "^1.4.2"
|
"tinycolor2": "^1.4.2",
|
||||||
|
"axios": "^0.19.2",
|
||||||
|
"i18next": "^19.4.4",
|
||||||
|
"i18next-browser-languagedetector": "^4.1.1",
|
||||||
|
"i18next-http-backend": "^1.0.10",
|
||||||
|
"moment": "^2.25.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"DATE": "{{date,intlDate}}",
|
||||||
|
"LONG_DATE": "{{date,intlLongDate}}",
|
||||||
|
"DATE_FORMAT": "{{date, format}}",
|
||||||
|
"TIME_FROM_X": "{{date,intlTimeFromX}}",
|
||||||
|
"H_FROM_X": "{{date,intlHoursFromX}}",
|
||||||
|
"H_FROM_M": "{{number,intlHoursFromMinutes}}",
|
||||||
|
"NUMBER": "{{number,intlNumber}}",
|
||||||
|
"DECIMAL": "{{number,intlDecimal}}",
|
||||||
|
"DECIMAL2": "{{number,intlDecimal2}}",
|
||||||
|
"Language": {
|
||||||
|
"English": "English",
|
||||||
|
"Romanian": "Romanian"
|
||||||
|
},
|
||||||
|
"Menu": {
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Resources": "Resources"
|
||||||
|
},
|
||||||
|
"Login": {
|
||||||
|
"Username": "Username",
|
||||||
|
"Password": "Password",
|
||||||
|
"Label": "Login",
|
||||||
|
"ChangeUser": "Change user",
|
||||||
|
"UserChanged": "User changed",
|
||||||
|
"Logout": "Logout",
|
||||||
|
"IncorrectCredentials": "Incorrect credentials.",
|
||||||
|
"Hello": "Hi, {{username}}",
|
||||||
|
"AuthenticationDate": "Authentication date"
|
||||||
|
},
|
||||||
|
"Machine": {
|
||||||
|
"FullName": "Full machine name",
|
||||||
|
"Name": "Machine name",
|
||||||
|
"IP": "IP",
|
||||||
|
"MAC": "MAC address",
|
||||||
|
"PoweredOn": "Powered on",
|
||||||
|
"Actions": {
|
||||||
|
"Wake": "Wake",
|
||||||
|
"Ping": "Ping"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"Language": {
|
||||||
|
"English": "Engleză",
|
||||||
|
"Romanian": "Română"
|
||||||
|
},
|
||||||
|
"Menu": {
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Resources": "Resurse"
|
||||||
|
},
|
||||||
|
"Login": {
|
||||||
|
"Username": "Utilizator",
|
||||||
|
"Password": "Parolă",
|
||||||
|
"Label": "Autentificare",
|
||||||
|
"ChangeUser": "Schimbă utilizatorul",
|
||||||
|
"UserChanged": "Utilizator schimbat",
|
||||||
|
"Logout": "Deconectare",
|
||||||
|
"IncorrectCredentials": "Credențiale incorecte.",
|
||||||
|
"Hello": "Salut, {{username}}",
|
||||||
|
"AuthenticationDate": "Momentul autentificării"
|
||||||
|
},
|
||||||
|
"Machine": {
|
||||||
|
"FullName": "Nume intreg masina",
|
||||||
|
"Name": "Nume masina",
|
||||||
|
"IP": "IP",
|
||||||
|
"MAC": "Adresa MAC",
|
||||||
|
"PoweredOn": "Pornit",
|
||||||
|
"Actions": {
|
||||||
|
"Wake": "Pornește",
|
||||||
|
"Ping": "Ping"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { Suspense } from "react";
|
||||||
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
|
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
|
||||||
|
|
||||||
// components
|
// components
|
||||||
|
@ -16,19 +16,25 @@ export default function App() {
|
||||||
var { isAuthenticated } = useUserState();
|
var { isAuthenticated } = useUserState();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HashRouter basename={process.env.PUBLIC_URL || ""}>
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<Switch>
|
<HashRouter basename={process.env.PUBLIC_URL || ""}>
|
||||||
<Route exact path="/" render={() => <Redirect to="/app/dashboard" />} />
|
<Switch>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/app"
|
path="/"
|
||||||
render={() => <Redirect to="/app/dashboard" />}
|
render={() => <Redirect to="/app/dashboard" />}
|
||||||
/>
|
/>
|
||||||
<PrivateRoute path="/app" component={Layout} />
|
<Route
|
||||||
<PublicRoute path="/login" component={Login} />
|
exact
|
||||||
<Route component={Error} />
|
path="/app"
|
||||||
</Switch>
|
render={() => <Redirect to="/app/dashboard" />}
|
||||||
</HashRouter>
|
/>
|
||||||
|
<PrivateRoute path="/app" component={Layout} />
|
||||||
|
<PublicRoute path="/login" component={Login} />
|
||||||
|
<Route component={Error} />
|
||||||
|
</Switch>
|
||||||
|
</HashRouter>
|
||||||
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
||||||
function PrivateRoute({ component, ...rest }) {
|
function PrivateRoute({ component, ...rest }) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
import { Inbox as InboxIcon } from "@material-ui/icons";
|
import { Inbox as InboxIcon } from "@material-ui/icons";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
// styles
|
// styles
|
||||||
import useStyles from "./styles";
|
import useStyles from "./styles";
|
||||||
|
@ -29,7 +30,8 @@ export default function SidebarLink({
|
||||||
type
|
type
|
||||||
}) {
|
}) {
|
||||||
var classes = useStyles();
|
var classes = useStyles();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _label = t(label);
|
||||||
// local
|
// local
|
||||||
var [isOpen, setIsOpen] = useState(false);
|
var [isOpen, setIsOpen] = useState(false);
|
||||||
var isLinkActive =
|
var isLinkActive =
|
||||||
|
@ -44,7 +46,7 @@ export default function SidebarLink({
|
||||||
[classes.linkTextHidden]: !isSidebarOpened
|
[classes.linkTextHidden]: !isSidebarOpened
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{label}
|
{_label}
|
||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ export default function SidebarLink({
|
||||||
[classes.linkTextHidden]: !isSidebarOpened
|
[classes.linkTextHidden]: !isSidebarOpened
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
primary={label}
|
primary={_label}
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
@ -112,7 +114,7 @@ export default function SidebarLink({
|
||||||
[classes.linkTextHidden]: !isSidebarOpened
|
[classes.linkTextHidden]: !isSidebarOpened
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
primary={label}
|
primary={_label}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
|
@ -141,7 +143,7 @@ export default function SidebarLink({
|
||||||
[classes.linkTextHidden]: !isSidebarOpened
|
[classes.linkTextHidden]: !isSidebarOpened
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
primary={label}
|
primary={_label}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{children && (
|
{children && (
|
||||||
|
|
|
@ -2,12 +2,12 @@ import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { ThemeProvider } from "@material-ui/styles";
|
import { ThemeProvider } from "@material-ui/styles";
|
||||||
import { CssBaseline } from "@material-ui/core";
|
import { CssBaseline } from "@material-ui/core";
|
||||||
|
|
||||||
import Themes from "./themes";
|
import Themes from "./themes";
|
||||||
import App from "./components/App";
|
import App from "./components/App";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
import { LayoutProvider } from "./context/LayoutContext";
|
import { LayoutProvider } from "./context/LayoutContext";
|
||||||
import { UserProvider } from "./context/UserContext";
|
import { UserProvider } from "./context/UserContext";
|
||||||
|
import "./utils/i18n";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<LayoutProvider>
|
<LayoutProvider>
|
||||||
|
@ -18,7 +18,7 @@ ReactDOM.render(
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</UserProvider>
|
</UserProvider>
|
||||||
</LayoutProvider>,
|
</LayoutProvider>,
|
||||||
document.getElementById("root"),
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want your app to work offline and load faster, you can change
|
// If you want your app to work offline and load faster, you can change
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { getItem } from "./localStorage";
|
||||||
|
import { storageKeys } from "./identity";
|
||||||
|
|
||||||
|
function getHeaders() {
|
||||||
|
const token = getItem(storageKeys.TOKEN);
|
||||||
|
const language = i18next.language;
|
||||||
|
|
||||||
|
return {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Basic ${token.raw}`,
|
||||||
|
"Accept-Language": `${language}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function internalRequest(url, options) {
|
||||||
|
try {
|
||||||
|
const res = await axios.request(url, options);
|
||||||
|
return res.data;
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
throw (
|
||||||
|
{
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.detail || error.response.data.title
|
||||||
|
} || error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// The request was made but no response was received
|
||||||
|
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
||||||
|
// http.ClientRequest in node.js
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const request = (url, options) => internalRequest(url, options);
|
||||||
|
|
||||||
|
export function post(url, data) {
|
||||||
|
const options = {
|
||||||
|
method: "post",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
headers: getHeaders()
|
||||||
|
};
|
||||||
|
|
||||||
|
return internalRequest(url, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function put(url, data) {
|
||||||
|
const options = {
|
||||||
|
method: "put",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
headers: getHeaders()
|
||||||
|
};
|
||||||
|
|
||||||
|
return internalRequest(url, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(url, data) {
|
||||||
|
const options = {
|
||||||
|
method: "delete",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
headers: getHeaders()
|
||||||
|
};
|
||||||
|
|
||||||
|
return internalRequest(url, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(url) {
|
||||||
|
const options = {
|
||||||
|
method: "GET",
|
||||||
|
headers: getHeaders()
|
||||||
|
};
|
||||||
|
return internalRequest(url, options);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
const isArray = (parameter) => {
|
||||||
|
const _isArray = parameter.constructor === Array;
|
||||||
|
return _isArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isObject = (parameter) => {
|
||||||
|
const _isObject = typeof parameter === "object" && parameter !== null;
|
||||||
|
|
||||||
|
return _isObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
function isJson(str) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(str);
|
||||||
|
return { data, success: true };
|
||||||
|
} catch (e) {
|
||||||
|
return { data: null, success: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { isArray, isObject, isJson };
|
|
@ -0,0 +1,101 @@
|
||||||
|
import i18n from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import Backend from "i18next-http-backend";
|
||||||
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
|
import moment from "moment";
|
||||||
|
import "moment/locale/ro.js";
|
||||||
|
import "moment/locale/de.js";
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(Backend)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.use(initReactI18next) // passes i18n down to react-i18next
|
||||||
|
.init(
|
||||||
|
{
|
||||||
|
fallbackLng: "en",
|
||||||
|
debug: true,
|
||||||
|
ns: ["translations"],
|
||||||
|
defaultNS: "translations",
|
||||||
|
//whitelist: ["en", "ro"],
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false, // not needed for react as it escapes by default
|
||||||
|
format: function (value, format, lng) {
|
||||||
|
if (format === "uppercase") return value.toUpperCase();
|
||||||
|
if (format === "intlDate") {
|
||||||
|
if (value && moment(value).isValid()) {
|
||||||
|
return moment(value).format("L");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlLongDate") {
|
||||||
|
if (value && moment(value).isValid()) {
|
||||||
|
return moment(value).format("LLLL");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlTimeFromX") {
|
||||||
|
if (value && moment(value.start).isValid()) {
|
||||||
|
let startDate = moment(value.start);
|
||||||
|
let endDate = moment(value.end);
|
||||||
|
return moment(endDate).from(startDate, true);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlHoursFromX") {
|
||||||
|
if (value && moment(value.start).isValid()) {
|
||||||
|
let startDate = moment(value.start);
|
||||||
|
let endDate = moment(value.end);
|
||||||
|
let span = moment.duration(endDate - startDate);
|
||||||
|
return `${parseInt(span.asHours(), 10)}h ${parseInt(
|
||||||
|
span.asMinutes() % 60,
|
||||||
|
10
|
||||||
|
)}m`;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlNumber")
|
||||||
|
return new Intl.NumberFormat(lng).format(value);
|
||||||
|
if (format === "intlDecimal")
|
||||||
|
return new Intl.NumberFormat(lng, {
|
||||||
|
minimumFractionDigits: 2
|
||||||
|
}).format(value);
|
||||||
|
if (format === "intlDecimal2")
|
||||||
|
return new Intl.NumberFormat(lng, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
}).format(value);
|
||||||
|
|
||||||
|
//dateformat
|
||||||
|
if (value && value.format) {
|
||||||
|
if (value.value && moment(value).isValid()) {
|
||||||
|
return moment(value.value).format(value.format);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backend: {
|
||||||
|
loadPath: `${process.env.PUBLIC_URL || ""}/locales/{{lng}}/{{ns}}.json`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
const currentLang = i18n.language;
|
||||||
|
if (!currentLang || !currentLang.startsWith("ro")) {
|
||||||
|
i18n.changeLanguage("en");
|
||||||
|
} else {
|
||||||
|
i18n.changeLanguage("ro");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
i18n.on("languageChanged", function (lng) {
|
||||||
|
moment.locale(lng);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { request } from "./axios";
|
||||||
|
import { setItem, getItem, removeItem } from "./localStorage";
|
||||||
|
|
||||||
|
const storageKeys = {
|
||||||
|
TOKEN: "AUTHORIZATION_TOKEN",
|
||||||
|
USER: "USER_NAME"
|
||||||
|
};
|
||||||
|
|
||||||
|
const authenticate = async (userName, password) => {
|
||||||
|
const urlTemplate = process.env.REACT_APP_IDENTITY_AUTHENTICATION_URL;
|
||||||
|
const url = urlTemplate
|
||||||
|
.replace("{username}", userName)
|
||||||
|
.replace("{password}", password);
|
||||||
|
const options = {
|
||||||
|
method: "post"
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await request(url, options);
|
||||||
|
if (response.status === "SUCCESS") {
|
||||||
|
setItem(storageKeys.TOKEN, response.token);
|
||||||
|
setItem(storageKeys.USER, userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
const invalidate = () => {
|
||||||
|
const token = getItem(storageKeys.TOKEN);
|
||||||
|
if (token) {
|
||||||
|
removeItem(storageKeys.TOKEN);
|
||||||
|
removeItem(storageKeys.USER);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { storageKeys, authenticate, invalidate };
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { isArray, isObject, isJson } from "./dataType";
|
||||||
|
|
||||||
|
const setItem = (key, value) => {
|
||||||
|
let valueToStore = value;
|
||||||
|
if (isArray(value) || isObject(value)) {
|
||||||
|
valueToStore = JSON.stringify(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.localStorage.setItem(key, valueToStore);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getItem = (key) => {
|
||||||
|
var value = window.localStorage.getItem(key);
|
||||||
|
var { data, success } = isJson(value);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeItem = (key) => {
|
||||||
|
window.localStorage.removeItem(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
const key = (index) => {
|
||||||
|
var keyName = window.localStorage.key(index);
|
||||||
|
return keyName;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { setItem, getItem, removeItem, clear, key };
|
Loading…
Reference in New Issue