1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2025-06-16 13:46:16 +02:00

Compare commits

..

75 Commits

Author SHA1 Message Date
158bd1bb24 Merge branch 'dev' into 'master'
Release 1.3.1

See merge request turris/reforis/foris-js!38
2019-11-14 12:58:31 +00:00
d935f78d6e Merge branch '13-packages-required-for-translations' into 'dev'
Added virtual environment and packages required for translations.

Closes #13

See merge request turris/reforis/foris-js!39
2019-11-14 12:51:58 +00:00
73f4ab48c3 Added virtual environment and packages required for translations. 2019-11-14 11:28:28 +01:00
7075592f24 Merge branch 'timeout' into 'dev'
Timeout handling

See merge request turris/reforis/foris-js!36
2019-11-13 14:45:24 +00:00
23029470b9 Improve error handling + small refactoring. 2019-11-13 15:28:26 +01:00
7e6e6f8c87 Use generic error message in the ForisForm. 2019-11-13 14:49:52 +01:00
b831d664a9 Add timout handling. 2019-11-13 14:49:52 +01:00
0f5b35a3ba Merge branch 'shared-lint-configs' into 'dev'
Shared lint configs

See merge request turris/reforis/foris-js!37
2019-11-13 10:11:11 +00:00
6e02f1d194 Shared lint configs 2019-11-13 10:11:11 +00:00
13ff8221ca Merge branch 'improve-alert' into 'dev'
Move alert to portal

See merge request turris/reforis/foris-js!35
2019-11-12 12:50:29 +00:00
a51ba0630d Move alert to portal 2019-11-12 12:50:29 +00:00
ee5cf07614 Merge branch 'loading-and-errors' into 'dev'
Loading and errors HOCs

See merge request turris/reforis/foris-js!34
2019-11-07 17:21:14 +00:00
8b39bf4193 Loading and errors HOCs 2019-11-07 17:21:14 +00:00
644726a0fc Merge branch '6-api-hooks-fix' into 'dev'
Added missing hook to index.js

Closes #6

See merge request turris/reforis/foris-js!33
2019-11-05 12:03:43 +00:00
654ae6914a Added missing hook to index.js 2019-11-05 13:00:44 +01:00
81dedf59cd Merge branch '6-api-hooks' into 'dev'
Resolve "Discuss and implement proper API methods."

Closes #6

See merge request turris/reforis/foris-js!32
2019-11-05 11:10:50 +00:00
7f8aaea7b8 Resolve "Discuss and implement proper API methods." 2019-11-05 11:10:50 +00:00
dfa80e64ec Merge branch 'publish-fix' into 'dev'
Fixed publish script

See merge request turris/reforis/foris-js!31
2019-11-01 11:08:05 +00:00
031b53f03c Fixed publish script 2019-11-01 10:49:45 +01:00
ca23b2d335 Merge branch 'alert-context-fix' into 'dev'
Flat structure of published package

See merge request turris/reforis/foris-js!30
2019-11-01 09:28:28 +00:00
0984c45161 Flat structure of published package 2019-11-01 09:28:28 +00:00
6835bc7a28 Merge branch 'global-alert' into 'dev'
Global alert

See merge request turris/reforis/foris-js!29
2019-10-30 16:06:53 +00:00
0915d477fe Global alert 2019-10-30 16:06:53 +00:00
c114579b7f Merge branch 'dev' into 'master'
Release 1.2.0

See merge request turris/reforis/foris-js!28
2019-10-24 13:52:35 +00:00
22b2bc9c09 Merge branch 'release-1.2.0' into 'dev'
Release 1.2.0

See merge request turris/reforis/foris-js!27

[skip ci]
2019-10-24 11:54:36 +00:00
cab2cfa068 Release 1.2.0 2019-10-24 13:47:25 +02:00
a137a0d4cf Merge branch 'dev' into 'master'
Release 1.1.1

See merge request turris/reforis/foris-js!26
2019-10-24 11:24:57 +00:00
54cf7e3c06 Merge branch 'master' into dev 2019-10-24 10:47:13 +02:00
18eb28f368 Merge branch 'radio-checkbox-whitespace' into 'dev'
Radio checkbox whitespace

See merge request turris/reforis/foris-js!25

[skip ci]
2019-10-24 08:12:39 +00:00
88f3836485 Radio checkbox whitespace 2019-10-24 08:12:39 +00:00
8f88b09e66 Merge branch 'dev' into 'master'
Release 1.1.0

See merge request turris/reforis/foris-js!24
2019-10-22 08:24:10 +00:00
f2aa28f172 Release 1.1.0 2019-10-22 08:24:10 +00:00
a88fbf63e9 Merge branch 'shell-quotes' into 'dev'
Added quotes to shell variables

See merge request turris/reforis/foris-js!23
2019-10-15 08:50:53 +00:00
ff9e8fdeb1 Added quotes to shell variables 2019-10-15 10:10:33 +02:00
8cd4ac8b44 Merge branch 'ws-connection-closed' into 'dev'
Download button

See merge request turris/reforis/foris-js!22
2019-10-11 14:11:14 +00:00
760e6d9243 Download button 2019-10-11 14:11:14 +00:00
2429f4662c Merge branch '5-versioning' into 'dev'
Changed beta versioning procedure

Closes #5

See merge request turris/reforis/foris-js!21
2019-10-11 08:25:06 +00:00
b320e6a860 Changed beta versioning procedure 2019-10-11 10:15:53 +02:00
1e3e9433ec Merge branch 'client-configuration' into 'dev'
Client configuration

See merge request turris/reforis/foris-js!20
2019-10-10 15:25:00 +00:00
e3a795e40d Client configuration 2019-10-10 15:25:00 +00:00
dccc9e5769 Merge branch 'dev' into 'master'
Release 1.0.0

See merge request turris/reforis/foris-js!19
2019-10-07 15:49:42 +00:00
30748fab12 Merge branch 'master' into dev
[skip ci]
2019-10-07 17:36:04 +02:00
a17ecc6060 Merge branch 'release-1.0.0' into 'dev'
Release 1.0.0

See merge request turris/reforis/foris-js!18

[skip ci]
2019-10-07 15:31:02 +00:00
75ce94d3ee Release 1.0.0 2019-10-07 17:24:03 +02:00
96263af618 Merge branch 'dev' into 'master'
Release 0.1.0

See merge request turris/reforis/foris-js!17
2019-10-07 15:16:27 +00:00
50a1bfd9b5 Release 0.1.0 2019-10-07 15:16:27 +00:00
b360431f38 Merge branch 'release-0.1.0' into 'dev'
Release 0.1.0

