mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-16 13:46:16 +02:00
Compare commits
27 Commits
v5.3.0
...
61e90d1e23
Author | SHA1 | Date | |
---|---|---|---|
61e90d1e23 | |||
9e15f1e93e | |||
390e6cc807 | |||
e044439646 | |||
844ea9ea72 | |||
bf57281fa7 | |||
0a143e7de6 | |||
7ec1c46a63 | |||
7ceccd5222 | |||
f868881b3d | |||
188ed87fc0 | |||
c0f64e8c6c | |||
b95cfb664d | |||
52cdaf5bc5 | |||
175a07a865 | |||
f952e25205 | |||
01eeb06f9e | |||
839e227feb | |||
4b239ed195 | |||
2bcbe0ae59 | |||
b1ff608337 | |||
b662ba5b52 | |||
a4115245fe | |||
e1a893874a | |||
dd383ef1b2 | |||
b6e2cb71bb | |||
048e686185 |
36
docs/components/Logo.js
Normal file
36
docs/components/Logo.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import React from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import Styled from "rsg-components/Styled";
|
||||||
|
import logo from "./logo.svg";
|
||||||
|
|
||||||
|
const styles = ({ fontFamily }) => ({
|
||||||
|
logo: {
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
margin: 0,
|
||||||
|
fontFamily: fontFamily.base,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "normal",
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
height: "1.3em",
|
||||||
|
marginLeft: "-0.2em",
|
||||||
|
marginRight: "0.2em",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function LogoRenderer({ classes, children }) {
|
||||||
|
return (
|
||||||
|
<h1 className={classes.logo}>
|
||||||
|
<img className={classes.image} src={logo} alt="React logo" />
|
||||||
|
{children}
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogoRenderer.propTypes = {
|
||||||
|
classes: PropTypes.object.isRequired,
|
||||||
|
children: PropTypes.node,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Styled(styles)(LogoRenderer);
|
3
docs/components/logo.svg
Normal file
3
docs/components/logo.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000">
|
||||||
|
<path d="M288.258 240.0394L717.5586-.44c.803 62.277-1.8207 124.502-1.4996 186.7266 1.8208 7.6343-7.2288 10.1966-12.102 13.4908L286.4375 432.1518l1.8206-192.1124zm2.284 277.645L711 278.3176l-.8416 192.7742L457.357 614.514l-1.842 289.03-167.7097 95.8926 2.7365-481.753z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 349 B |
@ -1,15 +1,15 @@
|
|||||||
Sooner or later you will face with situation when you want/need to make some
|
Sooner or later, you will face with situation when you want/need to make some
|
||||||
changes in the library. Then the most important tool for you it's
|
changes in the library. Then the most important tool for you it's the
|
||||||
[`npm link`](https://docs.npmjs.com/cli/link).
|
[`npm link`](https://docs.npmjs.com/cli/link).
|
||||||
|
|
||||||
Please, notice that it will not work if you link library just from root of the
|
Please, notice that it will not work if you link the library just from the root
|
||||||
repo. It happens due to location of sources `./src`. You need to pack library
|
of the repo. It happens due to the location of sources `./src`. You need to pack
|
||||||
first `make pack` and then link it from `./dist` directory.
|
the library first, `make pack` and then link it from the `./dist` directory.
|
||||||
|
|
||||||
Yeah it's not such comfortable solution for development. But it can fixed by
|
Yeah, it's not such a comfortable solution for development. But it can be fixed
|
||||||
writing small script similar as `make pack` but with linking every file and
|
by writing a small script similar to making a pack but by linking every file and
|
||||||
directory from `./src` to the some directory and linking then from it. Notice
|
directory from `./src` to the same directory and linking then from it. Notice
|
||||||
that you need to link `package.json` and `package-lock.json` as well.
|
that you need to link a `package.json` and a `package-lock.json` as well.
|
||||||
|
|
||||||
So step by step:
|
So step by step:
|
||||||
|
|
||||||
|
4
docs/forisjs-npm.svg
Normal file
4
docs/forisjs-npm.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" fill="white">
|
||||||
|
<path d="M49.5 171.722222222222h400v133.333333333333h-200v22.222222222223h-88.888888888889v-22.222222222223H49.5V171.722222222222zm22.222222222222 111.111111111111h44.444444444445v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-88.888888888889H71.722222222222v88.888888888889zm111.111111111111-88.888888888889v111.111111111111h44.444444444445v-22.222222222222h44.444444444444v-88.888888888889h-88.888888888889zm44.444444444445 22.222222222222H249.5v44.444444444445h-22.222222222222v-44.444444444445zm66.666666666666-22.222222222222v88.888888888889h44.444444444445v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-66.666666666667h22.222222222222v66.666666666667h22.222222222223v-88.888888888889H293.944444444444z" fill="#cb3837" />
|
||||||
|
<path d="M71.722222222222 282.833333333333h44.444444444444v-66.666666666667h22.222222222223v66.666666666667h22.222222222222v-88.888888888889H71.722222222222zm111.111111111111-88.888888888889v111.111111111111h44.444444444444v-22.222222222222h44.444444444445v-88.888888888889h-88.888888888889zM249.5 260.611111111111h-22.222222222223v-44.444444444445H249.5v44.444444444445zm44.444444444444-66.666666666667v88.888888888889h44.444444444444v-66.666666666667h22.222222222223v66.666666666667h22.222222222222v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-88.888888888889z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,6 +0,0 @@
|
|||||||
Foris JS library is set of components and utils for Foris JS application and
|
|
||||||
plugins.
|
|
||||||
|
|
||||||
Please notice that all of these components or utils are used in reForis and
|
|
||||||
plugins. If you like to study by example I would recommend to full-text search
|
|
||||||
these repos.
|
|
37
docs/introduction.md
Normal file
37
docs/introduction.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Welcome! This is the official documentation for Foris JS.
|
||||||
|
|
||||||
|
## What Foris JS is
|
||||||
|
|
||||||
|
Foris JS library is a set of components and utils for reForis application and
|
||||||
|
plugins.
|
||||||
|
|
||||||
|
Please notice that all of these components or utils are used in reForis and
|
||||||
|
plugins. If you want to study them by example, I recommend you to full-text
|
||||||
|
search those repositories.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Please make sure that [Node.js](https://nodejs.org/en/) is installed on your
|
||||||
|
system.
|
||||||
|
|
||||||
|
The current Long Term Support (LTS) release is an ideal starting point, see
|
||||||
|
[here](https://github.com/nodejs/Release#release-schedule).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To install the latest release:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
npm install foris
|
||||||
|
```
|
||||||
|
|
||||||
|
To install a specific version:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
npm install foris@version
|
||||||
|
```
|
||||||
|
|
||||||
|
<a target="_blank" href="https://www.npmjs.com/package/foris">Check
|
||||||
|
on<img width="100px" src="./docs/forisjs-npm.svg"></a>
|
21254
package-lock.json
generated
21254
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "foris",
|
"name": "foris",
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"description": "Set of components and utils for Foris and its plugins.",
|
"description": "Foris JS library is a set of components and utils for reForis application and plugins.",
|
||||||
"author": "CZ.NIC, z.s.p.o.",
|
"author": "CZ.NIC, z.s.p.o.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -53,10 +53,10 @@
|
|||||||
"react": "16.9.0",
|
"react": "16.9.0",
|
||||||
"react-dom": "16.9.0",
|
"react-dom": "16.9.0",
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-styleguidist": "^7.3.11",
|
"react-styleguidist": "^11.2.0",
|
||||||
"snapshot-diff": "^0.7.0",
|
"snapshot-diff": "^0.7.0",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^1.2.1",
|
||||||
"webpack": "^5.15.0"
|
"webpack": "^5.68.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint src",
|
"lint": "eslint src",
|
||||||
|
@ -21,9 +21,14 @@ DownloadButton.defaultProps = {
|
|||||||
className: "btn-primary",
|
className: "btn-primary",
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DownloadButton({ href, className, children }) {
|
export function DownloadButton({ href, className, children, ...props }) {
|
||||||
return (
|
return (
|
||||||
<a href={href} className={`btn ${className}`.trim()} download>
|
<a
|
||||||
|
href={href}
|
||||||
|
className={`btn ${className}`.trim()}
|
||||||
|
{...props}
|
||||||
|
download
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
@ -21,14 +21,17 @@ PasswordInput.propTypes = {
|
|||||||
helpText: PropTypes.string,
|
helpText: PropTypes.string,
|
||||||
/** Use show/hide password button. */
|
/** Use show/hide password button. */
|
||||||
withEye: PropTypes.bool,
|
withEye: PropTypes.bool,
|
||||||
|
/** Use new-password in autocomplete attribute. */
|
||||||
|
newPass: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PasswordInput({ withEye, ...props }) {
|
export function PasswordInput({ withEye, newPass, ...props }) {
|
||||||
const [isHidden, setHidden] = useState(true);
|
const [isHidden, setHidden] = useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
type={withEye && !isHidden ? "text" : "password"}
|
type={withEye && !isHidden ? "text" : "password"}
|
||||||
autoComplete={isHidden ? "new-password" : null}
|
autoComplete={newPass ? "new-password" : "current-password"}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{withEye ? (
|
{withEye ? (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
@ -18,20 +18,14 @@ Select.propTypes = {
|
|||||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
/** Help text message. */
|
/** Help text message. */
|
||||||
helpText: PropTypes.string,
|
helpText: PropTypes.string,
|
||||||
/** Turns on/off alphabetical ordering of the Select options. */
|
|
||||||
customOrder: PropTypes.bool,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Select({ label, choices, helpText, customOrder, ...props }) {
|
export function Select({ label, choices, helpText, ...props }) {
|
||||||
const uid = useUID();
|
const uid = useUID();
|
||||||
|
|
||||||
const keys = Object.keys(choices);
|
const options = Object.keys(choices).map((choice) => (
|
||||||
if (!customOrder) {
|
<option key={choice} value={choice}>
|
||||||
keys.sort((a, b) => a - b || a.toString().localeCompare(b.toString()));
|
{choices[choice]}
|
||||||
}
|
|
||||||
const options = keys.map((key) => (
|
|
||||||
<option key={key} value={key}>
|
|
||||||
{choices[key]}
|
|
||||||
</option>
|
</option>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
5
src/bootstrap/Switch.md
Normal file
5
src/bootstrap/Switch.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Switch example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
<Switch label="Enable Switch" helpText="Toggle that switch!" />
|
||||||
|
```
|
@ -13,7 +13,7 @@ exports[`<PasswordInput/> Render password input 1`] = `
|
|||||||
class="input-group"
|
class="input-group"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
autocomplete="new-password"
|
autocomplete="current-password"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="1"
|
id="1"
|
||||||
type="password"
|
type="password"
|
||||||
|
@ -64,6 +64,7 @@ DeviceForm.propTypes = {
|
|||||||
channel: PropTypes.string.isRequired,
|
channel: PropTypes.string.isRequired,
|
||||||
guest_wifi: PropTypes.object.isRequired,
|
guest_wifi: PropTypes.object.isRequired,
|
||||||
encryption: PropTypes.string.isRequired,
|
encryption: PropTypes.string.isRequired,
|
||||||
|
available_bands: PropTypes.array.isRequired,
|
||||||
}),
|
}),
|
||||||
formErrors: PropTypes.object.isRequired,
|
formErrors: PropTypes.object.isRequired,
|
||||||
setFormValue: PropTypes.func.isRequired,
|
setFormValue: PropTypes.func.isRequired,
|
||||||
@ -87,6 +88,7 @@ function DeviceForm({
|
|||||||
...props
|
...props
|
||||||
}) {
|
}) {
|
||||||
const deviceID = formData.id;
|
const deviceID = formData.id;
|
||||||
|
const bnds = formData.available_bands;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Switch
|
<Switch
|
||||||
@ -159,18 +161,24 @@ function DeviceForm({
|
|||||||
value={formData.hwmode}
|
value={formData.hwmode}
|
||||||
helpText={HELP_TEXTS.hwmode}
|
helpText={HELP_TEXTS.hwmode}
|
||||||
inline
|
inline
|
||||||
onChange={setFormValue((value) => ({
|
onChange={setFormValue((value) => {
|
||||||
devices: {
|
// Get the last item in an array of available HT modes
|
||||||
[deviceIndex]: {
|
const [best2] = bnds[0].available_htmodes.slice(-1);
|
||||||
hwmode: { $set: value },
|
const [best5] = bnds[1].available_htmodes.slice(-1);
|
||||||
channel: { $set: "0" },
|
return {
|
||||||
htmode: {
|
devices: {
|
||||||
$set:
|
[deviceIndex]: {
|
||||||
value === "11a" ? "VHT80" : "HT20",
|
hwmode: { $set: value },
|
||||||
|
channel: { $set: "0" },
|
||||||
|
htmode: {
|
||||||
|
$set:
|
||||||
|
// Set HT mode depending on checked frequency
|
||||||
|
value === "11a" ? best5 : best2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
}))}
|
})}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -209,7 +217,6 @@ function DeviceForm({
|
|||||||
[deviceIndex]: { encryption: { $set: value } },
|
[deviceIndex]: { encryption: { $set: value } },
|
||||||
},
|
},
|
||||||
}))}
|
}))}
|
||||||
customOrder
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ export function validator(formData) {
|
|||||||
|
|
||||||
if (device.password.length < 8)
|
if (device.password.length < 8)
|
||||||
errors.password = _("Password must contain at least 8 symbols");
|
errors.password = _("Password must contain at least 8 symbols");
|
||||||
|
if (device.password.length >= 64)
|
||||||
|
errors.password = _(
|
||||||
|
"Password must not contain more than 63 symbols"
|
||||||
|
);
|
||||||
|
|
||||||
if (!device.guest_wifi.enabled) return errors;
|
if (!device.guest_wifi.enabled) return errors;
|
||||||
|
|
||||||
@ -97,6 +101,10 @@ export function validator(formData) {
|
|||||||
guest_wifi_errors.password = _(
|
guest_wifi_errors.password = _(
|
||||||
"Password must contain at least 8 symbols"
|
"Password must contain at least 8 symbols"
|
||||||
);
|
);
|
||||||
|
if (device.guest_wifi.password.length >= 64)
|
||||||
|
guest_wifi_errors.password = _(
|
||||||
|
"Password must not contain more than 63 symbols"
|
||||||
|
);
|
||||||
|
|
||||||
if (guest_wifi_errors.SSID || guest_wifi_errors.password) {
|
if (guest_wifi_errors.SSID || guest_wifi_errors.password) {
|
||||||
errors.guest_wifi = guest_wifi_errors;
|
errors.guest_wifi = guest_wifi_errors;
|
||||||
|
@ -26,6 +26,7 @@ describe("<WiFiSettings/>", () => {
|
|||||||
let getAllByText;
|
let getAllByText;
|
||||||
let getAllByLabelText;
|
let getAllByLabelText;
|
||||||
let getByText;
|
let getByText;
|
||||||
|
let getByLabelText;
|
||||||
let asFragment;
|
let asFragment;
|
||||||
const endpoint = "/reforis/api/wifi";
|
const endpoint = "/reforis/api/wifi";
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ describe("<WiFiSettings/>", () => {
|
|||||||
asFragment = renderRes.asFragment;
|
asFragment = renderRes.asFragment;
|
||||||
getAllByText = renderRes.getAllByText;
|
getAllByText = renderRes.getAllByText;
|
||||||
getAllByLabelText = renderRes.getAllByLabelText;
|
getAllByLabelText = renderRes.getAllByLabelText;
|
||||||
|
getByLabelText = renderRes.getByLabelText;
|
||||||
getByText = renderRes.getByText;
|
getByText = renderRes.getByText;
|
||||||
mockAxios.mockResponse({ data: wifiSettingsFixture() });
|
mockAxios.mockResponse({ data: wifiSettingsFixture() });
|
||||||
await wait(() => renderRes.getByText("Wi-Fi 1"));
|
await wait(() => renderRes.getByText("Wi-Fi 1"));
|
||||||
@ -51,7 +53,6 @@ describe("<WiFiSettings/>", () => {
|
|||||||
const webSockets = new WebSockets();
|
const webSockets = new WebSockets();
|
||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<WiFiSettings
|
<WiFiSettings
|
||||||
ws={webSockets}
|
|
||||||
ws={webSockets}
|
ws={webSockets}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
resetEndpoint="foo"
|
resetEndpoint="foo"
|
||||||
@ -146,7 +147,7 @@ describe("<WiFiSettings/>", () => {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
guest_wifi: { enabled: false },
|
guest_wifi: { enabled: false },
|
||||||
hidden: false,
|
hidden: false,
|
||||||
htmode: "HT20",
|
htmode: "VHT80",
|
||||||
hwmode: "11g",
|
hwmode: "11g",
|
||||||
id: 0,
|
id: 0,
|
||||||
password: "TestPass",
|
password: "TestPass",
|
||||||
@ -220,4 +221,24 @@ describe("<WiFiSettings/>", () => {
|
|||||||
it("ByteCount function", () => {
|
it("ByteCount function", () => {
|
||||||
expect(byteCount("abc")).toEqual(3);
|
expect(byteCount("abc")).toEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should validate password length", () => {
|
||||||
|
const shortErrorFeedback = /Password must contain/i;
|
||||||
|
const longErrorFeedback = /Password must not contain/i;
|
||||||
|
|
||||||
|
fireEvent.click(getByText("Wi-Fi 1"));
|
||||||
|
|
||||||
|
const passwordInput = getByLabelText("Password");
|
||||||
|
|
||||||
|
const changePassword = (value) =>
|
||||||
|
fireEvent.change(passwordInput, { target: { value } });
|
||||||
|
|
||||||
|
changePassword("12");
|
||||||
|
expect(getByText(shortErrorFeedback)).toBeDefined();
|
||||||
|
|
||||||
|
changePassword(
|
||||||
|
"longpasswordlongpasswordlongpasswordlongpasswordlongpasswordlong"
|
||||||
|
);
|
||||||
|
expect(getByText(longErrorFeedback)).toBeDefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -394,7 +394,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
|||||||
+ class=\\"input-group\\"
|
+ class=\\"input-group\\"
|
||||||
+ >
|
+ >
|
||||||
+ <input
|
+ <input
|
||||||
+ autocomplete=\\"new-password\\"
|
+ autocomplete=\\"current-password\\"
|
||||||
+ class=\\"form-control is-invalid\\"
|
+ class=\\"form-control is-invalid\\"
|
||||||
+ id=\\"23\\"
|
+ id=\\"23\\"
|
||||||
+ required=\\"\\"
|
+ required=\\"\\"
|
||||||
@ -509,7 +509,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
|||||||
+ class=\\"input-group\\"
|
+ class=\\"input-group\\"
|
||||||
+ >
|
+ >
|
||||||
+ <input
|
+ <input
|
||||||
+ autocomplete=\\"new-password\\"
|
+ autocomplete=\\"current-password\\"
|
||||||
+ class=\\"form-control\\"
|
+ class=\\"form-control\\"
|
||||||
+ id=\\"5\\"
|
+ id=\\"5\\"
|
||||||
+ required=\\"\\"
|
+ required=\\"\\"
|
||||||
@ -627,6 +627,11 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
|||||||
+ id=\\"8\\"
|
+ id=\\"8\\"
|
||||||
+ >
|
+ >
|
||||||
+ <option
|
+ <option
|
||||||
|
+ value=\\"NOHT\\"
|
||||||
|
+ >
|
||||||
|
+ Disabled
|
||||||
|
+ </option>
|
||||||
|
+ <option
|
||||||
+ value=\\"HT20\\"
|
+ value=\\"HT20\\"
|
||||||
+ >
|
+ >
|
||||||
+ 802.11n - 20 MHz wide channel
|
+ 802.11n - 20 MHz wide channel
|
||||||
@ -637,11 +642,6 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
|||||||
+ 802.11n - 40 MHz wide channel
|
+ 802.11n - 40 MHz wide channel
|
||||||
+ </option>
|
+ </option>
|
||||||
+ <option
|
+ <option
|
||||||
+ value=\\"NOHT\\"
|
|
||||||
+ >
|
|
||||||
+ Disabled
|
|
||||||
+ </option>
|
|
||||||
+ <option
|
|
||||||
+ value=\\"VHT20\\"
|
+ value=\\"VHT20\\"
|
||||||
+ >
|
+ >
|
||||||
+ 802.11ac - 20 MHz wide channel
|
+ 802.11ac - 20 MHz wide channel
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
@ -13,6 +13,10 @@ export const HTMODES = {
|
|||||||
VHT40: _("802.11ac - 40 MHz wide channel"),
|
VHT40: _("802.11ac - 40 MHz wide channel"),
|
||||||
VHT80: _("802.11ac - 80 MHz wide channel"),
|
VHT80: _("802.11ac - 80 MHz wide channel"),
|
||||||
VHT160: _("802.11ac - 160 MHz wide channel"),
|
VHT160: _("802.11ac - 160 MHz wide channel"),
|
||||||
|
HE20: _("802.11ax - 20 MHz wide channel"),
|
||||||
|
HE40: _("802.11ax - 40 MHz wide channel"),
|
||||||
|
HE80: _("802.11ax - 80 MHz wide channel"),
|
||||||
|
HE160: _("802.11ax - 160 MHz wide channel"),
|
||||||
};
|
};
|
||||||
export const HWMODES = {
|
export const HWMODES = {
|
||||||
"11g": "2.4",
|
"11g": "2.4",
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
validateDomain,
|
|
||||||
validateDUID,
|
|
||||||
validateIPv4Address,
|
validateIPv4Address,
|
||||||
validateIPv6Address,
|
validateIPv6Address,
|
||||||
validateIPv6Prefix,
|
validateIPv6Prefix,
|
||||||
|
validateDomain,
|
||||||
|
validateHostname,
|
||||||
|
validateDUID,
|
||||||
validateMAC,
|
validateMAC,
|
||||||
} from "utils/validations";
|
} from "utils/validations";
|
||||||
|
|
||||||
@ -68,6 +69,15 @@ describe("Validation functions", () => {
|
|||||||
expect(validateDomain(".")).not.toBe(undefined);
|
expect(validateDomain(".")).not.toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("validateHostname valid", () => {
|
||||||
|
expect(validateHostname("new-android")).toBe(undefined);
|
||||||
|
expect(validateHostname("local")).toBe(undefined);
|
||||||
|
});
|
||||||
|
it("validateHostname invalid", () => {
|
||||||
|
expect(validateHostname("-android")).not.toBe(undefined);
|
||||||
|
expect(validateHostname("local.")).not.toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
it("validateDUID valid", () => {
|
it("validateDUID valid", () => {
|
||||||
expect(validateDUID("abcdefAB")).toBe(undefined);
|
expect(validateDUID("abcdefAB")).toBe(undefined);
|
||||||
expect(validateDUID("ABCDEF12")).toBe(undefined);
|
expect(validateDUID("ABCDEF12")).toBe(undefined);
|
||||||
|
@ -82,6 +82,7 @@ export {
|
|||||||
validateIPv6Address,
|
validateIPv6Address,
|
||||||
validateIPv6Prefix,
|
validateIPv6Prefix,
|
||||||
validateDomain,
|
validateDomain,
|
||||||
|
validateHostname,
|
||||||
validateDUID,
|
validateDUID,
|
||||||
validateMAC,
|
validateMAC,
|
||||||
validateMultipleEmails,
|
validateMultipleEmails,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
@ -14,6 +14,7 @@ export const ERROR_MESSAGES = {
|
|||||||
IPv6: _("This is not a valid IPv6 address."),
|
IPv6: _("This is not a valid IPv6 address."),
|
||||||
IPv6Prefix: _("This is not a valid IPv6 prefix."),
|
IPv6Prefix: _("This is not a valid IPv6 prefix."),
|
||||||
domain: _("This is not a valid domain name."),
|
domain: _("This is not a valid domain name."),
|
||||||
|
hostname: _("This is not a valid hostname."),
|
||||||
DUID: _("This is not a valid DUID."),
|
DUID: _("This is not a valid DUID."),
|
||||||
MAC: _("This is not a valid MAC address."),
|
MAC: _("This is not a valid MAC address."),
|
||||||
MultipleEmails: _("Doesn't contain a list of emails separated by commas."),
|
MultipleEmails: _("Doesn't contain a list of emails separated by commas."),
|
||||||
@ -23,7 +24,8 @@ const REs = {
|
|||||||
IPv4: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
|
IPv4: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
|
||||||
IPv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
|
IPv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
|
||||||
IPv6Prefix: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))$/,
|
IPv6Prefix: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))$/,
|
||||||
domain: /^[A-Za-z0-9][A-Za-z0-9.-]{1,255}$/,
|
domain: /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/,
|
||||||
|
hostname: /^[a-z\d]([a-z\d-]{0,61}[a-z\d])?(\.[a-z\d]([a-z\d-]{0,61}[a-z\d])?)*$/i,
|
||||||
DUID: /^([0-9a-fA-F]{2}){4}([0-9a-fA-F]{2})*$/,
|
DUID: /^([0-9a-fA-F]{2}){4}([0-9a-fA-F]{2})*$/,
|
||||||
MAC: /^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/,
|
MAC: /^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/,
|
||||||
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-.]+ *)*$/,
|
||||||
@ -40,6 +42,7 @@ const validateIPv4Address = createValidator("IPv4");
|
|||||||
const validateIPv6Address = createValidator("IPv6");
|
const validateIPv6Address = createValidator("IPv6");
|
||||||
const validateIPv6Prefix = createValidator("IPv6Prefix");
|
const validateIPv6Prefix = createValidator("IPv6Prefix");
|
||||||
const validateDomain = createValidator("domain");
|
const validateDomain = createValidator("domain");
|
||||||
|
const validateHostname = createValidator("hostname");
|
||||||
const validateDUID = createValidator("DUID");
|
const validateDUID = createValidator("DUID");
|
||||||
const validateMAC = createValidator("MAC");
|
const validateMAC = createValidator("MAC");
|
||||||
const validateMultipleEmails = createValidator("MultipleEmails");
|
const validateMultipleEmails = createValidator("MultipleEmails");
|
||||||
@ -49,6 +52,7 @@ export {
|
|||||||
validateIPv6Address,
|
validateIPv6Address,
|
||||||
validateIPv6Prefix,
|
validateIPv6Prefix,
|
||||||
validateDomain,
|
validateDomain,
|
||||||
|
validateHostname,
|
||||||
validateDUID,
|
validateDUID,
|
||||||
validateMAC,
|
validateMAC,
|
||||||
validateMultipleEmails,
|
validateMultipleEmails,
|
||||||
|
@ -1,39 +1,56 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||||
*
|
*
|
||||||
* This is free software, licensed under the GNU General Public License v3.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const pjson = require("./package.json");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
title: "Foris JS docs",
|
title: "Foris JS Docs",
|
||||||
|
version: `v${pjson.version}`,
|
||||||
|
theme: {
|
||||||
|
color: {
|
||||||
|
link: "#0075a3",
|
||||||
|
linkHover: "#00a2e2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tocMode: "collapse",
|
||||||
|
pagePerSection: true,
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
name: "Foris JS",
|
name: "Introduction",
|
||||||
content: "docs/intro.md",
|
content: "docs/introduction.md",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Development (Linking)",
|
name: "Development",
|
||||||
content: "docs/development.md",
|
content: "docs/development.md",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Foris forms",
|
name: "Components",
|
||||||
components: [
|
description: "Set of main components.",
|
||||||
"src/form/components/ForisForm.js",
|
sections: [
|
||||||
"src/form/components/alerts.js",
|
{
|
||||||
"src/form/components/SubmitButton.js",
|
name: "Foris forms",
|
||||||
|
components: [
|
||||||
|
"src/form/components/ForisForm.js",
|
||||||
|
"src/form/components/alerts.js",
|
||||||
|
"src/form/components/SubmitButton.js",
|
||||||
|
],
|
||||||
|
exampleMode: "expand",
|
||||||
|
usageMode: "expand",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Alert Context",
|
||||||
|
components: ["src/alertContext/AlertContext.js"],
|
||||||
|
exampleMode: "expand",
|
||||||
|
usageMode: "expand",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
exampleMode: "expand",
|
sectionDepth: 1,
|
||||||
usageMode: "expand",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Alert Context",
|
|
||||||
components: ["src/alertContext/AlertContext.js"],
|
|
||||||
exampleMode: "expand",
|
|
||||||
usageMode: "expand",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "Bootstrap components",
|
name: "Bootstrap components",
|
||||||
description: "Set of bootstrap components.",
|
description: "Set of bootstrap components.",
|
||||||
@ -41,8 +58,12 @@ module.exports = {
|
|||||||
exampleMode: "expand",
|
exampleMode: "expand",
|
||||||
usageMode: "expand",
|
usageMode: "expand",
|
||||||
ignore: ["src/bootstrap/constants.js"],
|
ignore: ["src/bootstrap/constants.js"],
|
||||||
|
sectionDepth: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
template: {
|
||||||
|
favicon: "/docs/components/logo.svg",
|
||||||
|
},
|
||||||
require: [
|
require: [
|
||||||
"babel-polyfill",
|
"babel-polyfill",
|
||||||
path.join(__dirname, "src/testUtils/mockGlobals"),
|
path.join(__dirname, "src/testUtils/mockGlobals"),
|
||||||
@ -55,6 +76,9 @@ module.exports = {
|
|||||||
"node_modules/@fortawesome/fontawesome-free/css/all.min.css"
|
"node_modules/@fortawesome/fontawesome-free/css/all.min.css"
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
styleguideComponents: {
|
||||||
|
LogoRenderer: path.join(__dirname, "docs/components/Logo"),
|
||||||
|
},
|
||||||
webpackConfig: {
|
webpackConfig: {
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
@ -73,5 +97,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
devServer: {
|
||||||
|
publicPath: "/",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user