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

Compare commits

..

1 Commits

Author SHA1 Message Date
74410b374b Bump v.5.1.2 2020-09-08 18:22:42 +02:00
23 changed files with 2728 additions and 2011 deletions

4509
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "foris",
"version": "5.1.9",
"version": "5.1.2",
"description": "Set of components and utils for Foris and its plugins.",
"author": "CZ.NIC, z.s.p.o.",
"repository": {
@ -14,11 +14,11 @@
"license": "GPL-3.0",
"main": "./src/index.js",
"dependencies": {
"axios": "^0.21.1",
"axios": "^0.19.2",
"immutability-helper": "3.0.1",
"moment": "^2.24.0",
"qrcode.react": "^0.9.3",
"react-datetime": "^3.0.4",
"react-datetime": "^2.16.3",
"react-uid": "^2.2.0"
},
"peerDependencies": {
@ -29,7 +29,7 @@
"react-router-dom": "^5.1.2"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/plugin-transform-runtime": "^7.9.0",
"@babel/preset-env": "^7.9.0",
@ -53,10 +53,10 @@
"react": "16.9.0",
"react-dom": "16.9.0",
"react-router-dom": "^5.1.2",
"react-styleguidist": "^11.1.5",
"react-styleguidist": "^10.6.2",
"snapshot-diff": "^0.7.0",
"style-loader": "^1.2.1",
"webpack": "^5.15.0"
"webpack": "^4.43.0"
},
"scripts": {
"lint": "eslint src",

View File

@ -37,11 +37,7 @@ Alert.defaultProps = {
export function Alert({ type, onDismiss, children }) {
return (
<div
className={`alert ${
onDismiss ? "alert-dismissible" : ""
} alert-${type}`}
>
<div className={`alert alert-dismissible alert-${type}`}>
{onDismiss ? (
<button type="button" className="close" onClick={onDismiss}>
&times;

View File

@ -7,7 +7,7 @@
import React from "react";
import PropTypes from "prop-types";
import Datetime from "react-datetime";
import Datetime from "react-datetime/DateTime";
import moment from "moment/moment";
import "react-datetime/css/react-datetime.css";
import "./DataTimeInput.css";

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
* 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, { useRef, useEffect } from "react";
import React, { useRef } from "react";
import PropTypes from "prop-types";
import { Portal } from "../utils/Portal";
@ -18,7 +18,6 @@ Modal.propTypes = {
/** Callback to manage modal visibility */
setShown: PropTypes.func.isRequired,
scrollable: PropTypes.bool,
size: PropTypes.string,
/** Modal content use following: `ModalHeader`, `ModalBody`, `ModalFooter` */
children: PropTypes.oneOfType([
@ -27,51 +26,19 @@ Modal.propTypes = {
]).isRequired,
};
export function Modal({ shown, setShown, scrollable, size, children }) {
export function Modal({ shown, setShown, scrollable, children }) {
const dialogRef = useRef();
let modalSize = "modal-";
useClickOutside(dialogRef, () => setShown(false));
useEffect(() => {
const handleEsc = (event) => {
if (event.keyCode === 27) {
setShown(false);
}
};
window.addEventListener("keydown", handleEsc);
return () => {
window.removeEventListener("keydown", handleEsc);
};
}, [setShown]);
switch (size) {
case "sm":
modalSize += "sm";
break;
case "lg":
modalSize += "lg";
break;
case "xl":
modalSize += "xl";
break;
default:
modalSize = "";
break;
}
return (
<Portal containerId="modal-container">
<div
className={`modal fade ${shown ? "show" : ""}`.trim()}
role="dialog"
>
<div className={`modal fade ${shown ? "show" : ""}`} role="dialog">
<div
ref={dialogRef}
className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
scrollable ? "modal-dialog-scrollable" : ""
}`.trim()}
className={`modal-dialog modal-dialog-centered${
scrollable ? " modal-dialog-scrollable" : ""
}`}
role="document"
>
<div className="modal-content">{children}</div>

View File

@ -1,19 +1,8 @@
Bootstrap modal component.
It's required to have an element `<div id={"modal-container"}/>` somewhere on
it's required to have an element `<div id={"modal-container"}/>` somewhere on
the page since modals are rendered in portals.
Modals also have three optional sizes, which can be defined through the `size`
prop:
- small - `sm`
- large - `lg`
- extra-large - `xl`
For more details please visit Bootstrap
<a href="https://getbootstrap.com/docs/4.5/components/modal/#optional-sizes" target="_blank">
documentation</a>.
```js
<div id="modal-container" />
```
@ -25,7 +14,7 @@ import { useState } from "react";
const [shown, setShown] = useState(false);
<>
<Modal setShown={setShown} shown={shown} size="sm">
<Modal setShown={setShown} shown={shown}>
<ModalHeader setShown={setShown} title="Warning!" />
<ModalBody>
<p>Bla bla bla...</p>

View File

@ -23,7 +23,7 @@ Switch.propTypes = {
export function Switch({ label, helpText, switchHeading, ...props }) {
const uid = useUID();
return (
<div className={`form-group ${switchHeading ? "switch" : ""}`.trim()}>
<div className={`form-group ${switchHeading ? "switch" : ""}`}>
<div
className={`custom-control custom-switch ${
!helpText ? "custom-control-inline" : ""

View File

@ -2,7 +2,7 @@
exports[`<Switch/> Render switch 1`] = `
<div
class="form-group"
class="form-group "
>
<div
class="custom-control custom-switch"
@ -30,7 +30,7 @@ exports[`<Switch/> Render switch 1`] = `
exports[`<Switch/> Render uncheked switch 1`] = `
<div
class="form-group"
class="form-group "
>
<div
class="custom-control custom-switch"

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
* 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.
@ -7,5 +7,5 @@
/** Bootstrap column size for form fields */
// eslint-disable-next-line import/prefer-default-export
export const formFieldsSize = "card p-4 col-sm-12 col-lg-12 p-0 mb-4";
export const formFieldsSize = "card p-4 col-sm-12 col-lg-12 p-0 mb-3";
export const buttonFormFieldsSize = "col-sm-12 col-lg-12 p-0 mb-3";

View File

@ -63,7 +63,7 @@ RebootModal.propTypes = {
function RebootModal({ shown, setShown, onReboot }) {
return (
<Modal shown={shown} setShown={setShown}>
<ModalHeader setShown={setShown} title={_("Warning!")} />
<ModalHeader setShown={setShown} title={_("Reboot confirmation")} />
<ModalBody>
<p>{_("Are you sure you want to restart the router?")}</p>
</ModalBody>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
* 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.
@ -13,7 +13,7 @@ import { useAlert } from "../../alertContext/AlertContext";
import { ALERT_TYPES } from "../../bootstrap/Alert";
import { useAPIPost } from "../../api/hooks";
import { API_STATE } from "../../api/utils";
import { formFieldsSize } from "../../bootstrap/constants";
import { buttonFormFieldsSize } from "../../bootstrap/constants";
ResetWiFiSettings.propTypes = {
ws: PropTypes.object.isRequired,
@ -51,7 +51,7 @@ export default function ResetWiFiSettings({ ws, endpoint }) {
}
return (
<div className={formFieldsSize}>
<>
<h2>{_("Reset Wi-Fi Settings")}</h2>
<p>
{_(`
@ -59,7 +59,7 @@ If a number of wireless cards doesn't match, you may try to reset the Wi-Fi sett
current Wi-Fi configuration and restore the default values.
`)}
</p>
<div className="text-right">
<div className={`${buttonFormFieldsSize} text-right`}>
<Button
className="btn-warning"
forisFormSize
@ -70,6 +70,6 @@ current Wi-Fi configuration and restore the default values.
{_("Reset Wi-Fi Settings")}
</Button>
</div>
</div>
</>
);
}

View File

@ -105,7 +105,6 @@ function DeviceForm({
label="SSID"
value={formData.SSID}
error={formErrors.SSID || null}
helpText={HELP_TEXTS.ssid}
required
onChange={setFormValue((value) => ({
devices: {
@ -157,7 +156,6 @@ function DeviceForm({
choices={getHwmodeChoices(formData)}
value={formData.hwmode}
helpText={HELP_TEXTS.hwmode}
inline
onChange={setFormValue((value) => ({
devices: {
[deviceIndex]: {

View File

@ -57,7 +57,6 @@ export default function WifiGuestForm({
label="SSID"
value={formData.SSID}
error={formErrors.SSID}
helpText={HELP_TEXTS.ssid}
onChange={setFormValue((value) => ({
devices: {
[formData.id]: {

View File

@ -63,12 +63,6 @@ function prepDataToSubmit(formData) {
return formData;
}
export function byteCount(string) {
const buffer = Buffer.from(string, "utf-8");
const count = buffer.byteLength;
return count;
}
export function validator(formData) {
const formErrors = formData.devices.map((device) => {
if (!device.enabled) return {};
@ -77,8 +71,6 @@ export function validator(formData) {
if (device.SSID.length > 32)
errors.SSID = _("SSID can't be longer than 32 symbols");
if (device.SSID.length === 0) errors.SSID = _("SSID can't be empty");
if (byteCount(device.SSID) > 32)
errors.SSID = _("SSID can't be longer than 32 bytes");
if (device.password.length < 8)
errors.password = _("Password must contain at least 8 symbols");
@ -90,8 +82,6 @@ export function validator(formData) {
guest_wifi_errors.SSID = _("SSID can't be longer than 32 symbols");
if (device.guest_wifi.SSID.length === 0)
guest_wifi_errors.SSID = _("SSID can't be empty");
if (byteCount(device.guest_wifi.SSID) > 32)
guest_wifi_errors.SSID = _("SSID can't be longer than 32 bytes");
if (device.guest_wifi.password.length < 8)
guest_wifi_errors.password = _(

View File

@ -19,7 +19,7 @@ import {
twoDevices,
threeDevices,
} from "./__fixtures__/wifiSettings";
import { WiFiSettings, validator, byteCount } from "../WiFiSettings";
import { WiFiSettings, validator } from "../WiFiSettings";
describe("<WiFiSettings/>", () => {
let firstRender;
@ -213,8 +213,4 @@ describe("<WiFiSettings/>", () => {
];
expect(validator(threeDevices)).toEqual(threeDevicesFormErrors);
});
it("ByteCount function", () => {
expect(byteCount("abc")).toEqual(3);
});
});

View File

@ -5,7 +5,7 @@ exports[`<WiFiSettings/> Snapshot 2.4 GHz 1`] = `
- First value
+ Second value
@@ -250,207 +250,95 @@
@@ -245,207 +245,95 @@
value=\\"0\\"
>
auto
@ -251,7 +251,7 @@ exports[`<WiFiSettings/> Snapshot 2.4 GHz 1`] = `
exports[`<WiFiSettings/> Snapshot both modules disabled. 1`] = `
<DocumentFragment>
<div
class="card p-4 col-sm-12 col-lg-12 p-0 mb-4"
class="card p-4 col-sm-12 col-lg-12 p-0 mb-3"
>
<form>
<div
@ -309,28 +309,24 @@ exports[`<WiFiSettings/> Snapshot both modules disabled. 1`] = `
</div>
</form>
</div>
<div
class="card p-4 col-sm-12 col-lg-12 p-0 mb-4"
>
<h2>
Reset Wi-Fi Settings
</h2>
<p>
<h2>
Reset Wi-Fi Settings
</h2>
<p>
If a number of wireless cards doesn't match, you may try to reset the Wi-Fi settings. Note that this will remove the
current Wi-Fi configuration and restore the default values.
</p>
<div
class="text-right"
</p>
<div
class="col-sm-12 col-lg-12 p-0 mb-3 text-right"
>
<button
class="btn btn-warning col-sm-12 col-md-3 col-lg-2"
type="button"
>
<button
class="btn btn-warning col-sm-12 col-md-3 col-lg-2"
type="button"
>
Reset Wi-Fi Settings
</button>
</div>
Reset Wi-Fi Settings
</button>
</div>
</DocumentFragment>
`;
@ -340,7 +336,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
- First value
+ Second value
@@ -479,10 +479,94 @@
@@ -474,10 +474,89 @@
Parameters of the guest network can be set in the Guest network tab.
</small>
@ -379,11 +375,6 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
+ </button>
+ </div>
+ </div>
+ <small
+ class=\\"form-text text-muted\\"
+ >
+ SSID which contains non-standard characters could cause problems on some devices.
+ </small>
+ </div>
+ <div
+ class=\\"form-group\\"
@ -435,7 +426,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
class=\\"form-group switch\\"
>
<div
@@ -506,10 +590,11 @@
@@ -501,10 +580,11 @@
<div
class=\\"text-right\\"
>
@ -454,7 +445,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
- First value
+ Second value
@@ -22,10 +22,467 @@
@@ -22,10 +22,462 @@
Wi-Fi 1
</h2>
</label>
@ -494,11 +485,6 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </button>
+ </div>
+ </div>
+ <small
+ class=\\"form-text text-muted\\"
+ >
+ SSID which contains non-standard characters could cause problems on some devices.
+ </small>
+ </div>
+ <div
+ class=\\"form-group\\"
@ -574,7 +560,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ GHz
+ </label>
+ <div
+ class=\\"custom-control custom-radio custom-control-inline\\"
+ class=\\"custom-control custom-radio\\"
+ >
+ <input
+ class=\\"custom-control-input\\"
@ -591,7 +577,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </label>
+ </div>
+ <div
+ class=\\"custom-control custom-radio custom-control-inline\\"
+ class=\\"custom-control custom-radio\\"
+ >
+ <input
+ checked=\\"\\"
@ -890,7 +876,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </select>
+ </div>
+ <div
+ class=\\"form-group\\"
+ class=\\"form-group \\"
+ >
+ <div
+ class=\\"custom-control custom-switch\\"

View File

@ -19,9 +19,6 @@ export const HWMODES = {
"11a": "5",
};
export const HELP_TEXTS = {
ssid: _(
`SSID which contains non-standard characters could cause problems on some devices.`
),
password: _(`
WPA2 pre-shared key, that is required to connect to the network.
`),

View File

@ -22,7 +22,7 @@ exports[`<RebootButton/> Render modal. 1`] = `
<h5
class="modal-title"
>
Warning!
Reboot confirmation
</h5>
<button
class="close"

View File

@ -39,6 +39,7 @@ export { Modal, ModalBody, ModalFooter, ModalHeader } from "./bootstrap/Modal";
// Common
export { RebootButton } from "./common/RebootButton";
export { WiFiSettings } from "./common/WiFiSettings/WiFiSettings";
// Form
export { ForisForm } from "./form/components/ForisForm";
export {
@ -69,8 +70,6 @@ export {
export { ErrorMessage } from "./utils/ErrorMessage";
export { useClickOutside } from "./utils/hooks";
export { toLocaleDateString } from "./utils/datetime";
export { displayCard } from "./utils/displayCard";
export { isPluginInstalled } from "./utils/isPluginInstalled";
// Foris URL
export { ForisURLs, REFORIS_URL_PREFIX } from "./utils/forisUrls";

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) 2020 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 function displayCard({ package_lists: packages }, cardName) {
const enabledPackagesNames = [];
packages
.filter((item) => item.enabled)
.map((item) => {
enabledPackagesNames.push(item.name);
item.options
.filter((option) => option.enabled)
.map((option) => {
enabledPackagesNames.push(option.name);
return null;
});
return null;
});
return enabledPackagesNames.includes(cardName);
}

View File

@ -20,8 +20,6 @@ export const ForisURLs = {
updates: `${REFORIS_URL_PREFIX}/package-management/updates`,
},
storage: `${REFORIS_URL_PREFIX}/storage`,
// Notifications links are used with <Link/> inside Router, thus url subdir is not required.
overview: "/overview",
notifications: "/overview#notifications",

View File

@ -1,9 +0,0 @@
/*
* Copyright (C) 2020 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 isPluginInstalled = (pluginName) =>
ForisPlugins.some((plugin) => plugin.name === pluginName);

7
translations/merge.py Normal file
View File

@ -0,0 +1,7 @@
import os
for entry in os.scandir("."):
if entry.is_dir():
print(entry.name)
os.system(f"msgmerge /home/mcjlnrtwcz/Repositories/reforis/reforis/translations/{entry.name}/LC_MESSAGES/messages.po forisjs.pot -o {entry.name}/LC_MESSAGES/forisjs.po")