See merge request turris/reforis/foris-js!16

[skip ci]
2019-10-07 15:01:29 +00:00
9eebb35e65 Release 0.1.0 2019-10-07 16:53:54 +02:00
cf556e3518 Merge branch '1-automatic-publish' into 'dev'
Resolve "Automatic NPM publish."

Closes #1

See merge request turris/reforis/foris-js!15
2019-10-07 14:43:57 +00:00
5977e675cf Resolve "Automatic NPM publish." 2019-10-07 14:43:57 +00:00
ee5f3da093 Merge branch '4-increment-decrement' into 'dev'
Resolve "Increment/decrement value in NumberInput when +/- button is kept pushed."

Closes #4

See merge request turris/reforis/foris-js!14
2019-10-07 09:18:25 +00:00
afa8c160a3 Resolve "Increment/decrement value in NumberInput when +/- button is kept pushed." 2019-10-07 09:18:25 +00:00
0af56ec84c Merge branch 'non-json-payload' into 'dev'
Filter non-JSON payload

See merge request turris/reforis/foris-js!13
2019-10-01 09:38:18 +00:00
96eed02d32 Filter non-JSON payload 2019-10-01 09:38:18 +00:00
8479518fab Merge branch 'docs' into 'dev'
Fix docs, extract CSS to Foris JS.

See merge request turris/reforis/foris-js!10
2019-09-30 13:01:00 +00:00
800dedbcfd Merge branch 'reforis-125-ignore-non-json-errors' into 'dev'
Ignore non-JSON error payload

See merge request turris/reforis/foris-js!12
2019-09-30 12:58:41 +00:00
44e45499c6 Ignore non-JSON error payload 2019-09-30 12:58:41 +00:00
5457f68c70 Download docs css via NPM. 2019-09-30 11:27:13 +02:00
680871de62 Core review docs fixes. 2019-09-30 11:26:06 +02:00
9641fbcb50 Version bump 2019-09-30 10:09:52 +02:00
1708f026a4 Merge branch 'filter-keys-fix' into 'dev'
Added missing export

See merge request turris/reforis/foris-js!11
2019-09-30 08:04:05 +00:00
7516cfdbfe Added missing export 2019-09-30 09:58:11 +02:00
cbb1382c66 Merge branch 'filter-keys' into 'dev'
Added function to filter object by keys

See merge request turris/reforis/foris-js!9
2019-09-30 07:51:59 +00:00
e4e28dbce4 Move css to the library. 2019-09-26 16:10:52 +02:00
7a14ed1b60 Copyright. 2019-09-26 12:23:22 +02:00
497a1a0ad3 Added function to filter object keys 2019-09-26 09:39:07 +02:00
4a481ea642 Add styleguidist docs. 2019-09-25 16:14:29 +02:00
8296c6129e Merge branch '89-arrows-number-input' into 'dev'
Disable default styles for number input

See merge request turris/reforis/foris-js!5
2019-09-25 11:59:45 +00:00
7253319b61 Disable default styles for number input 2019-09-25 11:59:45 +00:00
7371fbcac0 Merge branch '3-handle-patch-request' into 'dev'
Resolve "Handle PATCH request"

Closes #3

See merge request turris/reforis/foris-js!8
2019-09-25 11:56:08 +00:00
d658f0b112 Resolve "Handle PATCH request" 2019-09-25 11:56:08 +00:00
edc5c92421 Merge branch '2-alert-context' into 'dev'
Resolve "Extract alert context from OpenVPN plugin"

Closes #2

See merge request turris/reforis/foris-js!7
2019-09-24 07:52:09 +00:00
d4bc5a6998 Resolve "Extract alert context from OpenVPN plugin" 2019-09-24 07:52:09 +00:00
b938dd85ff Merge branch 'api-delete-method' into 'dev'
DELETE method in API hooks

See merge request turris/reforis/foris-js!6
2019-09-10 08:30:42 +00:00
4ff3e33411 DELETE method in API hooks 2019-09-10 08:30:42 +00:00
89 changed files with 4067 additions and 1022 deletions

View File

@ -1,66 +1,6 @@
const path = require("path");
module.exports = { module.exports = {
"env": { extends: "eslint-config-reforis",
"browser": true, rules: {
"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",
"import/prefer-default-export": "off", "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
View File

@ -4,6 +4,9 @@
logs logs
*.log *.log
# Python
venv/
# NodeJS # NodeJS
## Logs ## Logs
npm-debug.log* npm-debug.log*
@ -43,8 +46,8 @@ coverage.xml
## Translations ## Translations
*.mo *.mo
/js/styleguide/
.gitignore .gitignore
dist/ dist/
foris-*.tgz foris-*.tgz
styleguide/

View File

@ -3,24 +3,42 @@ image: node:8-alpine
stages: stages:
- test - test
- build - build
- publish
before_script: before_script:
- apk add make
- npm install - npm install
test: test:
stage: test stage: test
script: script:
- npm test - make test
lint: lint:
stage: test stage: test
script: script:
- npm run lint - make lint
build: build:
stage: build stage: build
script: script:
- npm pack - make pack
artifacts: artifacts:
paths: 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

View File

@ -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: 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 "make create-messages"
@echo " Create locale messages (.pot)." @echo " Create locale messages (.pot)."
@echo "make update-messages" @echo "make update-messages"
@echo " Update locale messages from .pot file." @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 "make clean"
@echo " Remove python artifacts and virtualenv." @echo " Remove python artifacts and virtualenv."
create-messages: venv: $(VENV_NAME)/bin/activate
pybabel extract -F babel.cfg -o ./translations/forisjs.pot . $(VENV_NAME)/bin/activate:
update-messages: test -d $(VENV_NAME) || $(DEV_PYTHON) -m virtualenv -p $(DEV_PYTHON) $(VENV_NAME)
pybabel update -i translations/forisjs.pot -d translations $(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: clean:
rm -rf node_modules dist rm -rf node_modules dist

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# foris-js
## 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

View File

@ -14,4 +14,12 @@ module.exports = {
}, },
}], }],
], ],
env: {
development: {
ignore: ["**/__tests__/**", "**/__mocks__/**"],
},
test: {
ignore: [],
},
},
}; };

1
docs/intro.md Normal file
View File

@ -0,0 +1 @@
Foris JS library is set of componets and utils for Foris JS application and plugins.

View File

@ -24,4 +24,8 @@ module.exports = {
globals: { globals: {
TZ: "utc", TZ: "utc",
}, },
transform: {
"^.+\\.js$": "babel-jest",
"^.+\\.css$": "jest-transform-css",
},
}; };

