mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-15 13:36:35 +02:00
Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
8d75b5ec6e | |||
c1aa1948b4 | |||
8c110ebf52 | |||
abb5be53aa | |||
af0fb80e45 | |||
688192504f | |||
b8e5dbec8d | |||
fde751a25f | |||
79006cfb99 | |||
de398901f3 | |||
56173d4959 | |||
7c837d041e | |||
473c81f9a4 | |||
15567a7dde | |||
e2695d49a1 | |||
a87e6858bf | |||
e864de5a24 | |||
5469e6ec80 | |||
4898016388 | |||
e0fab75c69 | |||
6480a39cdb | |||
6f05d5d136 | |||
0892a1534a | |||
1bac60e054 | |||
328e568ab3 | |||
c68389359e | |||
e03e0f44cc | |||
1e04d34645 | |||
ed7cf34e76 | |||
aaf4087c96 | |||
240db88661 | |||
913a7d7b75 | |||
bdc8726791 | |||
1c986519f6 | |||
defc363f01 | |||
69723f6b0b | |||
c32137e29a | |||
be7349661f | |||
5186385b9f | |||
002786d073 | |||
4d246540c1 | |||
35b97ec0fe | |||
e1d75d8328 | |||
0f85713483 |
4511
package-lock.json
generated
4511
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "foris",
|
||||
"version": "5.1.1",
|
||||
"version": "5.1.9",
|
||||
"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.19.2",
|
||||
"axios": "^0.21.1",
|
||||
"immutability-helper": "3.0.1",
|
||||
"moment": "^2.24.0",
|
||||
"qrcode.react": "^0.9.3",
|
||||
"react-datetime": "^2.16.3",
|
||||
"react-datetime": "^3.0.4",
|
||||
"react-uid": "^2.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@ -29,7 +29,7 @@
|
||||
"react-router-dom": "^5.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.8.4",
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@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": "^10.6.2",
|
||||
"react-styleguidist": "^11.1.5",
|
||||
"snapshot-diff": "^0.7.0",
|
||||
"style-loader": "^1.2.1",
|
||||
"webpack": "^4.43.0"
|
||||
"webpack": "^5.15.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint src",
|
||||
|
@ -37,7 +37,11 @@ Alert.defaultProps = {
|
||||
|
||||
export function Alert({ type, onDismiss, children }) {
|
||||
return (
|
||||
<div className={`alert alert-dismissible alert-${type}`}>
|
||||
<div
|
||||
className={`alert ${
|
||||
onDismiss ? "alert-dismissible" : ""
|
||||
} alert-${type}`}
|
||||
>
|
||||
{onDismiss ? (
|
||||
<button type="button" className="close" onClick={onDismiss}>
|
||||
×
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Datetime from "react-datetime/DateTime";
|
||||
import Datetime from "react-datetime";
|
||||
import moment from "moment/moment";
|
||||
import "react-datetime/css/react-datetime.css";
|
||||
import "./DataTimeInput.css";
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, { useRef } from "react";
|
||||
import React, { useRef, useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Portal } from "../utils/Portal";
|
||||
@ -18,6 +18,7 @@ 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([
|
||||
@ -26,19 +27,51 @@ Modal.propTypes = {
|
||||
]).isRequired,
|
||||
};
|
||||
|
||||
export function Modal({ shown, setShown, scrollable, children }) {
|
||||
export function Modal({ shown, setShown, scrollable, size, 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" : ""}`} role="dialog">
|
||||
<div
|
||||
className={`modal fade ${shown ? "show" : ""}`.trim()}
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
ref={dialogRef}
|
||||
className={`modal-dialog modal-dialog-centered${
|
||||
scrollable ? " modal-dialog-scrollable" : ""
|
||||
}`}
|
||||
className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
|
||||
scrollable ? "modal-dialog-scrollable" : ""
|
||||
}`.trim()}
|
||||
role="document"
|
||||
>
|
||||
<div className="modal-content">{children}</div>
|
||||
|
@ -1,8 +1,19 @@
|
||||
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" />
|
||||
```
|
||||
@ -14,7 +25,7 @@ import { useState } from "react";
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
<>
|
||||
<Modal setShown={setShown} shown={shown}>
|
||||
<Modal setShown={setShown} shown={shown} size="sm">
|
||||
<ModalHeader setShown={setShown} title="Warning!" />
|
||||
<ModalBody>
|
||||
<p>Bla bla bla...</p>
|
||||
|
@ -23,7 +23,7 @@ Switch.propTypes = {
|
||||
export function Switch({ label, helpText, switchHeading, ...props }) {
|
||||
const uid = useUID();
|
||||
return (
|
||||
<div className={`form-group ${switchHeading ? "switch" : ""}`}>
|
||||
<div className={`form-group ${switchHeading ? "switch" : ""}`.trim()}>
|
||||
<div
|
||||
className={`custom-control custom-switch ${
|
||||
!helpText ? "custom-control-inline" : ""
|
||||
|
@ -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"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2021 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-3";
|
||||
export const formFieldsSize = "card p-4 col-sm-12 col-lg-12 p-0 mb-4";
|
||||
export const buttonFormFieldsSize = "col-sm-12 col-lg-12 p-0 mb-3";
|
||||
|
@ -63,7 +63,7 @@ RebootModal.propTypes = {
|
||||
function RebootModal({ shown, setShown, onReboot }) {
|
||||
return (
|
||||
<Modal shown={shown} setShown={setShown}>
|
||||
<ModalHeader setShown={setShown} title={_("Reboot confirmation")} />
|
||||
<ModalHeader setShown={setShown} title={_("Warning!")} />
|
||||
<ModalBody>
|
||||
<p>{_("Are you sure you want to restart the router?")}</p>
|
||||
</ModalBody>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2021 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 { buttonFormFieldsSize } from "../../bootstrap/constants";
|
||||
import { formFieldsSize } 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={`${buttonFormFieldsSize} text-right`}>
|
||||
<div className="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>
|
||||
);
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ function DeviceForm({
|
||||
label="SSID"
|
||||
value={formData.SSID}
|
||||
error={formErrors.SSID || null}
|
||||
helpText={HELP_TEXTS.ssid}
|
||||
required
|
||||
onChange={setFormValue((value) => ({
|
||||
devices: {
|
||||
@ -156,6 +157,7 @@ function DeviceForm({
|
||||
choices={getHwmodeChoices(formData)}
|
||||
value={formData.hwmode}
|
||||
helpText={HELP_TEXTS.hwmode}
|
||||
inline
|
||||
onChange={setFormValue((value) => ({
|
||||
devices: {
|
||||
[deviceIndex]: {
|
||||
|
@ -57,6 +57,7 @@ export default function WifiGuestForm({
|
||||
label="SSID"
|
||||
value={formData.SSID}
|
||||
error={formErrors.SSID}
|
||||
helpText={HELP_TEXTS.ssid}
|
||||
onChange={setFormValue((value) => ({
|
||||
devices: {
|
||||
[formData.id]: {
|
||||
|
@ -63,6 +63,12 @@ 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 {};
|
||||
@ -71,6 +77,8 @@ 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");
|
||||
@ -82,6 +90,8 @@ 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 = _(
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
twoDevices,
|
||||
threeDevices,
|
||||
} from "./__fixtures__/wifiSettings";
|
||||
import { WiFiSettings, validator } from "../WiFiSettings";
|
||||
import { WiFiSettings, validator, byteCount } from "../WiFiSettings";
|
||||
|
||||
describe("<WiFiSettings/>", () => {
|
||||
let firstRender;
|
||||
@ -213,4 +213,8 @@ describe("<WiFiSettings/>", () => {
|
||||
];
|
||||
expect(validator(threeDevices)).toEqual(threeDevicesFormErrors);
|
||||
});
|
||||
|
||||
it("ByteCount function", () => {
|
||||
expect(byteCount("abc")).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ exports[`<WiFiSettings/> Snapshot 2.4 GHz 1`] = `
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -245,207 +245,95 @@
|
||||
@@ -250,207 +250,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-3"
|
||||
class="card p-4 col-sm-12 col-lg-12 p-0 mb-4"
|
||||
>
|
||||
<form>
|
||||
<div
|
||||
@ -309,24 +309,28 @@ exports[`<WiFiSettings/> Snapshot both modules disabled. 1`] = `
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<h2>
|
||||
Reset Wi-Fi Settings
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
<div
|
||||
class="card p-4 col-sm-12 col-lg-12 p-0 mb-4"
|
||||
>
|
||||
<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="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"
|
||||
</p>
|
||||
<div
|
||||
class="text-right"
|
||||
>
|
||||
Reset Wi-Fi Settings
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-warning col-sm-12 col-md-3 col-lg-2"
|
||||
type="button"
|
||||
>
|
||||
Reset Wi-Fi Settings
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
@ -336,7 +340,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -474,10 +474,89 @@
|
||||
@@ -479,10 +479,94 @@
|
||||
Parameters of the guest network can be set in the Guest network tab.
|
||||
|
||||
</small>
|
||||
@ -375,6 +379,11 @@ 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\\"
|
||||
@ -426,7 +435,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
class=\\"form-group switch\\"
|
||||
>
|
||||
<div
|
||||
@@ -501,10 +580,11 @@
|
||||
@@ -506,10 +590,11 @@
|
||||
<div
|
||||
class=\\"text-right\\"
|
||||
>
|
||||
@ -445,7 +454,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -22,10 +22,462 @@
|
||||
@@ -22,10 +22,467 @@
|
||||
Wi-Fi 1
|
||||
</h2>
|
||||
</label>
|
||||
@ -485,6 +494,11 @@ 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\\"
|
||||
@ -560,7 +574,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ GHz
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-radio\\"
|
||||
+ class=\\"custom-control custom-radio custom-control-inline\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"custom-control-input\\"
|
||||
@ -577,7 +591,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ </label>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-radio\\"
|
||||
+ class=\\"custom-control custom-radio custom-control-inline\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ checked=\\"\\"
|
||||
@ -876,7 +890,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ </select>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group \\"
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-switch\\"
|
||||
|
@ -19,6 +19,9 @@ 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.
|
||||
`),
|
||||
|
@ -22,7 +22,7 @@ exports[`<RebootButton/> Render modal. 1`] = `
|
||||
<h5
|
||||
class="modal-title"
|
||||
>
|
||||
Reboot confirmation
|
||||
Warning!
|
||||
</h5>
|
||||
<button
|
||||
class="close"
|
||||
|
@ -39,7 +39,6 @@ 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 {
|
||||
@ -70,6 +69,8 @@ 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";
|
||||
|
23
src/utils/displayCard.js
Normal file
23
src/utils/displayCard.js
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -20,6 +20,8 @@ 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",
|
||||
|
9
src/utils/isPluginInstalled.js
Normal file
9
src/utils/isPluginInstalled.js
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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);
|
@ -1,7 +0,0 @@
|
||||
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")
|
Reference in New Issue
Block a user