mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-15 13:36:35 +02:00
Compare commits
114 Commits
Author | SHA1 | Date | |
---|---|---|---|
a8d8c872f9 | |||
cda7898a96 | |||
26bea9c7c4 | |||
fd1518265f | |||
61d10e91e0 | |||
aac6c6bf2a | |||
d55615abcc | |||
9d322811c3 | |||
f30685d9c2 | |||
5bb298270b | |||
8d0c640994 | |||
25ddb5949c | |||
7b739f55a0 | |||
03a020f87c | |||
c6fd9bbadb | |||
acaaab0654 | |||
04a667eb6f | |||
d71f638bd5 | |||
1064277cd9 | |||
8d1d5b57fd | |||
fd01bc6f56 | |||
e27a23600f | |||
daf787e2df | |||
512c65c213 | |||
3925fb6439 | |||
21bbfb6d2e | |||
1dcba1dfa8 | |||
fd8acd1ceb | |||
48d5cf0119 | |||
1a82f8e225 | |||
638821d025 | |||
fbaa73e378 | |||
e54db2c577 | |||
a6866a0673 | |||
429814ebb5 | |||
73e213c467 | |||
2e68e56e44 | |||
b3bb4de646 | |||
b30f9f59b4 | |||
158bd1bb24 | |||
d935f78d6e | |||
73f4ab48c3 | |||
7075592f24 | |||
23029470b9 | |||
7e6e6f8c87 | |||
b831d664a9 | |||
0f5b35a3ba | |||
6e02f1d194 | |||
13ff8221ca | |||
a51ba0630d | |||
ee5cf07614 | |||
8b39bf4193 | |||
644726a0fc | |||
654ae6914a | |||
81dedf59cd | |||
7f8aaea7b8 | |||
dfa80e64ec | |||
031b53f03c | |||
ca23b2d335 | |||
0984c45161 | |||
6835bc7a28 | |||
0915d477fe | |||
c114579b7f | |||
22b2bc9c09 | |||
cab2cfa068 | |||
a137a0d4cf | |||
54cf7e3c06 | |||
18eb28f368 | |||
88f3836485 | |||
8f88b09e66 | |||
f2aa28f172 | |||
a88fbf63e9 | |||
ff9e8fdeb1 | |||
8cd4ac8b44 | |||
760e6d9243 | |||
2429f4662c | |||
b320e6a860 | |||
1e3e9433ec | |||
e3a795e40d | |||
dccc9e5769 | |||
30748fab12 | |||
a17ecc6060 | |||
75ce94d3ee | |||
96263af618 | |||
50a1bfd9b5 | |||
b360431f38 | |||
9eebb35e65 | |||
cf556e3518 | |||
5977e675cf | |||
ee5f3da093 | |||
afa8c160a3 | |||
0af56ec84c | |||
96eed02d32 | |||
8479518fab | |||
800dedbcfd | |||
44e45499c6 | |||
5457f68c70 | |||
680871de62 | |||
9641fbcb50 | |||
1708f026a4 | |||
7516cfdbfe | |||
cbb1382c66 | |||
e4e28dbce4 | |||
7a14ed1b60 | |||
497a1a0ad3 | |||
4a481ea642 | |||
8296c6129e | |||
7253319b61 | |||
7371fbcac0 | |||
d658f0b112 | |||
edc5c92421 | |||
d4bc5a6998 | |||
b938dd85ff | |||
4ff3e33411 |
64
.eslintrc.js
64
.eslintrc.js
@ -1,66 +1,6 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es6": true,
|
||||
"jest": true
|
||||
},
|
||||
"extends": [
|
||||
"airbnb",
|
||||
"airbnb/hooks"
|
||||
],
|
||||
"globals": {
|
||||
"_": "readonly",
|
||||
"babel": "readonly",
|
||||
"ForisTranslations": "readonly",
|
||||
"ngettext": "readonly",
|
||||
"ForisPlugins": "readonly"
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"quotes": ["error", "double"],
|
||||
"indent": ["error", 4],
|
||||
"react/jsx-indent": ["error", 4],
|
||||
"react/jsx-indent-props": ["error", 4],
|
||||
"react/prop-types": "warn",
|
||||
"react/no-array-index-key": "warn",
|
||||
"react/button-has-type": "warn",
|
||||
extends: "eslint-config-reforis",
|
||||
rules: {
|
||||
"import/prefer-default-export": "off",
|
||||
"import/no-unresolved": [
|
||||
"error",
|
||||
// Ignore imports used only in tests
|
||||
{ ignore: ["customTestRender"] }
|
||||
],
|
||||
"import/no-cycle": "warn",
|
||||
"no-console": "error",
|
||||
"no-use-before-define": ["error", {
|
||||
functions: false,
|
||||
classes: true,
|
||||
variables: true
|
||||
}],
|
||||
"no-restricted-syntax": "warn",
|
||||
// Should be enabled in the future
|
||||
"camelcase": "off",
|
||||
"no-param-reassign": "off",
|
||||
"react/jsx-props-no-spreading": "off",
|
||||
"react/require-default-props": "off",
|
||||
"react/default-props-match-prop-types": "off",
|
||||
"react/forbid-prop-types": "off",
|
||||
// Permanently disabled
|
||||
"react/jsx-filename-extension": "off",
|
||||
"no-plusplus": "off",
|
||||
"consistent-return": "off",
|
||||
"radix": "off",
|
||||
"no-continue": "off",
|
||||
"react/no-danger": "off",
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"paths": ["src"]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -4,6 +4,9 @@
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Python
|
||||
venv/
|
||||
|
||||
# NodeJS
|
||||
## Logs
|
||||
npm-debug.log*
|
||||
@ -43,8 +46,8 @@ coverage.xml
|
||||
## Translations
|
||||
*.mo
|
||||
|
||||
/js/styleguide/
|
||||
.gitignore
|
||||
|
||||
dist/
|
||||
foris-*.tgz
|
||||
styleguide/
|
||||
|
@ -3,24 +3,42 @@ image: node:8-alpine
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- publish
|
||||
|
||||
before_script:
|
||||
- apk add make
|
||||
- npm install
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- npm test
|
||||
- make test
|
||||
|
||||
lint:
|
||||
stage: test
|
||||
script:
|
||||
- npm run lint
|
||||
- make lint
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- npm pack
|
||||
- make pack
|
||||
artifacts:
|
||||
paths:
|
||||
- foris-*.tgz
|
||||
- dist/foris-*.tgz
|
||||
|
||||
publish_beta:
|
||||
stage: publish
|
||||
only:
|
||||
refs:
|
||||
- dev
|
||||
script:
|
||||
- make publish-beta
|
||||
|
||||
publish_latest:
|
||||
stage: publish
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
script:
|
||||
- make publish-latest
|
||||
|
64
Makefile
64
Makefile
@ -1,17 +1,71 @@
|
||||
.PHONY: all create-messages update-messages clean
|
||||
.PHONY: all install-js watch-js build-js collect-files pack publish-beta publish-latest lint test test-js-update-snapshots create-messages update-messages docs docs-watch clean
|
||||
|
||||
DEV_PYTHON=python3.7
|
||||
VENV_NAME?=venv
|
||||
VENV_BIN=$(shell pwd)/$(VENV_NAME)/bin
|
||||
|
||||
all:
|
||||
@echo "make install-js"
|
||||
@echo " Install dependencies"
|
||||
@echo "make watch-js"
|
||||
@echo " Compile JS in watch mode."
|
||||
@echo "make build-js"
|
||||
@echo " Compile JS."
|
||||
@echo "make lint-js"
|
||||
@echo " Run linter"
|
||||
@echo "make test-js"
|
||||
@echo " Run tests"
|
||||
@echo "make create-messages"
|
||||
@echo " Create locale messages (.pot)."
|
||||
@echo "make update-messages"
|
||||
@echo " Update locale messages from .pot file."
|
||||
@echo "make docs"
|
||||
@echo " Build project documentation."
|
||||
@echo "make docs-watch"
|
||||
@echo " Start styleguidist server."
|
||||
@echo "make clean"
|
||||
@echo " Remove python artifacts and virtualenv."
|
||||
|
||||
create-messages:
|
||||
pybabel extract -F babel.cfg -o ./translations/forisjs.pot .
|
||||
update-messages:
|
||||
pybabel update -i translations/forisjs.pot -d translations
|
||||
venv: $(VENV_NAME)/bin/activate
|
||||
$(VENV_NAME)/bin/activate:
|
||||
test -d $(VENV_NAME) || $(DEV_PYTHON) -m virtualenv -p $(DEV_PYTHON) $(VENV_NAME)
|
||||
$(VENV_BIN)/$(DEV_PYTHON) -m pip install -r requirements.txt
|
||||
touch $(VENV_NAME)/bin/activate
|
||||
|
||||
install-js: package.json
|
||||
npm install --save-dev
|
||||
|
||||
watch-js:
|
||||
npm run build:watch
|
||||
build-js:
|
||||
npm run build
|
||||
|
||||
collect-files:
|
||||
sh scripts/collect_files.sh
|
||||
pack: collect-files
|
||||
cd dist && npm pack
|
||||
publish-beta: collect-files
|
||||
sh scripts/publish.sh beta
|
||||
publish-latest: collect-files
|
||||
sh scripts/publish.sh latest
|
||||
|
||||
lint:
|
||||
npm run lint
|
||||
|
||||
test:
|
||||
npm test
|
||||
test-js-update-snapshots:
|
||||
npm test -- -u
|
||||
|
||||
create-messages: venv
|
||||
$(VENV_BIN)/pybabel extract -F babel.cfg -o ./translations/forisjs.pot .
|
||||
update-messages: venv
|
||||
$(VENV_BIN)/pybabel update -i ./translations/forisjs.pot -d ./translations -D forisjs
|
||||
|
||||
docs:
|
||||
npm run-script docs
|
||||
docs-watch:
|
||||
npm run-script docs:watch
|
||||
|
||||
clean:
|
||||
rm -rf node_modules dist
|
||||
|
18
README.md
Normal file
18
README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# foris-js
|
||||
Set of utils and common React elements for reForis.
|
||||
|
||||
## Publishing package
|
||||
|
||||
### Beta versions
|
||||
|
||||
Each commit to `dev` branch will result in publishing a new version of library
|
||||
tagged `beta`. Versions names are based on commit SHA, e.g.
|
||||
`foris@0.1.0-beta.d9073aa4`.
|
||||
|
||||
### Preparing a release
|
||||
|
||||
1. Crete a merge request to `dev` branch with version bumped
|
||||
2. When merging add `[skip ci]` to commit message to prevent publishing
|
||||
unnecessary version
|
||||
3. Create a merge request from `dev` to `master` branch
|
||||
4. New version should be published automatically
|
@ -14,4 +14,12 @@ module.exports = {
|
||||
},
|
||||
}],
|
||||
],
|
||||
env: {
|
||||
development: {
|
||||
ignore: ["**/__tests__/**", "**/__mocks__/**"],
|
||||
},
|
||||
test: {
|
||||
ignore: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
1
docs/intro.md
Normal file
1
docs/intro.md
Normal file
@ -0,0 +1 @@
|
||||
Foris JS library is set of componets and utils for Foris JS application and plugins.
|
@ -24,4 +24,8 @@ module.exports = {
|
||||
globals: {
|
||||
TZ: "utc",
|
||||
},
|
||||
transform: {
|
||||
"^.+\\.js$": "babel-jest",
|
||||
"^.+\\.css$": "jest-transform-css",
|
||||
},
|
||||
};
|
||||
|
2245
package-lock.json
generated
2245
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "foris",
|
||||
"version": "0.0.7",
|
||||
"version": "2.0.0",
|
||||
"description": "Set of components and utils for Foris and its plugins.",
|
||||
"author": "CZ.NIC, z.s.p.o.",
|
||||
"repository": {
|
||||
@ -12,60 +12,63 @@
|
||||
"reforis"
|
||||
],
|
||||
"license": "GPL-3.0",
|
||||
"main": "./dist/index.js",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"immutability-helper": "^3.0.1",
|
||||
"jest-transform-css": "^2.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.25",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-datetime": "^2.16.3",
|
||||
"react-router": "^5.0.1",
|
||||
"react-uid": "^2.2.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.25"
|
||||
"react-uid": "^2.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0",
|
||||
"react-dom": "^16.9.0"
|
||||
"immutability-helper": "3.0.1",
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.5.5",
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/cli": "^7.4.4",
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/plugin-syntax-export-default-from": "^7.2.0",
|
||||
"@babel/plugin-transform-runtime": "^7.4.4",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@testing-library/react": "^8.0.1",
|
||||
"babel-eslint": "^9.0.0",
|
||||
"@fortawesome/fontawesome-free": "^5.11.2",
|
||||
"@testing-library/react": "^8.0.9",
|
||||
"babel-jest": "^24.8.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-module-resolver": "^3.2.0",
|
||||
"babel-plugin-react-transform": "^3.0.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-airbnb": "^18.0.1",
|
||||
"eslint-plugin-import": "^2.17.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.1",
|
||||
"eslint-plugin-react": "^7.13.0",
|
||||
"eslint-plugin-react-hooks": "^1.6.0",
|
||||
"bootstrap": "^4.3.1",
|
||||
"copy-webpack-plugin": "^5.0.4",
|
||||
"css-loader": "^3.2.0",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-config-reforis": "^1.0.0",
|
||||
"file-loader": "^4.2.0",
|
||||
"immutability-helper": "3.0.1",
|
||||
"jest": "^24.8.0",
|
||||
"jest-mock-axios": "^3.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.25",
|
||||
"react": "^16.9.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-styleguidist": "^9.1.11",
|
||||
"snapshot-diff": "^0.5.1"
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0",
|
||||
"react-styleguidist": "^9.1.16",
|
||||
"snapshot-diff": "^0.5.1",
|
||||
"style-loader": "^1.0.0",
|
||||
"webpack": "^4.41.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline",
|
||||
"prepare": "rm -rf ./dist && npm run build",
|
||||
"build": "rm -rf dist; babel src --out-dir dist --source-maps inline --copy-files",
|
||||
"build:watch": "babel src --verbose --watch --out-dir dist --source-maps inline --copy-files",
|
||||
"lint": "eslint src",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage --colors"
|
||||
},
|
||||
"files": [
|
||||
"dist/**",
|
||||
"translations"
|
||||
]
|
||||
"test:coverage": "jest --coverage --colors",
|
||||
"docs": "npx styleguidist build ",
|
||||
"docs:watch": "styleguidist server"
|
||||
}
|
||||
}
|
||||
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
Babel
|
9
scripts/collect_files.sh
Normal file
9
scripts/collect_files.sh
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Collect files
|
||||
npm run build
|
||||
cp package.json README.md dist
|
||||
cp -rf translations dist
|
||||
# Remove unwanted files
|
||||
rm -rf dist/**/__tests__
|
||||
rm -rf dist/__mocks__
|
24
scripts/publish.sh
Executable file
24
scripts/publish.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test -z "$NPM_TOKEN"
|
||||
then
|
||||
echo "\$NPM_TOKEN is not set"
|
||||
exit 1
|
||||
else
|
||||
cd dist
|
||||
# Need to replace "_" with "-" as GitLab CI won't accept secret vars with "-"
|
||||
echo "//registry.npmjs.org/:_authToken=$(echo "$NPM_TOKEN" | tr _ -)" > .npmrc
|
||||
echo "unsafe-perm = true" >> ~/.npmrc
|
||||
if test "$1" = "beta"
|
||||
then
|
||||
BETA_VERSION=$(npx -c 'echo "$npm_package_version"')-beta.$CI_COMMIT_SHORT_SHA
|
||||
npm version "$BETA_VERSION" --git-tag-version false
|
||||
npm publish --tag beta
|
||||
elif test "$1" = "latest"
|
||||
then
|
||||
npm publish
|
||||
else
|
||||
echo "Usage: publish.sh [ beta | latest ]"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
52
src/alertContext/AlertContext.js
Normal file
52
src/alertContext/AlertContext.js
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, { useState, useContext, useCallback } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Alert, ALERT_TYPES } from "bootstrap/Alert";
|
||||
import { Portal } from "utils/Portal";
|
||||
|
||||
AlertContextProvider.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]),
|
||||
};
|
||||
|
||||
function AlertContextProvider({ children }) {
|
||||
const { AlertContext } = window;
|
||||
const [alert, setAlert] = useState(null);
|
||||
|
||||
const setAlertWrapper = useCallback((message, type = ALERT_TYPES.DANGER) => {
|
||||
setAlert({ message, type });
|
||||
}, [setAlert]);
|
||||
|
||||
const dismissAlert = useCallback(() => setAlert(null), [setAlert]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{alert && (
|
||||
<Portal containerId="alert-container">
|
||||
<Alert type={alert.type} onDismiss={dismissAlert}>
|
||||
{alert.message}
|
||||
</Alert>
|
||||
</Portal>
|
||||
)}
|
||||
<AlertContext.Provider value={[setAlertWrapper, dismissAlert]}>
|
||||
{ children }
|
||||
</AlertContext.Provider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function useAlert() {
|
||||
const { AlertContext } = window;
|
||||
return useContext(AlertContext);
|
||||
}
|
||||
|
||||
export { AlertContextProvider, useAlert };
|
65
src/alertContext/__tests__/AlertContext.test.js
Normal file
65
src/alertContext/__tests__/AlertContext.test.js
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render, getByText, queryByText, fireEvent } from "customTestRender";
|
||||
|
||||
import { useAlert, AlertContextProvider } from "../AlertContext";
|
||||
|
||||
function AlertTest() {
|
||||
const [setAlert, dismissAlert] = useAlert();
|
||||
// alert-container serves as an output for Portal which renders Alert
|
||||
return (
|
||||
<>
|
||||
<div id="alert-container" />
|
||||
<button onClick={() => setAlert("Alert content")}>Set alert</button>
|
||||
<button onClick={dismissAlert}>Dismiss alert</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
describe("AlertContext", () => {
|
||||
let componentContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
const { container } = render(
|
||||
<AlertContextProvider>
|
||||
<AlertTest />
|
||||
</AlertContextProvider>
|
||||
);
|
||||
componentContainer = container;
|
||||
});
|
||||
|
||||
it("should render component without alert", () => {
|
||||
expect(componentContainer).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render alert", () => {
|
||||
fireEvent.click(getByText(componentContainer, "Set alert"));
|
||||
expect(componentContainer).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should dismiss alert with alert button", () => {
|
||||
fireEvent.click(getByText(componentContainer, "Set alert"));
|
||||
// Alert is present
|
||||
expect(getByText(componentContainer, "Alert content")).toBeDefined();
|
||||
|
||||
fireEvent.click(componentContainer.querySelector(".close"));
|
||||
// Alert is gone
|
||||
expect(queryByText(componentContainer, "Alert content")).toBeNull();
|
||||
});
|
||||
|
||||
it("should dismiss alert with external button", () => {
|
||||
fireEvent.click(getByText(componentContainer, "Set alert"));
|
||||
// Alert is present
|
||||
expect(getByText(componentContainer, "Alert content")).toBeDefined();
|
||||
|
||||
fireEvent.click(getByText(componentContainer, "Dismiss alert"));
|
||||
// Alert is gone
|
||||
expect(queryByText(componentContainer, "Alert content")).toBeNull();
|
||||
});
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AlertContext should render alert 1`] = `
|
||||
<div>
|
||||
<div
|
||||
id="alert-container"
|
||||
>
|
||||
<div
|
||||
class="alert alert-dismissible alert-danger"
|
||||
>
|
||||
<button
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
Alert content
|
||||
</div>
|
||||
</div>
|
||||
<button>
|
||||
Set alert
|
||||
</button>
|
||||
<button>
|
||||
Dismiss alert
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`AlertContext should render component without alert 1`] = `
|
||||
<div>
|
||||
<div
|
||||
id="alert-container"
|
||||
/>
|
||||
<button>
|
||||
Set alert
|
||||
</button>
|
||||
<button>
|
||||
Dismiss alert
|
||||
</button>
|
||||
</div>
|
||||
`;
|
193
src/api/hooks.js
193
src/api/hooks.js
@ -5,149 +5,116 @@
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import axios from "axios";
|
||||
import { useCallback, useReducer } from "react";
|
||||
import {
|
||||
useCallback, useEffect, useReducer, useState,
|
||||
} from "react";
|
||||
|
||||
import { ForisURLs } from "forisUrls";
|
||||
import {
|
||||
API_ACTIONS, API_METHODS, API_STATE, getErrorPayload, HEADERS, TIMEOUT,
|
||||
} from "./utils";
|
||||
|
||||
const DATA_METHODS = ["POST", "PATCH", "PUT"];
|
||||
|
||||
const POST_HEADERS = {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": getCookie("_csrf_token"),
|
||||
};
|
||||
function createAPIHook(method) {
|
||||
return (urlRoot, contentType) => {
|
||||
const [state, dispatch] = useReducer(APIReducer, {
|
||||
state: API_STATE.INIT,
|
||||
data: null,
|
||||
});
|
||||
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== "") {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === (`${name}=`)) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
const sendRequest = useCallback(async ({ data, suffix } = {}) => {
|
||||
const headers = { ...HEADERS };
|
||||
if (contentType) {
|
||||
headers["Content-Type"] = contentType;
|
||||
}
|
||||
|
||||
dispatch({ type: API_ACTIONS.INIT });
|
||||
try {
|
||||
// Prepare request
|
||||
const request = API_METHODS[method];
|
||||
const config = {
|
||||
timeout: TIMEOUT,
|
||||
headers,
|
||||
};
|
||||
const url = suffix ? `${urlRoot}/${suffix}` : urlRoot;
|
||||
|
||||
// Make request
|
||||
let result;
|
||||
if (DATA_METHODS.includes(method)) {
|
||||
result = await request(url, data, config);
|
||||
} else {
|
||||
result = await request(url, config);
|
||||
}
|
||||
|
||||
// Process request result
|
||||
dispatch({
|
||||
type: API_ACTIONS.SUCCESS,
|
||||
payload: result.data,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: API_ACTIONS.FAILURE,
|
||||
status: error.response && error.response.status,
|
||||
payload: getErrorPayload(error),
|
||||
});
|
||||
}
|
||||
return cookieValue;
|
||||
}, [urlRoot, contentType]);
|
||||
return [state, sendRequest];
|
||||
};
|
||||
}
|
||||
|
||||
export const TIMEOUT = 5000;
|
||||
|
||||
const API_ACTIONS = {
|
||||
INIT: 1,
|
||||
SUCCESS: 2,
|
||||
FAILURE: 3,
|
||||
};
|
||||
|
||||
const APIGetReducer = (state, action) => {
|
||||
function APIReducer(state, action) {
|
||||
switch (action.type) {
|
||||
case API_ACTIONS.INIT:
|
||||
return {
|
||||
...state,
|
||||
isLoading: true,
|
||||
isError: false,
|
||||
state: API_STATE.SENDING,
|
||||
};
|
||||
case API_ACTIONS.SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
state: API_STATE.SUCCESS,
|
||||
data: action.payload,
|
||||
};
|
||||
case API_ACTIONS.FAILURE:
|
||||
if (action.status === 403) window.location.assign(ForisURLs.login);
|
||||
if (action.status === 403) {
|
||||
window.location.assign(ForisURLs.login);
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
isLoading: false,
|
||||
isError: true,
|
||||
state: API_STATE.ERROR,
|
||||
data: action.payload,
|
||||
};
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
|
||||
export function useAPIGet(url) {
|
||||
const [state, dispatch] = useReducer(APIGetReducer, {
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
data: null,
|
||||
});
|
||||
const get = useCallback(async () => {
|
||||
dispatch({ type: API_ACTIONS.INIT });
|
||||
try {
|
||||
const result = await axios.get(url, {
|
||||
timeout: TIMEOUT,
|
||||
});
|
||||
dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data });
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: API_ACTIONS.FAILURE,
|
||||
payload: error.response.data,
|
||||
status: error.response.status,
|
||||
});
|
||||
}
|
||||
}, [url]);
|
||||
|
||||
return [state, get];
|
||||
}
|
||||
|
||||
const APIPostReducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case API_ACTIONS.INIT:
|
||||
return {
|
||||
...state,
|
||||
isSending: true,
|
||||
isError: false,
|
||||
isSuccess: false,
|
||||
};
|
||||
case API_ACTIONS.SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isSending: false,
|
||||
isError: false,
|
||||
isSuccess: true,
|
||||
data: action.payload,
|
||||
};
|
||||
case API_ACTIONS.FAILURE:
|
||||
if (action.status === 403) window.location.assign(ForisURLs.login);
|
||||
return {
|
||||
...state,
|
||||
isSending: false,
|
||||
isError: true,
|
||||
isSuccess: false,
|
||||
data: action.payload,
|
||||
};
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
const useAPIGet = createAPIHook("GET");
|
||||
const useAPIPost = createAPIHook("POST");
|
||||
const useAPIPatch = createAPIHook("PATCH");
|
||||
const useAPIPut = createAPIHook("PUT");
|
||||
const useAPIDelete = createAPIHook("DELETE");
|
||||
|
||||
export {
|
||||
useAPIGet, useAPIPost, useAPIPatch, useAPIPut, useAPIDelete,
|
||||
};
|
||||
|
||||
export function useAPIPost(url) {
|
||||
const [state, dispatch] = useReducer(APIPostReducer, {
|
||||
isSending: false,
|
||||
isError: false,
|
||||
isSuccess: false,
|
||||
data: null,
|
||||
});
|
||||
export function useAPIPolling(endpoint, delay = 1000, until) { // delay ms
|
||||
const [state, setState] = useState({ state: API_STATE.INIT });
|
||||
const [getResponse, get] = useAPIGet(endpoint);
|
||||
|
||||
const post = async (data) => {
|
||||
dispatch({ type: API_ACTIONS.INIT });
|
||||
try {
|
||||
const result = await axios.post(url, data, {
|
||||
timeout: TIMEOUT,
|
||||
headers: POST_HEADERS,
|
||||
});
|
||||
dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data });
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: API_ACTIONS.FAILURE,
|
||||
payload: error.response.data,
|
||||
status: error.response.status,
|
||||
});
|
||||
useEffect(() => {
|
||||
if (getResponse.state !== API_STATE.INIT) {
|
||||
setState(getResponse);
|
||||
}
|
||||
};
|
||||
return [state, post];
|
||||
}, [getResponse]);
|
||||
|
||||
useEffect(() => {
|
||||
if (until) {
|
||||
const interval = setInterval(get, delay);
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [until, delay, get]);
|
||||
|
||||
return [state];
|
||||
}
|
||||
|
78
src/api/utils.js
Normal file
78
src/api/utils.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
export const HEADERS = {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": getCookie("_csrf_token"),
|
||||
};
|
||||
|
||||
export const TIMEOUT = 5000;
|
||||
|
||||
export const API_ACTIONS = {
|
||||
INIT: 1,
|
||||
SUCCESS: 2,
|
||||
FAILURE: 3,
|
||||
};
|
||||
|
||||
export const API_STATE = {
|
||||
INIT: "init",
|
||||
SENDING: "sending",
|
||||
SUCCESS: "success",
|
||||
ERROR: "error",
|
||||
};
|
||||
|
||||
export const API_METHODS = {
|
||||
GET: axios.get,
|
||||
POST: axios.post,
|
||||
PATCH: axios.patch,
|
||||
PUT: axios.put,
|
||||
DELETE: axios.delete,
|
||||
};
|
||||
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== "") {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === (`${name}=`)) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
export function getErrorPayload(error) {
|
||||
if (error.response) {
|
||||
if (error.response.status === 403) {
|
||||
return _("The session is expired. Please log in again.");
|
||||
}
|
||||
return getJSONErrorMessage(error);
|
||||
}
|
||||
if (error.code === "ECONNABORTED") {
|
||||
return _("Timeout error occurred.");
|
||||
}
|
||||
if (error.request) {
|
||||
return _("No response received.");
|
||||
}
|
||||
/* eslint no-console: "off" */
|
||||
console.error(error);
|
||||
return _("An unknown error occurred. Check the console for more info.");
|
||||
}
|
||||
|
||||
export function getJSONErrorMessage(error) {
|
||||
if (error.response.headers["content-type"] === "application/json") {
|
||||
return error.response.data;
|
||||
}
|
||||
return _("An unknown API error occurred.");
|
||||
}
|
@ -8,11 +8,20 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export const ALERT_TYPES = Object.freeze({
|
||||
PRIMARY: "primary",
|
||||
SECONDARY: "secondary",
|
||||
SUCCESS: "success",
|
||||
DANGER: "danger",
|
||||
WARNING: "warning",
|
||||
INFO: "info",
|
||||
LIGHT: "light",
|
||||
DARK: "dark",
|
||||
});
|
||||
|
||||
Alert.propTypes = {
|
||||
/** Type of the alert it adds as `alert-${type}` class. */
|
||||
type: PropTypes.string.isRequired,
|
||||
/** Alert message. */
|
||||
message: PropTypes.string,
|
||||
type: PropTypes.oneOf(Object.values(ALERT_TYPES)),
|
||||
/** Alert content. */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
@ -22,13 +31,16 @@ Alert.propTypes = {
|
||||
onDismiss: PropTypes.func,
|
||||
};
|
||||
|
||||
Alert.defaultProps = {
|
||||
type: ALERT_TYPES.DANGER,
|
||||
};
|
||||
|
||||
export function Alert({
|
||||
type, message, onDismiss, children,
|
||||
type, onDismiss, children,
|
||||
}) {
|
||||
return (
|
||||
<div className={`alert alert-dismissible alert-${type}`}>
|
||||
{onDismiss ? <button type="button" className="close" onClick={onDismiss}>×</button> : false}
|
||||
{message}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useUID } from "react-uid/dist/es5/index";
|
||||
import { useUID } from "react-uid";
|
||||
|
||||
import { formFieldsSize } from "./constants";
|
||||
|
||||
@ -32,8 +32,8 @@ export function CheckBox({
|
||||
}) {
|
||||
const uid = useUID();
|
||||
return (
|
||||
<div className={useDefaultSize ? formFieldsSize : ""} style={{ marginBottom: "1rem" }}>
|
||||
<div className="custom-control custom-checkbox" style={{ marginBottom: "0" }}>
|
||||
<div className={`form-group ${useDefaultSize ? formFieldsSize : ""}`.trim()}>
|
||||
<div className="custom-control custom-checkbox ">
|
||||
<input
|
||||
className="custom-control-input"
|
||||
type="checkbox"
|
||||
@ -42,9 +42,11 @@ export function CheckBox({
|
||||
|
||||
{...props}
|
||||
/>
|
||||
<label className="custom-control-label" htmlFor={uid} style={helpText ? { marginBottom: "0" } : null}>{label}</label>
|
||||
<label className="custom-control-label" htmlFor={uid}>
|
||||
{label}
|
||||
{helpText && <small className="form-text text-muted">{helpText}</small>}
|
||||
</label>
|
||||
</div>
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -11,6 +11,6 @@ const [value, setValue] = useState(false);
|
||||
value={value}
|
||||
label="Some label"
|
||||
helpText="Read the small text!"
|
||||
onChange={value => setValue(value)}
|
||||
onChange={event =>setValue(event.target.value)}
|
||||
/>
|
||||
```
|
||||
|
@ -9,6 +9,7 @@ import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Datetime from "react-datetime/DateTime";
|
||||
import moment from "moment/moment";
|
||||
import "react-datetime/css/react-datetime.css";
|
||||
|
||||
import { Input } from "./Input";
|
||||
|
||||
|
34
src/bootstrap/DownloadButton.js
Normal file
34
src/bootstrap/DownloadButton.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
DownloadButton.propTypes = {
|
||||
href: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]),
|
||||
};
|
||||
|
||||
DownloadButton.defaultProps = {
|
||||
className: "btn-primary",
|
||||
};
|
||||
|
||||
export function DownloadButton({ href, className, children }) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={`btn ${className}`.trim()}
|
||||
download
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
7
src/bootstrap/DownloadButton.md
Normal file
7
src/bootstrap/DownloadButton.md
Normal file
@ -0,0 +1,7 @@
|
||||
Hyperlink with apperance of a button.
|
||||
|
||||
It has `download` attribute, which prevents closing WebSocket connection on Firefox. See [related issue](https://bugzilla.mozilla.org/show_bug.cgi?id=858538) for more details.
|
||||
|
||||
```js
|
||||
<DownloadButton href="example.zip">Download</DownloadButton>
|
||||
```
|
@ -12,7 +12,6 @@ import { Input } from "./Input";
|
||||
|
||||
export const EmailInput = ({ ...props }) => <Input type="email" {...props} />;
|
||||
|
||||
|
||||
EmailInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
|
@ -11,7 +11,7 @@ const [email, setEmail] = useState('Wrong email');
|
||||
value={email}
|
||||
label="Some label"
|
||||
helpText="Read the small text!"
|
||||
onChange={target => setEmail(target.value)}
|
||||
onChange={event =>setEmail(event.target.value)}
|
||||
/>
|
||||
<button type="submit">Try to submit</button>
|
||||
</form>
|
||||
|
34
src/bootstrap/FileInput.js
Normal file
34
src/bootstrap/FileInput.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { Input } from "./Input";
|
||||
|
||||
FileInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error message. */
|
||||
error: PropTypes.string,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Email value. */
|
||||
value: PropTypes.string,
|
||||
};
|
||||
|
||||
export function FileInput({ ...props }) {
|
||||
return (
|
||||
<Input
|
||||
type="file"
|
||||
className="custom-file-input"
|
||||
labelClassName="custom-file-label"
|
||||
groupClassName="custom-file"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
15
src/bootstrap/FileInput.md
Normal file
15
src/bootstrap/FileInput.md
Normal file
@ -0,0 +1,15 @@
|
||||
Bootstrap component for file input. Includes label and has predefined sizes and structure for using in foris forms.
|
||||
|
||||
All additional `props` are passed to the `<input type="file">` HTML component.
|
||||
|
||||
```js
|
||||
import {useState} from 'react';
|
||||
const [files, setFiles] = useState([]);
|
||||
|
||||
<FileInput
|
||||
files={files}
|
||||
label="Some file"
|
||||
helpText="Will be uploaded"
|
||||
onChange={event =>setFiles(event.target.files)}
|
||||
/>
|
||||
```
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { useUID } from "react-uid/dist/es5/index";
|
||||
import { useUID } from "react-uid";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { formFieldsSize } from "./constants";
|
||||
@ -21,19 +21,20 @@ Input.propTypes = {
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]),
|
||||
labelClassName: PropTypes.string,
|
||||
groupClassName: PropTypes.string,
|
||||
};
|
||||
|
||||
/** Base bootstrap input component. */
|
||||
export function Input({
|
||||
type, label, helpText, error, className, children, ...props
|
||||
type, label, helpText, error, className, children, labelClassName, groupClassName, ...props
|
||||
}) {
|
||||
const uid = useUID();
|
||||
const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim();
|
||||
return (
|
||||
<div className={formFieldsSize}>
|
||||
<div className="form-group">
|
||||
<label htmlFor={uid}>{label}</label>
|
||||
<div className="input-group">
|
||||
<div className={`form-group ${formFieldsSize}`}>
|
||||
<label className={labelClassName} htmlFor={uid}>{label}</label>
|
||||
<div className={`input-group ${groupClassName || ""}`.trim()}>
|
||||
<input
|
||||
className={inputClassName}
|
||||
type={type}
|
||||
@ -46,6 +47,5 @@ export function Input({
|
||||
{error ? <div className="invalid-feedback">{error}</div> : null}
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -37,11 +37,10 @@ export function Modal({ shown, setShown, children }) {
|
||||
};
|
||||
}, [setShown]);
|
||||
|
||||
|
||||
return (
|
||||
<Portal containerId="modal-container">
|
||||
<div className={`modal fade ${shown ? "show" : ""}`} role="dialog">
|
||||
<div ref={dialogRef} className="modal-dialog" role="document">
|
||||
<div ref={dialogRef} className="modal-dialog modal-dialog-centered" role="document">
|
||||
<div className="modal-content">
|
||||
{children}
|
||||
</div>
|
||||
|
@ -1,6 +1,13 @@
|
||||
Bootstrap modal component.
|
||||
|
||||
I have no idea why example doesn't work here but you can investigate HTML code...
|
||||
it's required to have an element `<div id={"modal-container"}/>` somewhere on the page since modals are rendered in portals.
|
||||
|
||||
```js
|
||||
<div id="modal-container"/>
|
||||
```
|
||||
|
||||
I have no idea why example doesn't work here but you can investigate HTML code and Foris project.
|
||||
|
||||
```js
|
||||
import {ModalHeader, ModalBody, ModalFooter} from './Modal';
|
||||
|
||||
@ -8,7 +15,7 @@ import {useState} from 'react';
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
<>
|
||||
<Modal shown={shown}>
|
||||
<Modal setShown={setShown} shown={shown}>
|
||||
<ModalHeader setShown={setShown} title='Warning!'/>
|
||||
<ModalBody><p>Bla bla bla...</p></ModalBody>
|
||||
<ModalFooter>
|
||||
@ -19,9 +26,8 @@ const [shown, setShown] = useState(false);
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
<button
|
||||
className='btn btn-secondary'
|
||||
onClick={()=>setShown(true)}
|
||||
>Show modal</button>
|
||||
<button className='btn btn-secondary' onClick={()=>setShown(true)}>
|
||||
Show modal
|
||||
</button>
|
||||
</>
|
||||
```
|
||||
|
10
src/bootstrap/NumberInput.css
Normal file
10
src/bootstrap/NumberInput.css
Normal file
@ -0,0 +1,10 @@
|
||||
input[type="number"] {
|
||||
-webkit-appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
input[type=number]::-webkit-inner-spin-button,
|
||||
input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
@ -6,11 +6,11 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { Input } from "./Input";
|
||||
|
||||
export const NumberInput = ({ ...props }) => <Input type="number" {...props} />;
|
||||
import { useConditionalTimeout } from "utils/hooks";
|
||||
import { Input } from "./Input";
|
||||
import "./NumberInput.css";
|
||||
|
||||
NumberInput.propTypes = {
|
||||
/** Field label. */
|
||||
@ -24,4 +24,49 @@ NumberInput.propTypes = {
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
/** Function called when value changes. */
|
||||
onChange: PropTypes.func.isRequired,
|
||||
/** Additional description dispaled to the right of input value. */
|
||||
inlineText: PropTypes.string,
|
||||
};
|
||||
|
||||
NumberInput.defaultProps = {
|
||||
value: 0,
|
||||
};
|
||||
|
||||
export function NumberInput({
|
||||
onChange, inlineText, value, ...props
|
||||
}) {
|
||||
function updateValue(initialValue, difference) {
|
||||
onChange({ target: { value: initialValue + difference } });
|
||||
}
|
||||
|
||||
const enableIncrease = useConditionalTimeout({ callback: updateValue }, value, 1);
|
||||
const enableDecrease = useConditionalTimeout({ callback: updateValue }, value, -1);
|
||||
|
||||
return (
|
||||
<Input type="number" onChange={onChange} value={value} {...props}>
|
||||
<div className="input-group-append">
|
||||
{inlineText && <p className="input-group-text">{inlineText}</p>}
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-secondary"
|
||||
onMouseDown={() => enableIncrease(true)}
|
||||
onMouseUp={() => enableIncrease(false)}
|
||||
aria-label="Increase"
|
||||
>
|
||||
<i className="fas fa-plus" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-secondary"
|
||||
onMouseDown={() => enableDecrease(true)}
|
||||
onMouseUp={() => enableDecrease(false)}
|
||||
aria-label="Decrease"
|
||||
>
|
||||
<i className="fas fa-minus" />
|
||||
</button>
|
||||
</div>
|
||||
</Input>
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ const [value, setValue] = useState(42);
|
||||
helpText="Read the small text!"
|
||||
min='33'
|
||||
max='54'
|
||||
onChange={target => setValue(target.value)}
|
||||
onChange={event =>setValue(event.target.value)}
|
||||
/>
|
||||
```
|
||||
|
@ -12,6 +12,6 @@ const [value, setValue] = useState('secret');
|
||||
value={value}
|
||||
label="Some password"
|
||||
helpText="Read the small text!"
|
||||
onChange={target => setValue(target.value)}
|
||||
onChange={event =>setValue(event.target.value)}
|
||||
/>
|
||||
```
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useUID } from "react-uid/dist/es5/index";
|
||||
import { useUID } from "react-uid";
|
||||
|
||||
import { formFieldsSize } from "./constants";
|
||||
|
||||
|
||||
RadioSet.propTypes = {
|
||||
/** Name attribute of the input HTML tag. */
|
||||
name: PropTypes.string.isRequired,
|
||||
@ -52,16 +51,10 @@ export function RadioSet({
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={`form-group ${formFieldsSize}`} style={{ marginBottom: "1rem" }}>
|
||||
{label
|
||||
? (
|
||||
<label className="col-12" htmlFor={uid} style={{ paddingLeft: "0" }}>
|
||||
{label}
|
||||
</label>
|
||||
)
|
||||
: null}
|
||||
<div className={`form-group ${formFieldsSize}`}>
|
||||
{label && <label htmlFor={uid} className="d-block">{label}</label>}
|
||||
{radios}
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
{helpText && <small className="form-text text-muted">{helpText}</small>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -77,7 +70,7 @@ function Radio({
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<div className="custom-control custom-radio custom-control-inline">
|
||||
<div className={`custom-control custom-radio ${!helpText ? "custom-control-inline" : ""}`.trim()}>
|
||||
<input
|
||||
id={id}
|
||||
className="custom-control-input"
|
||||
@ -86,8 +79,8 @@ function Radio({
|
||||
{...props}
|
||||
/>
|
||||
<label className="custom-control-label" htmlFor={id}>{label}</label>
|
||||
{helpText && <small className="form-text text-muted mt-0 mb-3">{helpText}</small>}
|
||||
</div>
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ Set of radio Bootstrap component input with label and predefined sizes and struc
|
||||
|
||||
All additional `props` are passed to the `<input type="number">` HTML component.
|
||||
|
||||
Unless `helpText` is set for one of the options they are displayed inline.
|
||||
|
||||
```js
|
||||
import {useState} from 'react';
|
||||
const CHOICES=[
|
||||
@ -17,7 +19,7 @@ const [value, setValue] = useState(CHOICES[0].value);
|
||||
value={value}
|
||||
name='some-radio'
|
||||
choices={CHOICES}
|
||||
onChange={event=>setValue(event.target.value)}
|
||||
onChange={event =>setValue(event.target.value)}
|
||||
/>
|
||||
<p>Selected value: {value}</p>
|
||||
</>
|
||||
|
@ -7,8 +7,7 @@
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useUID } from "react-uid/dist/es5/index";
|
||||
|
||||
import { useUID } from "react-uid";
|
||||
|
||||
Select.propTypes = {
|
||||
/** Select field Label. */
|
||||
|
@ -24,18 +24,18 @@ Spinner.defaultProps = {
|
||||
};
|
||||
|
||||
export function Spinner({
|
||||
fullScreen, children, className, ...props
|
||||
fullScreen, children, className,
|
||||
}) {
|
||||
if (!fullScreen) {
|
||||
return (
|
||||
<div className={`spinner-wrapper ${className || ""}`} {...props}>
|
||||
<div className={`spinner-wrapper ${className || "my-3 text-center"}`}>
|
||||
<SpinnerElement>{children}</SpinnerElement>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="spinner-fs-wrapper" {...props}>
|
||||
<div className="spinner-fs-wrapper">
|
||||
<div className="spinner-fs-background">
|
||||
<SpinnerElement>{children}</SpinnerElement>
|
||||
</div>
|
||||
@ -46,6 +46,8 @@ export function Spinner({
|
||||
SpinnerElement.propTypes = {
|
||||
/** Spinner's size */
|
||||
small: PropTypes.bool,
|
||||
/** Additional className */
|
||||
className: PropTypes.string,
|
||||
/** Children components */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
@ -53,13 +55,16 @@ SpinnerElement.propTypes = {
|
||||
]),
|
||||
};
|
||||
|
||||
export function SpinnerElement({ small, children }) {
|
||||
export function SpinnerElement({ small, className, children }) {
|
||||
return (
|
||||
<>
|
||||
<div className={`spinner-border ${small ? "spinner-border-sm" : ""}`} role="status">
|
||||
<div
|
||||
className={`spinner-border ${small ? "spinner-border-sm" : ""} ${className || ""}`.trim()}
|
||||
role="status"
|
||||
>
|
||||
<span className="sr-only" />
|
||||
</div>
|
||||
<div className="spinner-text">{children}</div>
|
||||
{children && <div className="spinner-text">{children}</div>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ import PropTypes from "prop-types";
|
||||
|
||||
import { Input } from "./Input";
|
||||
|
||||
|
||||
export const TextInput = ({ ...props }) => <Input type="text" {...props} />;
|
||||
|
||||
|
||||
TextInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
|
@ -10,6 +10,6 @@ const [value, setValue] = useState('Bla bla');
|
||||
value={value}
|
||||
label="Some text"
|
||||
helpText="Read the small text!"
|
||||
onChange={event => setValue(event.target.value)}
|
||||
onChange={event =>setValue(event.target.value)}
|
||||
/>
|
||||
```
|
||||
|
19
src/bootstrap/__tests__/DownloadButton.test.js
Normal file
19
src/bootstrap/__tests__/DownloadButton.test.js
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { render } from "customTestRender";
|
||||
|
||||
import { DownloadButton } from "../DownloadButton";
|
||||
|
||||
describe("<DownloadButton />", () => {
|
||||
it("should have download attribute", () => {
|
||||
const { container } = render(<DownloadButton href="http://example.com">Test Button</DownloadButton>);
|
||||
expect(container.firstChild.getAttribute("download")).not.toBeNull();
|
||||
});
|
||||
});
|
@ -7,23 +7,39 @@
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { render } from "customTestRender";
|
||||
import { render, fireEvent, getByLabelText, wait } from "customTestRender";
|
||||
|
||||
import { NumberInput } from "../NumberInput";
|
||||
|
||||
|
||||
describe("<NumberInput/>", () => {
|
||||
it("Render number input", () => {
|
||||
const onChangeMock = jest.fn();
|
||||
let componentContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
const { container } = render(
|
||||
<NumberInput
|
||||
label="Test label"
|
||||
helpText="Some help text"
|
||||
value={1123}
|
||||
onChange={() => {
|
||||
}}
|
||||
value={1}
|
||||
onChange={onChangeMock}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild)
|
||||
.toMatchSnapshot();
|
||||
componentContainer = container;
|
||||
});
|
||||
|
||||
it("Render number input", () => {
|
||||
expect(componentContainer.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Increase number with button", async () => {
|
||||
const increaseButton = getByLabelText(componentContainer, "Increase");
|
||||
fireEvent.mouseDown(increaseButton);
|
||||
await wait(() => expect(onChangeMock).toHaveBeenCalledWith({"target": {"value": 2}}));
|
||||
});
|
||||
|
||||
it("Decrease number with button", async () => {
|
||||
const decreaseButton = getByLabelText(componentContainer, "Decrease");
|
||||
fireEvent.mouseDown(decreaseButton);
|
||||
await wait(() => expect(onChangeMock).toHaveBeenCalledWith({"target": {"value": 0}}));
|
||||
});
|
||||
});
|
||||
|
@ -2,12 +2,10 @@
|
||||
|
||||
exports[`<Checkbox/> Render checkbox 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox"
|
||||
style="margin-bottom: 0px;"
|
||||
class="custom-control custom-checkbox "
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
@ -18,27 +16,24 @@ exports[`<Checkbox/> Render checkbox 1`] = `
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="1"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<Checkbox/> Render uncheked checkbox 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox"
|
||||
style="margin-bottom: 0px;"
|
||||
class="custom-control custom-checkbox "
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
@ -48,15 +43,14 @@ exports[`<Checkbox/> Render uncheked checkbox 1`] = `
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="1"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -2,11 +2,8 @@
|
||||
|
||||
exports[`<NumberInput/> Render number input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
@ -19,14 +16,35 @@ exports[`<NumberInput/> Render number input 1`] = `
|
||||
class="form-control"
|
||||
id="1"
|
||||
type="number"
|
||||
value="1123"
|
||||
value="1"
|
||||
/>
|
||||
<div
|
||||
class="input-group-append"
|
||||
>
|
||||
<button
|
||||
aria-label="Increase"
|
||||
class="btn btn-outline-secondary"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="fas fa-plus"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Decrease"
|
||||
class="btn btn-outline-secondary"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="fas fa-minus"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -2,11 +2,8 @@
|
||||
|
||||
exports[`<PasswordInput/> Render password input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
@ -28,6 +25,5 @@ exports[`<PasswordInput/> Render password input 1`] = `
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -3,12 +3,10 @@
|
||||
exports[`<RadioSet/> Render radio set 1`] = `
|
||||
<div
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
>
|
||||
<label
|
||||
class="col-12"
|
||||
class="d-block"
|
||||
for="1"
|
||||
style="padding-left: 0px;"
|
||||
>
|
||||
Radios set label
|
||||
</label>
|
||||
|
@ -2,11 +2,8 @@
|
||||
|
||||
exports[`<TextInput/> Render text input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
@ -27,6 +24,5 @@ exports[`<TextInput/> Render text input 1`] = `
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
77
src/common/RebootButton.js
Normal file
77
src/common/RebootButton.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { useAPIPost } from "api/hooks";
|
||||
import { API_STATE } from "api/utils";
|
||||
import { ForisURLs } from "forisUrls";
|
||||
|
||||
import { Button } from "bootstrap/Button";
|
||||
import {
|
||||
Modal, ModalHeader, ModalBody, ModalFooter,
|
||||
} from "bootstrap/Modal";
|
||||
import { useAlert } from "alertContext/AlertContext";
|
||||
|
||||
RebootButton.propTypes = {
|
||||
forisFormSize: PropTypes.bool,
|
||||
};
|
||||
|
||||
export function RebootButton(props) {
|
||||
const [triggered, setTriggered] = useState(false);
|
||||
const [modalShown, setModalShown] = useState(false);
|
||||
const [triggerRebootStatus, triggerReboot] = useAPIPost(ForisURLs.reboot);
|
||||
|
||||
const [setAlert] = useAlert();
|
||||
useEffect(() => {
|
||||
if (triggerRebootStatus.state === API_STATE.ERROR) {
|
||||
setAlert(_("Reboot request failed."));
|
||||
}
|
||||
});
|
||||
|
||||
function rebootHandler() {
|
||||
setTriggered(true);
|
||||
triggerReboot();
|
||||
setModalShown(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<RebootModal shown={modalShown} setShown={setModalShown} onReboot={rebootHandler} />
|
||||
<Button
|
||||
className="btn-danger"
|
||||
loading={triggered}
|
||||
disabled={triggered}
|
||||
onClick={() => setModalShown(true)}
|
||||
|
||||
{...props}
|
||||
>
|
||||
{_("Reboot")}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
RebootModal.propTypes = {
|
||||
shown: PropTypes.bool.isRequired,
|
||||
setShown: PropTypes.func.isRequired,
|
||||
onReboot: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function RebootModal({ shown, setShown, onReboot }) {
|
||||
return (
|
||||
<Modal shown={shown} setShown={setShown}>
|
||||
<ModalHeader setShown={setShown} title={_("Reboot confirmation")} />
|
||||
<ModalBody><p>{_("Are you sure you want to restart the router?")}</p></ModalBody>
|
||||
<ModalFooter>
|
||||
<Button onClick={() => setShown(false)}>{_("Cancel")}</Button>
|
||||
<Button className="btn-danger" onClick={onReboot}>{_("Confirm reboot")}</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
55
src/common/__tests__/RebootButton.test.js
Normal file
55
src/common/__tests__/RebootButton.test.js
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { fireEvent, getByText, queryByText, render, wait } from "customTestRender";
|
||||
import mockAxios from "jest-mock-axios";
|
||||
import { mockJSONError } from "testUtils/network";
|
||||
import { mockSetAlert } from "testUtils/alertContextMock";
|
||||
|
||||
import { RebootButton } from "../RebootButton";
|
||||
|
||||
describe("<RebootButton/>", () => {
|
||||
let componentContainer;
|
||||
beforeEach(() => {
|
||||
const { container } = render(<>
|
||||
<div id="modal-container"/>
|
||||
<RebootButton/>
|
||||
</>);
|
||||
componentContainer = container;
|
||||
});
|
||||
|
||||
it("Render.", () => {
|
||||
expect(componentContainer)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Render modal.", () => {
|
||||
expect(queryByText(componentContainer, "Confirm reboot"))
|
||||
.toBeNull();
|
||||
fireEvent.click(getByText(componentContainer, "Reboot"));
|
||||
expect(componentContainer)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Confirm reboot.", () => {
|
||||
fireEvent.click(getByText(componentContainer, "Reboot"));
|
||||
fireEvent.click(getByText(componentContainer, "Confirm reboot"));
|
||||
expect(mockAxios.post)
|
||||
.toHaveBeenCalledWith("/reforis/api/reboot", undefined, expect.anything());
|
||||
});
|
||||
|
||||
it("Hold error.", async () => {
|
||||
fireEvent.click(getByText(componentContainer, "Reboot"));
|
||||
fireEvent.click(getByText(componentContainer, "Confirm reboot"));
|
||||
mockJSONError();
|
||||
await wait(() => expect(mockSetAlert)
|
||||
.toBeCalledWith("Reboot request failed."));
|
||||
});
|
||||
|
||||
});
|
94
src/common/__tests__/__snapshots__/RebootButton.test.js.snap
Normal file
94
src/common/__tests__/__snapshots__/RebootButton.test.js.snap
Normal file
@ -0,0 +1,94 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<RebootButton/> Render modal. 1`] = `
|
||||
<div>
|
||||
<div
|
||||
id="modal-container"
|
||||
>
|
||||
<div
|
||||
class="modal fade show"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-dialog modal-dialog-centered"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
>
|
||||
<h5
|
||||
class="modal-title"
|
||||
>
|
||||
Reboot confirmation
|
||||
</h5>
|
||||
<button
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to restart the router?
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary "
|
||||
type="button"
|
||||
>
|
||||
|
||||
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
>
|
||||
|
||||
|
||||
Confirm reboot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
>
|
||||
|
||||
|
||||
Reboot
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<RebootButton/> Render. 1`] = `
|
||||
<div>
|
||||
<div
|
||||
id="modal-container"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
>
|
||||
|
||||
|
||||
Reboot
|
||||
</button>
|
||||
</div>
|
||||
`;
|
@ -1,9 +1,18 @@
|
||||
export const REFORIS_URL_PREFIX = process.env.LIGHTTPD ? "/reforis" : "";
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
export const REFORIS_URL_PREFIX = "/reforis";
|
||||
export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
|
||||
|
||||
export const ForisURLs = {
|
||||
login: `${REFORIS_URL_PREFIX}/login`,
|
||||
static: `${REFORIS_URL_PREFIX}/static/reforis`,
|
||||
wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
|
||||
|
||||
packageManagement: {
|
||||
updateSettings: `${REFORIS_URL_PREFIX}/package-management/update-settings`,
|
||||
updates: `${REFORIS_URL_PREFIX}/package-management/updates`,
|
||||
@ -14,4 +23,7 @@ export const ForisURLs = {
|
||||
notificationsSettings: "/administration/notifications-settings",
|
||||
|
||||
luci: "/cgi-bin/luci",
|
||||
|
||||
// API
|
||||
reboot: `${REFORIS_API_URL_PREFIX}/reboot`,
|
||||
};
|
||||
|
@ -5,26 +5,31 @@
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Spinner } from "bootstrap/Spinner";
|
||||
import { useAPIPost } from "api/hooks";
|
||||
|
||||
import { Prompt } from "react-router";
|
||||
import { API_STATE } from "api/utils";
|
||||
import { ErrorMessage } from "utils/ErrorMessage";
|
||||
import { useAlert } from "alertContext/AlertContext";
|
||||
import { ALERT_TYPES } from "bootstrap/Alert";
|
||||
import { useForisModule, useForm } from "../hooks";
|
||||
import { STATES as SUBMIT_BUTTON_STATES, SubmitButton } from "./SubmitButton";
|
||||
import { FailAlert, SuccessAlert } from "./alerts";
|
||||
|
||||
ForisForm.propTypes = {
|
||||
/** WebSocket object see `scr/common/WebSockets.js`. */
|
||||
/** Optional WebSocket object. See `scr/common/WebSockets.js`.
|
||||
* `forisConfig.wsModule` should be specified when it's passed.
|
||||
* */
|
||||
ws: PropTypes.object,
|
||||
/** Foris configuration object. See usage in main components. */
|
||||
forisConfig: PropTypes.shape({
|
||||
/** reForis Flask aplication API endpoint from `src/common/API.js`. */
|
||||
endpoint: PropTypes.string.isRequired,
|
||||
/** `foris-controller` module name to be used via WebSockets.
|
||||
* If it's not passed then WebSockets aren't used
|
||||
* It can be use only with `ws` prop.
|
||||
* */
|
||||
wsModule: PropTypes.string,
|
||||
/** `foris-controller` action name to be used via WebSockets.
|
||||
@ -46,6 +51,17 @@ ForisForm.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
/** Optional override of form submit callback */
|
||||
onSubmitOverridden: PropTypes.func,
|
||||
|
||||
// eslint-disable-next-line react/no-unused-prop-types
|
||||
customWSProp(props) {
|
||||
const wsModuleIsSpecified = !!(props.forisConfig && props.forisConfig.wsModule);
|
||||
if (props.ws && !wsModuleIsSpecified) {
|
||||
return new Error("forisConfig.wsModule should be specified when ws object is passed.");
|
||||
}
|
||||
if (!props.ws && wsModuleIsSpecified) {
|
||||
return new Error("forisConfig.wsModule is specified without passing ws object.");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
ForisForm.defaultProps = {
|
||||
@ -69,39 +85,53 @@ export function ForisForm({
|
||||
children,
|
||||
}) {
|
||||
const [formState, onFormChangeHandler, resetFormData] = useForm(validator, prepData);
|
||||
const [setAlert] = useAlert();
|
||||
|
||||
const [forisModuleState] = useForisModule(ws, forisConfig);
|
||||
useEffect(() => {
|
||||
if (forisModuleState.data) {
|
||||
if (forisModuleState.state === API_STATE.SUCCESS) {
|
||||
resetFormData(forisModuleState.data);
|
||||
}
|
||||
}, [forisModuleState.data, resetFormData, prepData]);
|
||||
}, [forisModuleState, resetFormData, prepData]);
|
||||
|
||||
const [postState, post] = useAPIPost(forisConfig.endpoint);
|
||||
useEffect(() => {
|
||||
if (postState.isSuccess) postCallback();
|
||||
}, [postCallback, postState.isSuccess]);
|
||||
if (postState.state === API_STATE.SUCCESS) {
|
||||
postCallback();
|
||||
setAlert(_("Settings saved successfully"), ALERT_TYPES.SUCCESS);
|
||||
} else if (postState.state === API_STATE.ERROR) {
|
||||
setAlert(postState.data);
|
||||
}
|
||||
}, [postCallback, postState.state, postState.data, setAlert]);
|
||||
|
||||
if (forisModuleState.state === API_STATE.ERROR) {
|
||||
return <ErrorMessage />;
|
||||
}
|
||||
if (!formState.data) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
function onSubmitHandler(e) {
|
||||
e.preventDefault();
|
||||
function onSubmitHandler(event) {
|
||||
event.preventDefault();
|
||||
resetFormData();
|
||||
const copiedFormData = JSON.parse(JSON.stringify(formState.data));
|
||||
const preparedData = prepDataToSubmit(copiedFormData);
|
||||
post(preparedData);
|
||||
post({ data: preparedData });
|
||||
}
|
||||
|
||||
function getSubmitButtonState() {
|
||||
if (postState.isSending) return SUBMIT_BUTTON_STATES.SAVING;
|
||||
if (forisModuleState.isLoading) return SUBMIT_BUTTON_STATES.LOAD;
|
||||
if (postState.state === API_STATE.SENDING) {
|
||||
return SUBMIT_BUTTON_STATES.SAVING;
|
||||
}
|
||||
if (forisModuleState.state === API_STATE.SENDING) {
|
||||
return SUBMIT_BUTTON_STATES.LOAD;
|
||||
}
|
||||
return SUBMIT_BUTTON_STATES.READY;
|
||||
}
|
||||
|
||||
const [alertIsDismissed, setAlertIsDismissed] = useState(false);
|
||||
|
||||
if (!formState.data) return <Spinner className="row justify-content-center" />;
|
||||
|
||||
const formIsDisabled = disabled || forisModuleState.isLoading || postState.isSending;
|
||||
const formIsDisabled = (disabled
|
||||
|| forisModuleState.state === API_STATE.SENDING
|
||||
|| postState.state === API_STATE.SENDING);
|
||||
const submitButtonIsDisabled = disabled || !!formState.errors;
|
||||
|
||||
const childrenWithFormProps = React.Children.map(
|
||||
@ -123,19 +153,9 @@ export function ForisForm({
|
||||
return _("Changes you made may not be saved. Are you sure you want to leave?");
|
||||
}
|
||||
|
||||
let alert = null;
|
||||
if (!alertIsDismissed) {
|
||||
if (postState.isSuccess) {
|
||||
alert = <SuccessAlert onDismiss={() => setAlertIsDismissed(true)} />;
|
||||
} else if (postState.isError) {
|
||||
alert = <FailAlert onDismiss={() => setAlertIsDismissed(true)} />;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Prompt message={getMessageOnLeavingPage} />
|
||||
{alert}
|
||||
<form onSubmit={onSubmit}>
|
||||
{childrenWithFormProps}
|
||||
<SubmitButton
|
||||
|
73
src/form/components/ForisForm.md
Normal file
73
src/form/components/ForisForm.md
Normal file
@ -0,0 +1,73 @@
|
||||
`<ForisForm/>` is Higher-Order Component which encapsulates entire form logic and provides with children required props.
|
||||
This component structure provides comfort API and allows to create typical Foris module forms easily.
|
||||
|
||||
## Example of usage of `<ForisForm/>`
|
||||
You can pass more forms as children.
|
||||
```js
|
||||
<ForisForm
|
||||
ws={ws}
|
||||
forisConfig={{
|
||||
endpoint: API_URLs.wan,
|
||||
wsModule: "wan",
|
||||
}}
|
||||
prepData={prepData}
|
||||
prepDataToSubmit={prepDataToSubmit}
|
||||
validator={validator}
|
||||
>
|
||||
<WANForm />
|
||||
<WAN6Form />
|
||||
<MACForm />
|
||||
</ForisForm>
|
||||
```
|
||||
|
||||
### Example of children forms `props` usage
|
||||
|
||||
```js
|
||||
export default function MACForm({
|
||||
formData, formErrors, setFormValue, ...props
|
||||
}) {
|
||||
const macSettings = formData.mac_settings;
|
||||
const errors = (formErrors || {}).mac_settings || {};
|
||||
return (
|
||||
<>
|
||||
<h3>{_("MAC")}</h3>
|
||||
<CheckBox
|
||||
label={_("Custom MAC address")}
|
||||
checked={macSettings.custom_mac_enabled}
|
||||
helpText={HELP_TEXTS.custom_mac_enabled}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({ mac_settings: { custom_mac_enabled: { $set: value } } }),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
{macSettings.custom_mac_enabled
|
||||
? (
|
||||
<TextInput
|
||||
label={_("MAC address")}
|
||||
value={macSettings.custom_mac || ""}
|
||||
helpText={HELP_TEXTS.custom_mac}
|
||||
error={errors.custom_mac}
|
||||
required
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({ mac_settings: { custom_mac: { $set: value } } }),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
The <ForisForm/> passes subsequent `props` to the child components.
|
||||
|
||||
| Prop | Type | Description |
|
||||
|----------------|--------|----------------------------------------------------------------------------|
|
||||
| `formData` | object | Data returned from API. |
|
||||
| `formErrors` | object | Errors returned after validation via validator. |
|
||||
| `setFormValue` | func | Function for data update. It takes update rule as arg (see example above). |
|
||||
| `disabled` | bool | Flag to disable form elements (during updates or loadings e.t.c.). |
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Alert } from "bootstrap/Alert";
|
||||
import { Portal } from "utils/Portal";
|
||||
|
||||
SuccessAlert.propTypes = {
|
||||
onDismiss: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const ALERT_CONTAINER_ID = "alert-container";
|
||||
|
||||
export function SuccessAlert({ onDismiss }) {
|
||||
return (
|
||||
<Portal containerId={ALERT_CONTAINER_ID}>
|
||||
<Alert
|
||||
type="success"
|
||||
message={_("Settings were successfully saved.")}
|
||||
onDismiss={onDismiss}
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
FailAlert.propTypes = {
|
||||
onDismiss: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export function FailAlert({ onDismiss }) {
|
||||
return (
|
||||
<Portal containerId={ALERT_CONTAINER_ID}>
|
||||
<Alert
|
||||
type="danger"
|
||||
message={_("Settings update was failed.")}
|
||||
onDismiss={onDismiss}
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
}
|
@ -11,13 +11,12 @@ import update from "immutability-helper";
|
||||
import { useAPIGet } from "api/hooks";
|
||||
import { useWSForisModule } from "webSockets/hooks";
|
||||
|
||||
|
||||
const FORM_ACTIONS = {
|
||||
updateValue: 1,
|
||||
resetData: 2,
|
||||
};
|
||||
|
||||
export function useForm(validator, prepData) {
|
||||
export function useForm(validator, dataPreprocessor) {
|
||||
const [state, dispatch] = useReducer(formReducer, {
|
||||
data: null,
|
||||
initialData: null,
|
||||
@ -28,10 +27,10 @@ export function useForm(validator, prepData) {
|
||||
dispatch({
|
||||
type: FORM_ACTIONS.resetData,
|
||||
data,
|
||||
prepData,
|
||||
dataPreprocessor,
|
||||
validator,
|
||||
});
|
||||
}, [prepData, validator]);
|
||||
}, [dataPreprocessor, validator]);
|
||||
|
||||
const onFormChangeHandler = useCallback((updateRule) => (event) => {
|
||||
dispatch({
|
||||
@ -41,6 +40,7 @@ export function useForm(validator, prepData) {
|
||||
validator,
|
||||
});
|
||||
}, [validator]);
|
||||
|
||||
return [
|
||||
state,
|
||||
onFormChangeHandler,
|
||||
@ -48,7 +48,6 @@ export function useForm(validator, prepData) {
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
function formReducer(state, action) {
|
||||
switch (action.type) {
|
||||
case FORM_ACTIONS.updateValue: {
|
||||
@ -61,12 +60,15 @@ function formReducer(state, action) {
|
||||
};
|
||||
}
|
||||
case FORM_ACTIONS.resetData: {
|
||||
if (!action.data) return { ...state, initialData: state.data };
|
||||
const prepData = action.prepData ? action.prepData(action.data) : action.data;
|
||||
if (!action.data) {
|
||||
return { ...state, initialData: state.data };
|
||||
}
|
||||
|
||||
const data = action.dataPreprocessor ? action.dataPreprocessor(action.data) : action.data;
|
||||
return {
|
||||
data: prepData,
|
||||
initialData: prepData,
|
||||
errors: action.data ? action.validator(prepData) : undefined,
|
||||
data,
|
||||
initialData: data,
|
||||
errors: action.data ? action.validator(data) : undefined,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
@ -82,6 +84,9 @@ function getChangedValue(target) {
|
||||
} else if (target.type === "number") {
|
||||
const parsedValue = parseInt(value);
|
||||
value = Number.isNaN(parsedValue) ? value : parsedValue;
|
||||
} else if (target.type === "file") {
|
||||
// Return first file (we don't need multiple yet)
|
||||
[value] = target.files;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
34
src/index.js
34
src/index.js
@ -1,19 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
// API
|
||||
export { useAPIGet, useAPIPost } from "./api/hooks";
|
||||
export {
|
||||
useAPIGet,
|
||||
useAPIPost,
|
||||
useAPIPatch,
|
||||
useAPIPut,
|
||||
useAPIDelete,
|
||||
useAPIPolling,
|
||||
} from "api/hooks";
|
||||
export { API_STATE } from "api/utils";
|
||||
|
||||
// Bootstrap
|
||||
export { Alert } from "bootstrap/Alert";
|
||||
export { Alert, ALERT_TYPES } from "bootstrap/Alert";
|
||||
export { Button } from "bootstrap/Button";
|
||||
export { CheckBox } from "bootstrap/CheckBox";
|
||||
export { formFieldsSize } from "bootstrap/constants";
|
||||
export { DownloadButton } from "bootstrap/DownloadButton";
|
||||
export { DataTimeInput } from "bootstrap/DataTimeInput";
|
||||
export { EmailInput } from "bootstrap/EmailInput";
|
||||
export { FileInput } from "bootstrap/FileInput";
|
||||
export { Input } from "bootstrap/Input";
|
||||
export { NumberInput } from "bootstrap/NumberInput";
|
||||
export { PasswordInput } from "bootstrap/PasswordInput";
|
||||
export { RadioSet } from "bootstrap/RadioSet";
|
||||
export { Select } from "bootstrap/Select";
|
||||
export { TextInput } from "bootstrap/TextInput";
|
||||
export { formFieldsSize } from "bootstrap/constants";
|
||||
|
||||
export {
|
||||
Spinner,
|
||||
@ -26,6 +43,9 @@ export {
|
||||
ModalHeader,
|
||||
} from "bootstrap/Modal";
|
||||
|
||||
// Common
|
||||
export { RebootButton } from "common/RebootButton";
|
||||
|
||||
// Form
|
||||
export { ForisForm } from "form/components/ForisForm";
|
||||
export { SubmitButton, STATES as SUBMIT_BUTTON_STATES } from "form/components/SubmitButton";
|
||||
@ -37,6 +57,11 @@ export { WebSockets } from "webSockets/WebSockets";
|
||||
|
||||
// Utils
|
||||
export { Portal } from "utils/Portal";
|
||||
export { undefinedIfEmpty, withoutUndefinedKeys, onlySpecifiedKeys } from "utils/objectHelpers";
|
||||
export {
|
||||
withEither, withSpinner, withSending, withSpinnerOnSending, withError, withErrorMessage,
|
||||
} from "utils/conditionalHOCs";
|
||||
export { ErrorMessage } from "utils/ErrorMessage";
|
||||
|
||||
// Foris URL
|
||||
export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls";
|
||||
@ -51,3 +76,6 @@ export {
|
||||
validateMAC,
|
||||
validateMultipleEmails,
|
||||
} from "validations";
|
||||
|
||||
// Alert context
|
||||
export { AlertContextProvider, useAlert } from "alertContext/AlertContext";
|
||||
|
23
src/testUtils/alertContextMock.js
Normal file
23
src/testUtils/alertContextMock.js
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
const mockSetAlert = jest.fn();
|
||||
const mockDismissAlert = jest.fn();
|
||||
|
||||
window.AlertContext = React.createContext();
|
||||
|
||||
function AlertContextMock({ children }) {
|
||||
return (
|
||||
<AlertContext.Provider value={[mockSetAlert, mockDismissAlert]}>
|
||||
{ children }
|
||||
</AlertContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export { AlertContextMock, mockSetAlert, mockDismissAlert };
|
@ -7,31 +7,37 @@
|
||||
|
||||
/* eslint import/export: "off" */
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {UIDReset} from 'react-uid';
|
||||
import {StaticRouter} from 'react-router';
|
||||
import {render} from '@testing-library/react'
|
||||
import React from "react";
|
||||
import { UIDReset } from "react-uid";
|
||||
import { StaticRouter } from "react-router";
|
||||
import { render } from "@testing-library/react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { AlertContextMock } from "./alertContextMock";
|
||||
|
||||
Wrapper.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
])
|
||||
PropTypes.node,
|
||||
]),
|
||||
};
|
||||
|
||||
function Wrapper({children}) {
|
||||
return <StaticRouter>
|
||||
function Wrapper({ children }) {
|
||||
return (
|
||||
<AlertContextMock>
|
||||
<StaticRouter>
|
||||
<UIDReset>
|
||||
{children}
|
||||
</UIDReset>
|
||||
</StaticRouter>
|
||||
</AlertContextMock>
|
||||
);
|
||||
}
|
||||
|
||||
const customTestRender = (ui, options) => render(ui, {wrapper: Wrapper, ...options});
|
||||
const customTestRender = (ui, options) => render(ui, { wrapper: Wrapper, ...options });
|
||||
|
||||
// re-export everything
|
||||
export * from '@testing-library/react'
|
||||
export * from "@testing-library/react";
|
||||
|
||||
// override render method
|
||||
export {customTestRender as render}
|
||||
export { customTestRender as render };
|
||||
|
12
src/testUtils/network.js
Normal file
12
src/testUtils/network.js
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import mockAxios from 'jest-mock-axios';
|
||||
|
||||
export function mockJSONError(data) {
|
||||
mockAxios.mockError({ response: { data, headers: { "content-type": "application/json" } } });
|
||||
}
|
@ -15,12 +15,15 @@ global.afterEach(() => {
|
||||
|
||||
// Mock babel (gettext)
|
||||
global._ = str => str;
|
||||
global.ngettext = str => str;
|
||||
global.babel = {format: (str) => str};
|
||||
global.ForisTranslations = {};
|
||||
|
||||
// Mock web sockets
|
||||
window.WebSocket = jest.fn();
|
||||
|
||||
// Mock scrollIntoView
|
||||
global.HTMLElement.prototype.scrollIntoView = () => {
|
||||
};
|
||||
global.HTMLElement.prototype.scrollIntoView = () => {};
|
||||
|
||||
jest.doMock('moment', () => {
|
||||
moment.tz.setDefault('UTC');
|
||||
|
16
src/utils/ErrorMessage.js
Normal file
16
src/utils/ErrorMessage.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
export function ErrorMessage() {
|
||||
return (
|
||||
<p className="text-center text-danger">
|
||||
{_("An error occurred while fetching data.")}
|
||||
</p>
|
||||
);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`conditional HOCs withError should render error message 1`] = `
|
||||
<div>
|
||||
<p
|
||||
class="text-center text-danger"
|
||||
>
|
||||
An error occurred while fetching data.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`conditional HOCs withErrorMessage should render error message 1`] = `
|
||||
<div>
|
||||
<p
|
||||
class="text-center text-danger"
|
||||
>
|
||||
An error occurred while fetching data.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`conditional HOCs withSpinner should render spinner 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="spinner-wrapper my-3 text-center"
|
||||
>
|
||||
<div
|
||||
class="spinner-border"
|
||||
role="status"
|
||||
>
|
||||
<span
|
||||
class="sr-only"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`conditional HOCs withSpinnerOnSending should render spinner 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="spinner-wrapper my-3 text-center"
|
||||
>
|
||||
<div
|
||||
class="spinner-border"
|
||||
role="status"
|
||||
>
|
||||
<span
|
||||
class="sr-only"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
110
src/utils/__tests__/conditionalHOCs.test.js
Normal file
110
src/utils/__tests__/conditionalHOCs.test.js
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render } from "customTestRender";
|
||||
import {
|
||||
withEither, withSpinner, withSending, withSpinnerOnSending, withError, withErrorMessage,
|
||||
} from "../conditionalHOCs";
|
||||
import { API_STATE } from "api/utils";
|
||||
|
||||
describe("conditional HOCs", () => {
|
||||
const First = () => <p>First</p>;
|
||||
const Alternative = () => <p>Alternative</p>;
|
||||
|
||||
describe("withEither", () => {
|
||||
it("should render First component", () => {
|
||||
const withAlternative = withEither(() => false, Alternative);
|
||||
const FirstWithConditional = withAlternative(First);
|
||||
const { getByText } = render(<FirstWithConditional />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render Alternative component", () => {
|
||||
const withAlternative = withEither(() => true, Alternative);
|
||||
const FirstWithConditional = withAlternative(First);
|
||||
const { getByText } = render(<FirstWithConditional />);
|
||||
expect(getByText("Alternative")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withSpinner", () => {
|
||||
it("should render First component", () => {
|
||||
const withSpinnerHidden = withSpinner(() => false);
|
||||
const FirstWithConditional = withSpinnerHidden(First);
|
||||
const { getByText } = render(<FirstWithConditional />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render spinner", () => {
|
||||
const withSpinnerVisible = withSpinner(() => true);
|
||||
const FirstWithConditional = withSpinnerVisible(First);
|
||||
const { container } = render(<FirstWithConditional />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withSending", () => {
|
||||
it("should render First component", () => {
|
||||
const withAlternative = withSending(Alternative);
|
||||
const FirstWithConditional = withAlternative(First);
|
||||
const { getByText } = render(<FirstWithConditional apiState={API_STATE.SUCCESS} />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render Alternative component", () => {
|
||||
const withAlternative = withSending(Alternative);
|
||||
const FirstWithConditional = withAlternative(First);
|
||||
const { getByText } = render(<FirstWithConditional apiState={API_STATE.SENDING} />);
|
||||
expect(getByText("Alternative")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withSpinnerOnSending", () => {
|
||||
it("should render First component", () => {
|
||||
const FirstWithConditional = withSpinnerOnSending(First);
|
||||
const { getByText } = render(<FirstWithConditional apiState={API_STATE.SUCCESS} />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render spinner", () => {
|
||||
const FirstWithConditional = withSpinnerOnSending(First);
|
||||
const { container } = render(<FirstWithConditional apiState={API_STATE.SENDING} />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withError", () => {
|
||||
it("should render First component", () => {
|
||||
const withErrorHidden = withError(() => false);
|
||||
const FirstWithConditional = withErrorHidden(First);
|
||||
const { getByText } = render(<FirstWithConditional />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render error message", () => {
|
||||
const withErrorVisible = withError(() => true);
|
||||
const FirstWithConditional = withErrorVisible(First);
|
||||
const { container } = render(<FirstWithConditional />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withErrorMessage", () => {
|
||||
it("should render First component", () => {
|
||||
const FirstWithConditional = withErrorMessage(First);
|
||||
const { getByText } = render(<FirstWithConditional apiState={API_STATE.SUCCESS} />);
|
||||
expect(getByText("First")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should render error message", () => {
|
||||
const FirstWithConditional = withErrorMessage(First);
|
||||
const { container } = render(<FirstWithConditional apiState={API_STATE.ERROR} />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
52
src/utils/conditionalHOCs.js
Normal file
52
src/utils/conditionalHOCs.js
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { Spinner } from "bootstrap/Spinner";
|
||||
import { API_STATE } from "api/utils";
|
||||
import { ErrorMessage } from "./ErrorMessage";
|
||||
|
||||
function withEither(conditionalFn, Either) {
|
||||
return (Component) => (props) => {
|
||||
if (conditionalFn(props)) {
|
||||
return <Either {...props} />;
|
||||
}
|
||||
return <Component {...props} />;
|
||||
};
|
||||
}
|
||||
|
||||
// Loading
|
||||
|
||||
function isSending(props) {
|
||||
if (Array.isArray(props.apiState)) {
|
||||
return props.apiState.some(
|
||||
(state) => [API_STATE.INIT, API_STATE.SENDING].includes(state),
|
||||
);
|
||||
}
|
||||
return [API_STATE.INIT, API_STATE.SENDING].includes(props.apiState);
|
||||
}
|
||||
|
||||
const withSpinner = (conditionalFn) => withEither(conditionalFn, Spinner);
|
||||
const withSending = (Either) => withEither(isSending, Either);
|
||||
const withSpinnerOnSending = withSpinner(isSending);
|
||||
|
||||
// Error handling
|
||||
|
||||
const withError = (conditionalFn) => withEither(conditionalFn, ErrorMessage);
|
||||
const withErrorMessage = withError(
|
||||
(props) => {
|
||||
if (Array.isArray(props.apiState)) {
|
||||
return props.apiState.includes(API_STATE.ERROR);
|
||||
}
|
||||
return props.apiState === API_STATE.ERROR;
|
||||
},
|
||||
);
|
||||
|
||||
export {
|
||||
withEither, withSpinner, withSending, withSpinnerOnSending, withError, withErrorMessage,
|
||||
};
|
20
src/utils/hooks.js
Normal file
20
src/utils/hooks.js
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
/** Execute callback when condition is set to true. */
|
||||
export function useConditionalTimeout({ callback, timeout = 125 }, ...callbackArgs) {
|
||||
const [condition, setCondition] = useState(false);
|
||||
useEffect(() => {
|
||||
if (condition) {
|
||||
const interval = setTimeout(() => callback(...callbackArgs), timeout);
|
||||
return () => setTimeout(interval);
|
||||
}
|
||||
}, [condition, callback, timeout, callbackArgs]);
|
||||
return setCondition;
|
||||
}
|
35
src/utils/objectHelpers.js
Normal file
35
src/utils/objectHelpers.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
/** Return undefined if object has no keys, otherwise return object. */
|
||||
export function undefinedIfEmpty(instance) {
|
||||
if (Object.keys(instance).length > 0) {
|
||||
return instance;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Return object without keys that have undefined value. */
|
||||
export function withoutUndefinedKeys(instance) {
|
||||
return Object.keys(instance).reduce(
|
||||
(accumulator, key) => {
|
||||
if (instance[key] !== undefined) {
|
||||
accumulator[key] = instance[key];
|
||||
}
|
||||
return accumulator;
|
||||
},
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
/** Return copy of passed object that has only desired keys. */
|
||||
export function onlySpecifiedKeys(object, desiredKeys) {
|
||||
return desiredKeys.reduce(
|
||||
(accumulator, key) => { accumulator[key] = object[key]; return accumulator; },
|
||||
{},
|
||||
);
|
||||
}
|
@ -29,7 +29,6 @@ const REs = {
|
||||
MultipleEmails: /^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+ *)( *, *[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+ *)*$/,
|
||||
};
|
||||
|
||||
|
||||
const createValidator = (fieldType) => (value) => {
|
||||
if (value && value !== "") return REs[fieldType].test(value) ? undefined : ERROR_MESSAGES[fieldType];
|
||||
};
|
||||
|
@ -61,9 +61,36 @@ export class WebSockets {
|
||||
return this;
|
||||
}
|
||||
|
||||
subscribe(params) {
|
||||
subscribe(module) {
|
||||
this.waitForConnection(() => {
|
||||
this.send("subscribe", params);
|
||||
this.send("subscribe", module);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
unbind(module, action, callback) {
|
||||
const callbacks = this.callbacks[module][action];
|
||||
|
||||
const index = callbacks.indexOf(callback);
|
||||
if (index !== -1) {
|
||||
callbacks.splice(index, 1);
|
||||
}
|
||||
|
||||
if (callbacks.length === 0) {
|
||||
delete this.callbacks[module][action];
|
||||
}
|
||||
|
||||
if (Object.keys(this.callbacks[module]).length === 0) {
|
||||
this.unsubscribe(module);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
unsubscribe(module) {
|
||||
this.waitForConnection(() => {
|
||||
this.send("unsubscribe", module);
|
||||
delete this.callbacks[module];
|
||||
});
|
||||
return this;
|
||||
}
|
||||
@ -82,15 +109,15 @@ export class WebSockets {
|
||||
let chain;
|
||||
try {
|
||||
chain = this.callbacks[json.module][json.action];
|
||||
} catch (e) {
|
||||
if (e instanceof TypeError) {
|
||||
console.log(`Callback for this message wasn't found:${e.data}`);
|
||||
} else throw e;
|
||||
} catch (error) {
|
||||
if (error instanceof TypeError) {
|
||||
console.log(`Callback for this message wasn't found:${error.data}`);
|
||||
} else throw error;
|
||||
}
|
||||
|
||||
if (typeof chain === "undefined") return;
|
||||
|
||||
for (let i = 0; i < chain.length; i++) chain[i](json);
|
||||
chain.forEach((callback) => callback(json));
|
||||
}
|
||||
|
||||
close() {
|
||||
|
@ -11,12 +11,21 @@ export function useWSForisModule(ws, module, action = "update_settings") {
|
||||
const [data, setData] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ws && module) {
|
||||
ws.subscribe(module)
|
||||
.bind(module, action, (msg) => {
|
||||
// Sometimes we want to disable this hook if WS is not passed. We can't make conditional
|
||||
// hooks, but we can disable it here. It's used especially in ForisForm when a module
|
||||
// doesn't present any WS endpoint.
|
||||
if (!ws) return;
|
||||
|
||||
function callback(msg) {
|
||||
setData(msg.data);
|
||||
});
|
||||
}
|
||||
|
||||
ws.subscribe(module)
|
||||
.bind(module, action, callback);
|
||||
|
||||
return () => {
|
||||
ws.unbind(module, action, callback);
|
||||
};
|
||||
}, [action, module, ws]);
|
||||
|
||||
return [data];
|
||||
|
60
styleguide.config.js
Normal file
60
styleguide.config.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
title: "Foris JS docs",
|
||||
sections: [
|
||||
{
|
||||
name: "Foris JS",
|
||||
content: "docs/intro.md",
|
||||
},
|
||||
{
|
||||
name: "Foris forms",
|
||||
components: [
|
||||
"src/form/components/ForisForm.js",
|
||||
"src/form/components/alerts.js",
|
||||
"src/form/components/SubmitButton.js",
|
||||
],
|
||||
exampleMode: "expand",
|
||||
usageMode: "expand",
|
||||
},
|
||||
{
|
||||
name: "Bootstrap components",
|
||||
description: "Set of bootstrap components.",
|
||||
components: "src/bootstrap/*.js",
|
||||
exampleMode: "expand",
|
||||
usageMode: "expand",
|
||||
ignore: [
|
||||
"src/bootstrap/constants.js",
|
||||
],
|
||||
},
|
||||
],
|
||||
require: [
|
||||
"babel-polyfill",
|
||||
path.join(__dirname, "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(__dirname, "node_modules/@fortawesome/fontawesome-free/css/all.min.css"),
|
||||
],
|
||||
webpackConfig: {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "babel-loader",
|
||||
}, {
|
||||
test: /\.css$/,
|
||||
use: ["style-loader", "css-loader"],
|
||||
}, {
|
||||
test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,
|
||||
loader: "file-loader",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
# Translations template for PROJECT.
|
||||
# Czech translations for PROJECT.
|
||||
# Copyright (C) 2019 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
@ -7,22 +7,21 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"PO-Revision-Date: 2019-08-28 12:55+0000\n"
|
||||
"Last-Translator: Stepan Henek <stepan+github@henek.name>\n"
|
||||
"Language-Team: Czech <https://hosted.weblate.org/projects/turris/foris-js/cs/"
|
||||
">\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-11-21 17:04+0000\n"
|
||||
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>\n"
|
||||
"Language: cs\n"
|
||||
"Language-Team: Czech <https://hosted.weblate.org/projects/turris/foris-"
|
||||
"js/cs/>\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 3.9-dev\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
msgstr "Tohle není platná IPv4 adresa."
|
||||
msgstr "Toto není platná IPv4 adresa."
|
||||
|
||||
#: src/validations.js:14
|
||||
msgid "This is not a valid IPv6 address."
|
||||
@ -30,11 +29,11 @@ msgstr "Tohle není platná IPv6 adresa."
|
||||
|
||||
#: src/validations.js:15
|
||||
msgid "This is not a valid IPv6 prefix."
|
||||
msgstr "Tohle není platný IPv6 prefix."
|
||||
msgstr "Toto není platný IPv6 prefix."
|
||||
|
||||
#: src/validations.js:16
|
||||
msgid "This is not a valid domain name."
|
||||
msgstr "Tohle není platné doménové jméno."
|
||||
msgstr "Toto není platné doménové jméno."
|
||||
|
||||
#: src/validations.js:17
|
||||
msgid "This is not a valid DUID."
|
||||
@ -42,13 +41,61 @@ msgstr "Tohle není platné DUID."
|
||||
|
||||
#: src/validations.js:18
|
||||
msgid "This is not a valid MAC address."
|
||||
msgstr "Tohle není platná MAC adresa."
|
||||
msgstr "Toto není platná MAC adresa."
|
||||
|
||||
#: src/validations.js:19
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr "Neobsahuje seznam e-mailů oddělených čárkou."
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr "Platnost relace skončila. Přihlaste se znovu."
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr "Došlo k chybě kvůli překročení časového limitu."
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr "Neobdržena žádná odezva."
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr "Došlo k neznámé chybě. Další informace naleznete v konzoli."
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr "Došlo k neznámé chybě v aplikačním programovém rozhraní."
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr "Nastavení úspěšně uložena"
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
"Změny, které byly provedeny, nebyly uloženy. Jste si jistý, že chcete "
|
||||
@ -66,10 +113,25 @@ msgstr "Načítám nastavení"
|
||||
msgid "Save"
|
||||
msgstr "Uložit"
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
msgstr "Nastavení bylo úspěšně uloženo."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr "Došlo k chybě při získávání dat."
|
||||
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr "Nastavení bylo úspěšně uloženo."
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr "Ukládání nastavení selhalo."
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr "Ukládání nastavení selhalo."
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: da\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: de\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: el\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:21+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: en\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
128
translations/es/LC_MESSAGES/forisjs.po
Normal file
128
translations/es/LC_MESSAGES/forisjs.po
Normal file
@ -0,0 +1,128 @@
|
||||
# Spanish translations for PROJECT.
|
||||
# Copyright (C) 2019 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language: es\n"
|
||||
"Language-Team: none\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:14
|
||||
msgid "This is not a valid IPv6 address."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:15
|
||||
msgid "This is not a valid IPv6 prefix."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:16
|
||||
msgid "This is not a valid domain name."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:17
|
||||
msgid "This is not a valid DUID."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:18
|
||||
msgid "This is not a valid MAC address."
|
||||
msgstr ""
|
||||
|
||||
#: src/validations.js:19
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/SubmitButton.js:32
|
||||
msgid "Updating"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/SubmitButton.js:35
|
||||
msgid "Load settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/SubmitButton.js:38
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: fi\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: fo\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -45,7 +45,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -61,11 +109,7 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:54+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: fr\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: hr\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -47,7 +47,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -63,11 +111,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: hu\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: it\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ja\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ko\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: lt\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -47,7 +47,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -63,11 +111,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: nb\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:55+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: nb_NO\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: nl\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: pl\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -47,7 +47,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -63,11 +111,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ro\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -47,7 +47,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -63,11 +111,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ru\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -47,7 +47,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -63,11 +111,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: sk\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-08-28 14:34+0200\n"
|
||||
"POT-Creation-Date: 2019-11-29 16:27+0100\n"
|
||||
"PO-Revision-Date: 2019-08-28 17:56+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: sv\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.6.0\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: src/validations.js:13
|
||||
msgid "This is not a valid IPv4 address."
|
||||
@ -46,7 +46,55 @@ msgstr ""
|
||||
msgid "Doesn't contain a list of emails separated by commas."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:123
|
||||
#: src/api/utils.js:58
|
||||
msgid "The session is expired. Please log in again."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:63
|
||||
msgid "Timeout error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:66
|
||||
msgid "No response received."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:70
|
||||
msgid "An unknown error occurred. Check the console for more info."
|
||||
msgstr ""
|
||||
|
||||
#: src/api/utils.js:77
|
||||
msgid "An unknown API error occurred."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:33
|
||||
msgid "Reboot request failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:54
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:69
|
||||
msgid "Reboot confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:70
|
||||
msgid "Are you sure you want to restart the router?"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/common/RebootButton.js:73
|
||||
msgid "Confirm reboot"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:88
|
||||
msgid "Settings saved successfully"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/ForisForm.js:140
|
||||
msgid "Changes you made may not be saved. Are you sure you want to leave?"
|
||||
msgstr ""
|
||||
|
||||
@ -62,11 +110,25 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:25
|
||||
msgid "Settings were successfully saved."
|
||||
#: src/utils/ErrorMessage.js:13
|
||||
msgid "An error occurred while fetching data."
|
||||
msgstr ""
|
||||
|
||||
#: src/form/components/alerts.js:41
|
||||
msgid "Settings update was failed."
|
||||
msgstr ""
|
||||
#~ msgid "Settings were successfully saved."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Settings update was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Warning!"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering was failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot triggering failed."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Reboot requestq failed."
|
||||
#~ msgstr ""
|
||||
|
||||
|
Reference in New Issue
Block a user