2228
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "foris", "name": "foris",
"version": "0.0.7", "version": "1.3.1",
"description": "Set of components and utils for Foris and its plugins.", "description": "Set of components and utils for Foris and its plugins.",
"author": "CZ.NIC, z.s.p.o.", "author": "CZ.NIC, z.s.p.o.",
"repository": { "repository": {
@ -12,60 +12,62 @@
"reforis" "reforis"
], ],
"license": "GPL-3.0", "license": "GPL-3.0",
"main": "./dist/index.js", "main": "index.js",
"dependencies": { "dependencies": {
"axios": "^0.19.0", "axios": "^0.19.0",
"immutability-helper": "^3.0.1", "immutability-helper": "^3.0.0",
"jest-transform-css": "^2.0.0",
"moment": "^2.24.0",
"moment-timezone": "^0.5.25",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react-datetime": "^2.16.3", "react-datetime": "^2.16.3",
"react-router": "^5.0.1", "react-router": "^5.0.1",
"react-uid": "^2.2.0", "react-uid": "^2.2.0"
"moment": "^2.24.0",
"moment-timezone": "^0.5.25"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16.9.0", "react": "^16.9.0",
"react-dom": "^16.9.0" "react-dom": "^16.9.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.5.5", "@babel/cli": "^7.4.4",
"@babel/core": "^7.5.5", "@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-syntax-export-default-from": "^7.2.0", "@babel/plugin-syntax-export-default-from": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.4.4", "@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.5", "@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@testing-library/react": "^8.0.1", "@fortawesome/fontawesome-free": "^5.11.2",
"babel-eslint": "^9.0.0", "@testing-library/react": "^8.0.9",
"babel-jest": "^24.8.0", "babel-jest": "^24.8.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-module-resolver": "^3.2.0", "babel-plugin-module-resolver": "^3.2.0",
"babel-plugin-react-transform": "^3.0.0", "babel-plugin-react-transform": "^3.0.0",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"eslint": "^5.16.0", "bootstrap": "^4.3.1",
"eslint-config-airbnb": "^18.0.1", "copy-webpack-plugin": "^5.0.4",
"eslint-plugin-import": "^2.17.3", "css-loader": "^3.2.0",
"eslint-plugin-jsx-a11y": "^6.2.1", "eslint": "^6.1.0",
"eslint-plugin-react": "^7.13.0", "eslint-config-reforis": "^1.0.0",
"eslint-plugin-react-hooks": "^1.6.0", "file-loader": "^4.2.0",
"jest": "^24.8.0", "jest": "^24.8.0",
"jest-mock-axios": "^3.0.0", "jest-mock-axios": "^3.0.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"moment-timezone": "^0.5.25", "moment-timezone": "^0.5.25",
"react": "^16.9.0", "react": "^16.9.0",
"react-dom": "^16.9.0", "react-dom": "^16.9.0",
"react-styleguidist": "^9.1.11", "react-styleguidist": "^9.1.16",
"snapshot-diff": "^0.5.1" "snapshot-diff": "^0.5.1",
"style-loader": "^1.0.0",
"webpack": "^4.41.0"
}, },
"scripts": { "scripts": {
"build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline", "build": "rm -rf dist; babel src --out-dir dist --source-maps inline --copy-files",
"prepare": "rm -rf ./dist && npm run build", "build:watch": "babel src --verbose --watch --out-dir dist --source-maps inline --copy-files",
"lint": "eslint src", "lint": "eslint src",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:coverage": "jest --coverage --colors" "test:coverage": "jest --coverage --colors",
}, "docs": "npx styleguidist build ",
"files": [ "docs:watch": "styleguidist server"
"dist/**", }
"translations"
]
} }

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
Babel

9
scripts/collect_files.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/sh
# Collect files
npm run build
cp package.json dist
cp -rf translations dist
# Remove unwanted files
rm -rf dist/**/__tests__
rm -rf dist/__mocks__

24
scripts/publish.sh Executable file
View 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

View 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";
const AlertContext = React.createContext();
AlertContextProvider.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
};
function AlertContextProvider({ children }) {
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() {
return useContext(AlertContext);
}
export { AlertContext, AlertContextProvider, useAlert };

View 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();
});
});

View File

@ -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>
`;

View File

@ -5,149 +5,88 @@
* See /LICENSE for more information. * See /LICENSE for more information.
*/ */
import axios from "axios";
import { useCallback, useReducer } from "react"; import { useCallback, useReducer } from "react";
import { ForisURLs } from "forisUrls"; 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 = { function createAPIHook(method) {
Accept: "application/json", return (url, contentType) => {
"Content-Type": "application/json", const [state, dispatch] = useReducer(APIReducer, {
"X-CSRFToken": getCookie("_csrf_token"), state: API_STATE.INIT,
}; data: null,
});
function getCookie(name) { const sendRequest = useCallback(async (data) => {
let cookieValue = null; const headers = { ...HEADERS };
if (document.cookie && document.cookie !== "") { if (contentType) {
const cookies = document.cookie.split(";"); headers["Content-Type"] = contentType;
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 const TIMEOUT = 5000; dispatch({ type: API_ACTIONS.INIT });
try {
const API_ACTIONS = { const request = API_METHODS[method];
INIT: 1, const config = {
SUCCESS: 2, timeout: TIMEOUT,
FAILURE: 3, headers,
}; };
let result;
const APIGetReducer = (state, action) => { if (DATA_METHODS.includes(method)) {
switch (action.type) { result = await request(url, data, config);
case API_ACTIONS.INIT: } else {
return { result = await request(url, config);
...state, }
isLoading: true, dispatch({
isError: false, type: API_ACTIONS.SUCCESS,
}; payload: result.data,
case API_ACTIONS.SUCCESS: });
return { } catch (error) {
...state, dispatch({
isLoading: false, type: API_ACTIONS.FAILURE,
isError: false, status: error.response && error.response.status,
data: action.payload, payload: getErrorPayload(error),
}; });
case API_ACTIONS.FAILURE: }
if (action.status === 403) window.location.assign(ForisURLs.login); }, [url, contentType]);
return { return [state, sendRequest];
...state,
isLoading: false,
isError: true,
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();
}
};
export function useAPIPost(url) {
const [state, dispatch] = useReducer(APIPostReducer, {
isSending: false,
isError: false,
isSuccess: false,
data: null,
});
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,
});
}
}; };
return [state, post];
} }
function APIReducer(state, action) {
switch (action.type) {
case API_ACTIONS.INIT:
return {
...state,
state: API_STATE.SENDING,
};
case API_ACTIONS.SUCCESS:
return {
state: API_STATE.SUCCESS,
data: action.payload,
};
case API_ACTIONS.FAILURE:
if (action.status === 403) {
window.location.assign(ForisURLs.login);
}
return {
state: API_STATE.ERROR,
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,
};

78
src/api/utils.js Normal file
View 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.");
}

View File

@ -8,11 +8,20 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; 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 = { Alert.propTypes = {
/** Type of the alert it adds as `alert-${type}` class. */ /** Type of the alert it adds as `alert-${type}` class. */
type: PropTypes.string.isRequired, type: PropTypes.oneOf(Object.values(ALERT_TYPES)),
/** Alert message. */
message: PropTypes.string,
/** Alert content. */ /** Alert content. */
children: PropTypes.oneOfType([ children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node), PropTypes.arrayOf(PropTypes.node),
@ -22,13 +31,16 @@ Alert.propTypes = {
onDismiss: PropTypes.func, onDismiss: PropTypes.func,
}; };
Alert.defaultProps = {
type: ALERT_TYPES.DANGER,
};
export function Alert({ export function Alert({
type, message, onDismiss, children, type, onDismiss, children,
}) { }) {
return ( return (
<div className={`alert alert-dismissible alert-${type}`}> <div className={`alert alert-dismissible alert-${type}`}>
{onDismiss ? <button type="button" className="close" onClick={onDismiss}>&times;</button> : false} {onDismiss ? <button type="button" className="close" onClick={onDismiss}>&times;</button> : false}
{message}
{children} {children}
</div> </div>
); );

View File

@ -7,7 +7,7 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { useUID } from "react-uid/dist/es5/index"; import { useUID } from "react-uid";
import { formFieldsSize } from "./constants"; import { formFieldsSize } from "./constants";
@ -32,8 +32,8 @@ export function CheckBox({
}) { }) {
const uid = useUID(); const uid = useUID();
return ( return (
<div className={useDefaultSize ? formFieldsSize : ""} style={{ marginBottom: "1rem" }}> <div className={`form-group ${useDefaultSize ? formFieldsSize : ""}`.trim()}>
<div className="custom-control custom-checkbox" style={{ marginBottom: "0" }}> <div className="custom-control custom-checkbox ">
<input <input
className="custom-control-input" className="custom-control-input"
type="checkbox" type="checkbox"
@ -42,9 +42,9 @@ export function CheckBox({
{...props} {...props}
/> />
<label className="custom-control-label" htmlFor={uid} style={helpText ? { marginBottom: "0" } : null}>{label}</label> <label className="custom-control-label" htmlFor={uid}>{label}</label>
{helpText && <small className="form-text text-muted">{helpText}</small>}
</div> </div>
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
</div> </div>
); );
} }

View File

@ -11,6 +11,6 @@ const [value, setValue] = useState(false);
value={value} value={value}
label="Some label" label="Some label"
helpText="Read the small text!" helpText="Read the small text!"
onChange={value => setValue(value)} onChange={event =>setValue(event.target.value)}
/> />
``` ```

View File

@ -9,6 +9,7 @@ import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Datetime from "react-datetime/DateTime"; import Datetime from "react-datetime/DateTime";
import moment from "moment/moment"; import moment from "moment/moment";
import "react-datetime/css/react-datetime.css";
import { Input } from "./Input"; import { Input } from "./Input";

View File

@ -0,0 +1,21 @@
/*
* 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,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
};
export function DownloadButton({ href, children }) {
return <a href={href} className="btn btn-primary" download>{children}</a>;
}

View 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>
```

View File

@ -12,7 +12,6 @@ import { Input } from "./Input";
export const EmailInput = ({ ...props }) => <Input type="email" {...props} />; export const EmailInput = ({ ...props }) => <Input type="email" {...props} />;
EmailInput.propTypes = { EmailInput.propTypes = {
/** Field label. */ /** Field label. */
label: PropTypes.string.isRequired, label: PropTypes.string.isRequired,

View File

@ -11,7 +11,7 @@ const [email, setEmail] = useState('Wrong email');
value={email} value={email}
label="Some label" label="Some label"
helpText="Read the small text!" helpText="Read the small text!"
onChange={target => setEmail(target.value)} onChange={event =>setEmail(event.target.value)}
/> />
<button type="submit">Try to submit</button> <button type="submit">Try to submit</button>
</form> </form>

View 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}
/>
);
}

View 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)}
/>
```

View File

@ -6,7 +6,7 @@
*/ */
import React from "react"; import React from "react";
import { useUID } from "react-uid/dist/es5/index"; import { useUID } from "react-uid";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { formFieldsSize } from "./constants"; import { formFieldsSize } from "./constants";
@ -21,31 +21,31 @@ Input.propTypes = {
PropTypes.arrayOf(PropTypes.node), PropTypes.arrayOf(PropTypes.node),
PropTypes.node, PropTypes.node,
]), ]),
labelClassName: PropTypes.string,
groupClassName: PropTypes.string,
}; };
/** Base bootstrap input component. */ /** Base bootstrap input component. */
export function Input({ export function Input({
type, label, helpText, error, className, children, ...props type, label, helpText, error, className, children, labelClassName, groupClassName, ...props
}) { }) {
const uid = useUID(); const uid = useUID();
const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim(); const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim();
return ( return (
<div className={formFieldsSize}> <div className={`form-group ${formFieldsSize}`}>
<div className="form-group"> <label className={labelClassName} htmlFor={uid}>{label}</label>
<label htmlFor={uid}>{label}</label> <div className={`input-group ${groupClassName || ""}`.trim()}>
<div className="input-group"> <input
<input className={inputClassName}
className={inputClassName} type={type}
type={type} id={uid}
id={uid}
{...props} {...props}
/> />
{children} {children}
</div>
{error ? <div className="invalid-feedback">{error}</div> : null}
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
</div> </div>
{error ? <div className="invalid-feedback">{error}</div> : null}
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
</div> </div>
); );
} }

View File

@ -37,11 +37,10 @@ export function Modal({ shown, setShown, children }) {
}; };
}, [setShown]); }, [setShown]);
return ( return (
<Portal containerId="modal-container"> <Portal containerId="modal-container">
<div className={`modal fade ${shown ? "show" : ""}`} role="dialog"> <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"> <div className="modal-content">
{children} {children}
</div> </div>

View File

@ -1,6 +1,13 @@
Bootstrap modal component. 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 ```js
import {ModalHeader, ModalBody, ModalFooter} from './Modal'; import {ModalHeader, ModalBody, ModalFooter} from './Modal';
@ -8,7 +15,7 @@ import {useState} from 'react';
const [shown, setShown] = useState(false); const [shown, setShown] = useState(false);
<> <>
<Modal shown={shown}> <Modal setShown={setShown} shown={shown}>
<ModalHeader setShown={setShown} title='Warning!'/> <ModalHeader setShown={setShown} title='Warning!'/>
<ModalBody><p>Bla bla bla...</p></ModalBody> <ModalBody><p>Bla bla bla...</p></ModalBody>
<ModalFooter> <ModalFooter>
@ -19,9 +26,8 @@ const [shown, setShown] = useState(false);
</ModalFooter> </ModalFooter>
</Modal> </Modal>
<button <button className='btn btn-secondary' onClick={()=>setShown(true)}>
className='btn btn-secondary' Show modal
onClick={()=>setShown(true)} </button>
>Show modal</button>
</> </>
``` ```

View 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;
}

View File

@ -6,11 +6,11 @@
*/ */
import React from "react"; import React from "react";
import PropTypes from "prop-types"; 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 = { NumberInput.propTypes = {
/** Field label. */ /** Field label. */
@ -24,4 +24,49 @@ NumberInput.propTypes = {
PropTypes.string, PropTypes.string,
PropTypes.number, 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>
);
}

View File

@ -12,6 +12,6 @@ const [value, setValue] = useState(42);
helpText="Read the small text!" helpText="Read the small text!"
min='33' min='33'
max='54' max='54'
onChange={target => setValue(target.value)} onChange={event =>setValue(event.target.value)}
/> />
``` ```

View File

@ -12,6 +12,6 @@ const [value, setValue] = useState('secret');
value={value} value={value}
label="Some password" label="Some password"
helpText="Read the small text!" helpText="Read the small text!"
onChange={target => setValue(target.value)} onChange={event =>setValue(event.target.value)}
/> />
``` ```

View File

@ -7,11 +7,10 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { useUID } from "react-uid/dist/es5/index"; import { useUID } from "react-uid";
import { formFieldsSize } from "./constants"; import { formFieldsSize } from "./constants";
RadioSet.propTypes = { RadioSet.propTypes = {
/** Name attribute of the input HTML tag. */ /** Name attribute of the input HTML tag. */
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
@ -52,16 +51,10 @@ export function RadioSet({
}); });
return ( return (
<div className={`form-group ${formFieldsSize}`} style={{ marginBottom: "1rem" }}> <div className={`form-group ${formFieldsSize}`}>
{label {label && <label htmlFor={uid} className="d-block">{label}</label>}
? (
<label className="col-12" htmlFor={uid} style={{ paddingLeft: "0" }}>
{label}
</label>
)
: null}
{radios} {radios}
{helpText ? <small className="form-text text-muted">{helpText}</small> : null} {helpText && <small className="form-text text-muted">{helpText}</small>}
</div> </div>
); );
} }
@ -77,7 +70,7 @@ function Radio({
}) { }) {
return ( return (
<> <>
<div className="custom-control custom-radio custom-control-inline"> <div className={`custom-control custom-radio ${!helpText ? "custom-control-inline" : ""}`.trim()}>
<input <input
id={id} id={id}
className="custom-control-input" className="custom-control-input"
@ -86,8 +79,8 @@ function Radio({
{...props} {...props}
/> />
<label className="custom-control-label" htmlFor={id}>{label}</label> <label className="custom-control-label" htmlFor={id}>{label}</label>
{helpText && <small className="form-text text-muted mt-0 mb-3">{helpText}</small>}
</div> </div>
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
</> </>
); );
} }

View File

@ -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. 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 ```js
import {useState} from 'react'; import {useState} from 'react';
const CHOICES=[ const CHOICES=[
@ -17,7 +19,7 @@ const [value, setValue] = useState(CHOICES[0].value);
value={value} value={value}
name='some-radio' name='some-radio'
choices={CHOICES} choices={CHOICES}
onChange={event=>setValue(event.target.value)} onChange={event =>setValue(event.target.value)}
/> />
<p>Selected value: {value}</p> <p>Selected value: {value}</p>
</> </>

View File

@ -7,8 +7,7 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { useUID } from "react-uid/dist/es5/index"; import { useUID } from "react-uid";
Select.propTypes = { Select.propTypes = {
/** Select field Label. */ /** Select field Label. */

View File

@ -28,7 +28,7 @@ export function Spinner({
}) { }) {
if (!fullScreen) { if (!fullScreen) {
return ( return (
<div className={`spinner-wrapper ${className || ""}`} {...props}> <div className={`spinner-wrapper ${className || "my-3 text-center"}`} {...props}>
<SpinnerElement>{children}</SpinnerElement> <SpinnerElement>{children}</SpinnerElement>
</div> </div>
); );

View File

@ -10,10 +10,8 @@ import PropTypes from "prop-types";
import { Input } from "./Input"; import { Input } from "./Input";
export const TextInput = ({ ...props }) => <Input type="text" {...props} />; export const TextInput = ({ ...props }) => <Input type="text" {...props} />;
TextInput.propTypes = { TextInput.propTypes = {
/** Field label. */ /** Field label. */
label: PropTypes.string.isRequired, label: PropTypes.string.isRequired,

View File

@ -10,6 +10,6 @@ const [value, setValue] = useState('Bla bla');
value={value} value={value}
label="Some text" label="Some text"
helpText="Read the small text!" helpText="Read the small text!"
onChange={event => setValue(event.target.value)} onChange={event =>setValue(event.target.value)}
/> />
``` ```

View 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();
});
});

View File

@ -7,23 +7,39 @@
import React from "react"; import React from "react";
import { render } from "customTestRender"; import { render, fireEvent, getByLabelText, wait } from "customTestRender";
import { NumberInput } from "../NumberInput"; import { NumberInput } from "../NumberInput";
describe("<NumberInput/>", () => { describe("<NumberInput/>", () => {
it("Render number input", () => { const onChangeMock = jest.fn();
let componentContainer;
beforeEach(() => {
const { container } = render( const { container } = render(
<NumberInput <NumberInput
label="Test label" label="Test label"
helpText="Some help text" helpText="Some help text"
value={1123} value={1}
onChange={() => { onChange={onChangeMock}
}}
/> />
); );
expect(container.firstChild) componentContainer = container;
.toMatchSnapshot(); });
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}}));
}); });
}); });

View File

@ -2,12 +2,10 @@
exports[`<Checkbox/> Render checkbox 1`] = ` exports[`<Checkbox/> Render checkbox 1`] = `
<div <div
class="col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
style="margin-bottom: 1rem;"
> >
<div <div
class="custom-control custom-checkbox" class="custom-control custom-checkbox "
style="margin-bottom: 0px;"
> >
<input <input
checked="" checked=""
@ -18,27 +16,24 @@ exports[`<Checkbox/> Render checkbox 1`] = `
<label <label
class="custom-control-label" class="custom-control-label"
for="1" for="1"
style="margin-bottom: 0px;"
> >
Test label Test label
</label> </label>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
`; `;
exports[`<Checkbox/> Render uncheked checkbox 1`] = ` exports[`<Checkbox/> Render uncheked checkbox 1`] = `
<div <div
class="col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
style="margin-bottom: 1rem;"
> >
<div <div
class="custom-control custom-checkbox" class="custom-control custom-checkbox "
style="margin-bottom: 0px;"
> >
<input <input
class="custom-control-input" class="custom-control-input"
@ -48,15 +43,14 @@ exports[`<Checkbox/> Render uncheked checkbox 1`] = `
<label <label
class="custom-control-label" class="custom-control-label"
for="1" for="1"
style="margin-bottom: 0px;"
> >
Test label Test label
</label> </label>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
`; `;

View File

@ -2,31 +2,49 @@
exports[`<NumberInput/> Render number input 1`] = ` exports[`<NumberInput/> Render number input 1`] = `
<div <div
class="col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
> >
<div <label
class="form-group" for="1"
> >
<label Test label
for="1" </label>
> <div
Test label class="input-group"
</label> >
<input
class="form-control"
id="1"
type="number"
value="1"
/>
<div <div
class="input-group" class="input-group-append"
> >
<input <button
class="form-control" aria-label="Increase"
id="1" class="btn btn-outline-secondary"
type="number" type="button"
value="1123" >
/> <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>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
`; `;

View File

@ -2,32 +2,28 @@
exports[`<PasswordInput/> Render password input 1`] = ` exports[`<PasswordInput/> Render password input 1`] = `
<div <div
class="col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
> >
<div <label
class="form-group" for="1"
> >
<label Test label
for="1" </label>
> <div
Test label class="input-group"
</label> >
<div <input
class="input-group" autocomplete="new-password"
> class="form-control"
<input id="1"
autocomplete="new-password" type="password"
class="form-control" value="Some password"
id="1" />
type="password"
value="Some password"
/>
</div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
`; `;

View File

@ -3,12 +3,10 @@
exports[`<RadioSet/> Render radio set 1`] = ` exports[`<RadioSet/> Render radio set 1`] = `
<div <div
class="form-group col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
style="margin-bottom: 1rem;"
> >
<label <label
class="col-12" class="d-block"
for="1" for="1"
style="padding-left: 0px;"
> >
Radios set label Radios set label
</label> </label>

View File

@ -2,31 +2,27 @@
exports[`<TextInput/> Render text input 1`] = ` exports[`<TextInput/> Render text input 1`] = `
<div <div
class="col-sm-12 offset-lg-1 col-lg-10" class="form-group col-sm-12 offset-lg-1 col-lg-10"
> >
<div <label
class="form-group" for="1"
> >
<label Test label
for="1" </label>
> <div
Test label class="input-group"
</label> >
<div <input
class="input-group" class="form-control"
> id="1"
<input type="text"
class="form-control" value="Some text"
id="1" />
type="text"
value="Some text"
/>
</div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
<small
class="form-text text-muted"
>
Some help text
</small>
</div> </div>
`; `;

View File

@ -1,3 +1,10 @@
/*
* 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 = process.env.LIGHTTPD ? "/reforis" : ""; export const REFORIS_URL_PREFIX = process.env.LIGHTTPD ? "/reforis" : "";
export const ForisURLs = { export const ForisURLs = {

View File

@ -5,16 +5,19 @@
* See /LICENSE for more information. * See /LICENSE for more information.
*/ */
import React, { useEffect, useState } from "react"; import React, { useEffect } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Spinner } from "bootstrap/Spinner"; import { Spinner } from "bootstrap/Spinner";
import { useAPIPost } from "api/hooks"; import { useAPIPost } from "api/hooks";
import { Prompt } from "react-router"; 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 { useForisModule, useForm } from "../hooks";
import { STATES as SUBMIT_BUTTON_STATES, SubmitButton } from "./SubmitButton"; import { STATES as SUBMIT_BUTTON_STATES, SubmitButton } from "./SubmitButton";
import { FailAlert, SuccessAlert } from "./alerts";
ForisForm.propTypes = { ForisForm.propTypes = {
/** WebSocket object see `scr/common/WebSockets.js`. */ /** WebSocket object see `scr/common/WebSockets.js`. */
@ -69,22 +72,34 @@ export function ForisForm({
children, children,
}) { }) {
const [formState, onFormChangeHandler, resetFormData] = useForm(validator, prepData); const [formState, onFormChangeHandler, resetFormData] = useForm(validator, prepData);
const [setAlert] = useAlert();
const [forisModuleState] = useForisModule(ws, forisConfig); const [forisModuleState] = useForisModule(ws, forisConfig);
useEffect(() => { useEffect(() => {
if (forisModuleState.data) { if (forisModuleState.state === API_STATE.SUCCESS) {
resetFormData(forisModuleState.data); resetFormData(forisModuleState.data);
} }
}, [forisModuleState.data, resetFormData, prepData]); }, [forisModuleState, resetFormData, prepData]);
const [postState, post] = useAPIPost(forisConfig.endpoint); const [postState, post] = useAPIPost(forisConfig.endpoint);
useEffect(() => { useEffect(() => {
if (postState.isSuccess) postCallback(); if (postState.state === API_STATE.SUCCESS) {
}, [postCallback, postState.isSuccess]); 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) { function onSubmitHandler(event) {
e.preventDefault(); event.preventDefault();
resetFormData(); resetFormData();
const copiedFormData = JSON.parse(JSON.stringify(formState.data)); const copiedFormData = JSON.parse(JSON.stringify(formState.data));
const preparedData = prepDataToSubmit(copiedFormData); const preparedData = prepDataToSubmit(copiedFormData);
@ -92,16 +107,18 @@ export function ForisForm({
} }
function getSubmitButtonState() { function getSubmitButtonState() {
if (postState.isSending) return SUBMIT_BUTTON_STATES.SAVING; if (postState.state === API_STATE.SENDING) {
if (forisModuleState.isLoading) return SUBMIT_BUTTON_STATES.LOAD; return SUBMIT_BUTTON_STATES.SAVING;
}
if (forisModuleState.state === API_STATE.SENDING) {
return SUBMIT_BUTTON_STATES.LOAD;
}
return SUBMIT_BUTTON_STATES.READY; return SUBMIT_BUTTON_STATES.READY;
} }
const [alertIsDismissed, setAlertIsDismissed] = useState(false); const formIsDisabled = (disabled
|| forisModuleState.state === API_STATE.SENDING
if (!formState.data) return <Spinner className="row justify-content-center" />; || postState.state === API_STATE.SENDING);
const formIsDisabled = disabled || forisModuleState.isLoading || postState.isSending;
const submitButtonIsDisabled = disabled || !!formState.errors; const submitButtonIsDisabled = disabled || !!formState.errors;
const childrenWithFormProps = React.Children.map( const childrenWithFormProps = React.Children.map(
@ -123,19 +140,9 @@ export function ForisForm({
return _("Changes you made may not be saved. Are you sure you want to leave?"); 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 ( return (
<> <>
<Prompt message={getMessageOnLeavingPage} /> <Prompt message={getMessageOnLeavingPage} />
{alert}
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
{childrenWithFormProps} {childrenWithFormProps}
<SubmitButton <SubmitButton

View 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.). |

View File

@ -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>
);
}

View File

@ -11,13 +11,12 @@ import update from "immutability-helper";
import { useAPIGet } from "api/hooks"; import { useAPIGet } from "api/hooks";
import { useWSForisModule } from "webSockets/hooks"; import { useWSForisModule } from "webSockets/hooks";
const FORM_ACTIONS = { const FORM_ACTIONS = {
updateValue: 1, updateValue: 1,
resetData: 2, resetData: 2,
}; };
export function useForm(validator, prepData) { export function useForm(validator, dataPreprocessor) {
const [state, dispatch] = useReducer(formReducer, { const [state, dispatch] = useReducer(formReducer, {
data: null, data: null,
initialData: null, initialData: null,
@ -28,10 +27,10 @@ export function useForm(validator, prepData) {
dispatch({ dispatch({
type: FORM_ACTIONS.resetData, type: FORM_ACTIONS.resetData,
data, data,
prepData, dataPreprocessor,
validator, validator,
}); });
}, [prepData, validator]); }, [dataPreprocessor, validator]);
const onFormChangeHandler = useCallback((updateRule) => (event) => { const onFormChangeHandler = useCallback((updateRule) => (event) => {
dispatch({ dispatch({
@ -41,6 +40,7 @@ export function useForm(validator, prepData) {
validator, validator,
}); });
}, [validator]); }, [validator]);
return [ return [
state, state,
onFormChangeHandler, onFormChangeHandler,
@ -48,7 +48,6 @@ export function useForm(validator, prepData) {
]; ];
} }
function formReducer(state, action) { function formReducer(state, action) {
switch (action.type) { switch (action.type) {
case FORM_ACTIONS.updateValue: { case FORM_ACTIONS.updateValue: {
@ -61,12 +60,15 @@ function formReducer(state, action) {
}; };
} }
case FORM_ACTIONS.resetData: { case FORM_ACTIONS.resetData: {
if (!action.data) return { ...state, initialData: state.data }; if (!action.data) {
const prepData = action.prepData ? action.prepData(action.data) : action.data; return { ...state, initialData: state.data };
}
const data = action.dataPreprocessor ? action.dataPreprocessor(action.data) : action.data;
return { return {
data: prepData, data,
initialData: prepData, initialData: data,
errors: action.data ? action.validator(prepData) : undefined, errors: action.data ? action.validator(data) : undefined,
}; };
} }
default: { default: {
@ -82,6 +84,9 @@ function getChangedValue(target) {
} else if (target.type === "number") { } else if (target.type === "number") {
const parsedValue = parseInt(value); const parsedValue = parseInt(value);
value = Number.isNaN(parsedValue) ? value : parsedValue; 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; return value;
} }

View File

@ -1,19 +1,31 @@
/*
* 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 // API
export { useAPIGet, useAPIPost } from "./api/hooks"; export {
useAPIGet, useAPIPost, useAPIPatch, useAPIPut, useAPIDelete,
} from "api/hooks";
export { API_STATE } from "api/utils";
// Bootstrap // Bootstrap
export { Alert } from "bootstrap/Alert"; export { Alert, ALERT_TYPES } from "bootstrap/Alert";
export { Button } from "bootstrap/Button"; export { Button } from "bootstrap/Button";
export { CheckBox } from "bootstrap/CheckBox"; export { CheckBox } from "bootstrap/CheckBox";
export { formFieldsSize } from "bootstrap/constants"; export { DownloadButton } from "bootstrap/DownloadButton";
export { DataTimeInput } from "bootstrap/DataTimeInput"; export { DataTimeInput } from "bootstrap/DataTimeInput";
export { EmailInput } from "bootstrap/EmailInput"; export { EmailInput } from "bootstrap/EmailInput";
export { FileInput } from "bootstrap/FileInput";
export { Input } from "bootstrap/Input"; export { Input } from "bootstrap/Input";
export { NumberInput } from "bootstrap/NumberInput"; export { NumberInput } from "bootstrap/NumberInput";
export { PasswordInput } from "bootstrap/PasswordInput"; export { PasswordInput } from "bootstrap/PasswordInput";
export { RadioSet } from "bootstrap/RadioSet"; export { RadioSet } from "bootstrap/RadioSet";
export { Select } from "bootstrap/Select"; export { Select } from "bootstrap/Select";
export { TextInput } from "bootstrap/TextInput"; export { TextInput } from "bootstrap/TextInput";
export { formFieldsSize } from "bootstrap/constants";
export { export {
Spinner, Spinner,
@ -37,6 +49,11 @@ export { WebSockets } from "webSockets/WebSockets";
// Utils // Utils
export { Portal } from "utils/Portal"; 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 // Foris URL
export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls"; export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls";
@ -51,3 +68,6 @@ export {
validateMAC, validateMAC,
validateMultipleEmails, validateMultipleEmails,
} from "validations"; } from "validations";
// Alert context
export { AlertContext, AlertContextProvider, useAlert } from "alertContext/AlertContext";

View 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";
import { AlertContext } from "../alertContext/AlertContext";
const mockSetAlert = jest.fn();
const mockDismissAlert = jest.fn();
function AlertContextMock({ children }) {
return (
<AlertContext.Provider value={[mockSetAlert, mockDismissAlert]}>
{ children }
</AlertContext.Provider>
);
}
export { AlertContextMock, mockSetAlert, mockDismissAlert };

View File

@ -7,31 +7,37 @@
/* eslint import/export: "off" */ /* eslint import/export: "off" */
import React from 'react'; import React from "react";
import PropTypes from 'prop-types'; import { UIDReset } from "react-uid";
import {UIDReset} from 'react-uid'; import { StaticRouter } from "react-router";
import {StaticRouter} from 'react-router'; import { render } from "@testing-library/react";
import {render} from '@testing-library/react' import PropTypes from "prop-types";
import { AlertContextMock } from "./alertContextMock";
Wrapper.propTypes = { Wrapper.propTypes = {
children: PropTypes.oneOfType([ children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node), PropTypes.arrayOf(PropTypes.node),
PropTypes.node PropTypes.node,
]) ]),
}; };
function Wrapper({children}) { function Wrapper({ children }) {
return <StaticRouter> return (
<UIDReset> <AlertContextMock>
{children} <StaticRouter>
</UIDReset> <UIDReset>
</StaticRouter> {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 // re-export everything
export * from '@testing-library/react' export * from "@testing-library/react";
// override render method // override render method
export {customTestRender as render} export { customTestRender as render };

12
src/testUtils/network.js Normal file
View 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" } } });
}

View File

@ -15,12 +15,15 @@ global.afterEach(() => {
// Mock babel (gettext) // Mock babel (gettext)
global._ = str => str; global._ = str => str;
global.ngettext = str => str;
global.babel = {format: (str) => str}; global.babel = {format: (str) => str};
global.ForisTranslations = {}; global.ForisTranslations = {};
// Mock web sockets
window.WebSocket = jest.fn();
// Mock scrollIntoView // Mock scrollIntoView
global.HTMLElement.prototype.scrollIntoView = () => { global.HTMLElement.prototype.scrollIntoView = () => {};
};
jest.doMock('moment', () => { jest.doMock('moment', () => {
moment.tz.setDefault('UTC'); moment.tz.setDefault('UTC');

16
src/utils/ErrorMessage.js Normal file
View 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>
);
}

View File

@ -0,0 +1,61 @@
// 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
class="spinner-text"
/>
</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
class="spinner-text"
/>
</div>
</div>
`;

View 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();
});
});
});

View 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 />;
}
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
View 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;
}

View 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; },
{},
);
}

View File

@ -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-.]+ *)*$/, 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) => { const createValidator = (fieldType) => (value) => {
if (value && value !== "") return REs[fieldType].test(value) ? undefined : ERROR_MESSAGES[fieldType]; if (value && value !== "") return REs[fieldType].test(value) ? undefined : ERROR_MESSAGES[fieldType];
}; };

60
styleguide.config.js Normal file
View 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",
},
],
},
},
};

View File

@ -1,4 +1,4 @@
# Translations template for PROJECT. # Czech translations for PROJECT.
# Copyright (C) 2019 ORGANIZATION # Copyright (C) 2019 ORGANIZATION
# This file is distributed under the same license as the PROJECT project. # This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019. # FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
@ -7,17 +7,16 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 12:55+0000\n" "PO-Revision-Date: 2019-08-28 12:55+0000\n"
"Last-Translator: Stepan Henek <stepan+github@henek.name>\n" "Last-Translator: Stepan Henek <stepan+github@henek.name>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/turris/foris-js/cs/"
">\n"
"Language: cs\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" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\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" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
@ -48,7 +47,31 @@ msgstr "Tohle není platná MAC adresa."
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "Neobsahuje seznam e-mailů oddělených čárkou." 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 ""
#: 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
"Změny, které byly provedeny, nebyly uloženy. Jste si jistý, že chcete " "Změny, které byly provedeny, nebyly uloženy. Jste si jistý, že chcete "
@ -66,10 +89,13 @@ msgstr "Načítám nastavení"
msgid "Save" msgid "Save"
msgstr "Uložit" msgstr "Uložit"
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "Nastavení bylo úspěšně uloženo." msgstr ""
#~ msgid "Settings were successfully saved."
#~ msgstr "Nastavení bylo úspěšně uloženo."
#~ msgid "Settings update was failed."
#~ msgstr "Ukládání nastavení selhalo."
#: src/form/components/alerts.js:41
msgid "Settings update was failed."
msgstr "Ukládání nastavení selhalo."

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: da\n" "Language: da\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n" "Language: de\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: el\n" "Language: el\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:21+0200\n" "PO-Revision-Date: 2019-08-28 17:21+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n" "Language: en\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fi\n" "Language: fi\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fo\n" "Language: fo\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -45,7 +45,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -61,11 +85,7 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr ""
#: src/form/components/alerts.js:41
msgid "Settings update was failed."
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:54+0200\n" "PO-Revision-Date: 2019-08-28 17:54+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fr\n" "Language: fr\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: hr\n" "Language: hr\n"
@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -47,7 +47,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -63,11 +87,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: hu\n" "Language: hu\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: it\n" "Language: it\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ja\n" "Language: ja\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ko\n" "Language: ko\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: lt\n" "Language: lt\n"
@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -47,7 +47,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -63,11 +87,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: nb\n" "Language: nb\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:55+0200\n" "PO-Revision-Date: 2019-08-28 17:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: nb_NO\n" "Language: nb_NO\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: nl\n" "Language: nl\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: pl\n" "Language: pl\n"
@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -47,7 +47,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -63,11 +87,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ro\n" "Language: ro\n"
@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -47,7 +47,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -63,11 +87,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ru\n" "Language: ru\n"
@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -47,7 +47,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -63,11 +87,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: sk\n" "Language: sk\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2019-08-28 14:34+0200\n" "POT-Creation-Date: 2019-11-14 11:13+0100\n"
"PO-Revision-Date: 2019-08-28 17:56+0200\n" "PO-Revision-Date: 2019-08-28 17:56+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: sv\n" "Language: sv\n"
@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n" "Generated-By: Babel 2.7.0\n"
#: src/validations.js:13 #: src/validations.js:13
msgid "This is not a valid IPv4 address." msgid "This is not a valid IPv4 address."
@ -46,7 +46,31 @@ msgstr ""
msgid "Doesn't contain a list of emails separated by commas." msgid "Doesn't contain a list of emails separated by commas."
msgstr "" 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/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?" msgid "Changes you made may not be saved. Are you sure you want to leave?"
msgstr "" msgstr ""
@ -62,11 +86,13 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/form/components/alerts.js:25 #: src/utils/ErrorMessage.js:13
msgid "Settings were successfully saved." msgid "An error occurred while fetching data."
msgstr "" msgstr ""
#: src/form/components/alerts.js:41 #~ msgid "Settings were successfully saved."
msgid "Settings update was failed." #~ msgstr ""
msgstr ""
#~ msgid "Settings update was failed."
#~ msgstr ""