foris 5.6.1 → 6.0.0-beta.0b02bead

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/api/hooks.js +11 -3
  2. package/bootstrap/Alert.js +14 -10
  3. package/bootstrap/Button.js +7 -10
  4. package/bootstrap/CheckBox.js +22 -20
  5. package/bootstrap/CopyInput.js +7 -3
  6. package/bootstrap/DataTimeInput.js +9 -6
  7. package/bootstrap/DownloadButton.js +5 -2
  8. package/bootstrap/EmailInput.js +7 -2
  9. package/bootstrap/FileInput.js +6 -3
  10. package/bootstrap/Input.js +20 -10
  11. package/bootstrap/Modal.js +6 -6
  12. package/bootstrap/NumberInput.js +28 -25
  13. package/bootstrap/PasswordInput.js +20 -21
  14. package/bootstrap/RadioSet.js +26 -33
  15. package/bootstrap/Select.js +15 -8
  16. package/bootstrap/Spinner.css +10 -4
  17. package/bootstrap/Spinner.js +2 -1
  18. package/bootstrap/Switch.js +27 -23
  19. package/bootstrap/TextInput.js +8 -3
  20. package/bootstrap/constants.js +5 -4
  21. package/common/RebootButton.js +9 -7
  22. package/common/WiFiSettings/ResetWiFiSettings.js +11 -8
  23. package/common/WiFiSettings/WiFiForm.js +16 -16
  24. package/common/WiFiSettings/WiFiGuestForm.js +6 -5
  25. package/common/WiFiSettings/WiFiQRCode.js +6 -5
  26. package/common/WiFiSettings/WiFiSettings.js +7 -4
  27. package/context/alertContext/AlertContext.js +10 -5
  28. package/context/customizationContext/CustomizationContext.js +24 -13
  29. package/foris-6.0.0.tgz +0 -0
  30. package/form/components/ForisForm.js +16 -14
  31. package/form/components/SubmitButton.js +2 -1
  32. package/form/hooks.js +3 -2
  33. package/index.js +27 -27
  34. package/package.json +25 -26
  35. package/utils/ErrorMessage.js +5 -2
  36. package/utils/Portal.js +10 -2
  37. package/utils/conditionalHOCs.js +14 -7
  38. package/utils/datetime.js +3 -4
  39. package/utils/displayCard.js +4 -2
  40. package/utils/hooks.js +1 -1
  41. package/utils/isPluginInstalled.js +4 -2
  42. package/utils/validations.js +6 -3
  43. package/webSockets/WebSockets.js +4 -4
  44. package/webSockets/hooks.js +5 -2
  45. package/foris-5.6.1.tgz +0 -0
@@ -1,11 +1,12 @@
1
1
  /*
2
- * Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2020-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
  import { useUID } from "react-uid";
11
12
 
@@ -17,7 +18,7 @@ RadioSet.propTypes = {
17
18
  /** Choices . */
18
19
  choices: PropTypes.arrayOf(
19
20
  PropTypes.shape({
20
- /** Choice lable . */
21
+ /** Choice label . */
21
22
  label: PropTypes.oneOfType([
22
23
  PropTypes.string,
23
24
  PropTypes.element,
@@ -36,15 +37,7 @@ RadioSet.propTypes = {
36
37
  inline: PropTypes.bool,
37
38
  };
38
39
 
39
- export function RadioSet({
40
- name,
41
- label,
42
- choices,
43
- value,
44
- helpText,
45
- inline,
46
- ...props
47
- }) {
40
+ function RadioSet({ name, label, choices, value, helpText, inline, ...props }) {
48
41
  const uid = useUID();
49
42
  const radios = choices.map((choice, key) => {
50
43
  const id = `${name}-${key}`;
@@ -64,7 +57,7 @@ export function RadioSet({
64
57
  });
65
58
 
66
59
  return (
67
- <div className="form-group">
60
+ <div className="mb-3">
68
61
  {label && (
69
62
  <label htmlFor={uid} className="d-block">
70
63
  {label}
@@ -72,7 +65,9 @@ export function RadioSet({
72
65
  )}
73
66
  {radios}
74
67
  {helpText && (
75
- <small className="form-text text-muted">{helpText}</small>
68
+ <div className="form-text">
69
+ <small>{helpText}</small>
70
+ </div>
76
71
  )}
77
72
  </div>
78
73
  );
@@ -92,27 +87,25 @@ Radio.propTypes = {
92
87
 
93
88
  export function Radio({ label, id, helpText, inline, ...props }) {
94
89
  return (
95
- <>
96
- <div
97
- className={`custom-control custom-radio ${
98
- inline ? "custom-control-inline" : ""
99
- }`.trim()}
100
- >
101
- <input
102
- id={id}
103
- className="custom-control-input"
104
- type="radio"
105
- {...props}
106
- />
107
- <label className="custom-control-label" htmlFor={id}>
108
- {label}
109
- </label>
90
+ <div
91
+ className={`mb-2 ${inline ? "form-check form-check-inline" : ""}`.trim()}
92
+ >
93
+ <input
94
+ id={id}
95
+ className="form-check-input me-2"
96
+ type="radio"
97
+ {...props}
98
+ />
99
+ <label className="form-check-label" htmlFor={id}>
100
+ {label}
110
101
  {helpText && (
111
- <small className="form-text text-muted mt-0 mb-3">
112
- {helpText}
113
- </small>
102
+ <div className="form-text">
103
+ <small>{helpText}</small>
104
+ </div>
114
105
  )}
115
- </div>
116
- </>
106
+ </label>
107
+ </div>
117
108
  );
118
109
  }
110
+
111
+ export default RadioSet;
@@ -1,11 +1,12 @@
1
1
  /*
2
- * Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
  import { useUID } from "react-uid";
11
12
 
@@ -20,7 +21,7 @@ Select.propTypes = {
20
21
  helpText: PropTypes.string,
21
22
  };
22
23
 
23
- export function Select({ label, choices, helpText, ...props }) {
24
+ function Select({ label, choices, helpText, ...props }) {
24
25
  const uid = useUID();
25
26
 
26
27
  const options = Object.keys(choices).map((choice) => (
@@ -30,14 +31,20 @@ export function Select({ label, choices, helpText, ...props }) {
30
31
  ));
31
32
 
32
33
  return (
33
- <div className="form-group">
34
- <label htmlFor={uid}>{label}</label>
35
- <select className="custom-select" id={uid} {...props}>
34
+ <div className="mb-3">
35
+ <label className="form-label" htmlFor={uid}>
36
+ {label}
37
+ </label>
38
+ <select className="form-select" id={uid} {...props}>
36
39
  {options}
37
40
  </select>
38
- {helpText ? (
39
- <small className="form-text text-muted">{helpText}</small>
40
- ) : null}
41
+ {helpText && (
42
+ <div className="form-text">
43
+ <small>{helpText}</small>
44
+ </div>
45
+ )}
41
46
  </div>
42
47
  );
43
48
  }
49
+
50
+ export default Select;
@@ -1,3 +1,11 @@
1
+ .spinner-fs-wrapper {
2
+ position: fixed;
3
+ top: 50%;
4
+ left: 50%;
5
+ transform: translate(-50%, -50%);
6
+ z-index: 1101; /* increase z-index by 1 to ensure it's on top of spinner-fs-background */
7
+ }
8
+
1
9
  .spinner-wrapper .spinner-border {
2
10
  width: 4rem;
3
11
  height: 4rem;
@@ -7,10 +15,8 @@
7
15
  .spinner-fs-background {
8
16
  background-color: rgba(2, 2, 2, 0.5);
9
17
  color: rgb(230, 230, 230);
10
- position: fixed;
11
- width: 100%;
12
- height: 100%;
13
- top: 0;
18
+ width: 100vw;
19
+ height: 100vh;
14
20
 
15
21
  display: flex;
16
22
  align-items: center;
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
12
  import "./Spinner.css";
@@ -16,7 +17,7 @@ Spinner.propTypes = {
16
17
  PropTypes.arrayOf(PropTypes.node),
17
18
  PropTypes.node,
18
19
  ]),
19
- /** Render component with full-screen mode (using apropriate `.css` styles) */
20
+ /** Render component with full-screen mode (using appropriate `.css` styles) */
20
21
  fullScreen: PropTypes.bool.isRequired,
21
22
  className: PropTypes.string,
22
23
  };
@@ -1,11 +1,12 @@
1
1
  /*
2
- * Copyright (c) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (c) 2020-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
  import { useUID } from "react-uid";
11
12
 
@@ -18,32 +19,35 @@ Switch.propTypes = {
18
19
  ]).isRequired,
19
20
  helpText: PropTypes.string,
20
21
  switchHeading: PropTypes.bool,
22
+ className: PropTypes.string,
21
23
  };
22
24
 
23
- export function Switch({ label, helpText, switchHeading, ...props }) {
25
+ function Switch({ label, helpText, switchHeading, className, ...props }) {
24
26
  const uid = useUID();
27
+
25
28
  return (
26
- <div className={`form-group ${switchHeading ? "switch" : ""}`.trim()}>
27
- <div
28
- className={`custom-control custom-switch ${
29
- !helpText ? "custom-control-inline" : ""
30
- } ${switchHeading ? "switch-heading" : ""}`.trim()}
31
- >
32
- <input
33
- type="checkbox"
34
- className="custom-control-input"
35
- id={uid}
36
- {...props}
37
- />
38
- <label className="custom-control-label" htmlFor={uid}>
39
- {label}
40
- </label>
41
- {helpText && (
42
- <small className="form-text text-muted mt-0 mb-3">
43
- {helpText}
44
- </small>
45
- )}
46
- </div>
29
+ <div
30
+ className={`form-check form-switch ${className || "mb-3"} ${
31
+ switchHeading ? "d-flex align-items-center" : ""
32
+ }`.trim()}
33
+ >
34
+ <input
35
+ type="checkbox"
36
+ className={`form-check-input ${switchHeading ? "me-2" : ""}`.trim()}
37
+ role="switch"
38
+ id={uid}
39
+ {...props}
40
+ />
41
+ <label className="form-check-label" htmlFor={uid}>
42
+ {label}
43
+ </label>
44
+ {helpText && (
45
+ <div className="form-text">
46
+ <small>{helpText}</small>
47
+ </div>
48
+ )}
47
49
  </div>
48
50
  );
49
51
  }
52
+
53
+ export default Switch;
@@ -1,16 +1,19 @@
1
1
  /*
2
- * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
- import { Input } from "./Input";
12
+ import Input from "./Input";
12
13
 
13
- export const TextInput = ({ ...props }) => <Input type="text" {...props} />;
14
+ function TextInput({ ...props }) {
15
+ return <Input type="text" {...props} />;
16
+ }
14
17
 
15
18
  TextInput.propTypes = {
16
19
  /** Field label. */
@@ -20,3 +23,5 @@ TextInput.propTypes = {
20
23
  /** Help text message. */
21
24
  helpText: PropTypes.string,
22
25
  };
26
+
27
+ export default TextInput;
@@ -1,11 +1,12 @@
1
1
  /*
2
- * Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  /** Bootstrap column size for form fields */
9
- // eslint-disable-next-line import/prefer-default-export
10
- export const formFieldsSize = "card p-4 col-sm-12 col-lg-12 p-0 mb-4";
11
- export const buttonFormFieldsSize = "col-sm-12 col-lg-12 p-0 mb-3";
9
+ const formFieldsSize = "card p-4 col-sm-12 col-lg-12 p-0 mb-4";
10
+ const buttonFormFieldsSize = "col-sm-12 col-lg-12 p-0 mb-3";
11
+
12
+ export { formFieldsSize, buttonFormFieldsSize };
@@ -1,22 +1,22 @@
1
1
  /*
2
- * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React, { useState, useEffect } from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
12
  import { useAPIPost } from "../api/hooks";
12
13
  import { API_STATE } from "../api/utils";
13
- import { ForisURLs } from "../utils/forisUrls";
14
-
15
- import { Button } from "../bootstrap/Button";
14
+ import Button from "../bootstrap/Button";
16
15
  import { Modal, ModalHeader, ModalBody, ModalFooter } from "../bootstrap/Modal";
17
16
  import { useAlert } from "../context/alertContext/AlertContext";
17
+ import { ForisURLs } from "../utils/forisUrls";
18
18
 
19
- export function RebootButton(props) {
19
+ function RebootButton(props) {
20
20
  const [triggered, setTriggered] = useState(false);
21
21
  const [modalShown, setModalShown] = useState(false);
22
22
  const [triggerRebootStatus, triggerReboot] = useAPIPost(ForisURLs.reboot);
@@ -28,11 +28,11 @@ export function RebootButton(props) {
28
28
  }
29
29
  });
30
30
 
31
- function rebootHandler() {
31
+ const rebootHandler = () => {
32
32
  setTriggered(true);
33
33
  triggerReboot();
34
34
  setModalShown(false);
35
- }
35
+ };
36
36
 
37
37
  return (
38
38
  <>
@@ -76,3 +76,5 @@ function RebootModal({ shown, setShown, onReboot }) {
76
76
  </Modal>
77
77
  );
78
78
  }
79
+
80
+ export default RebootButton;
@@ -1,26 +1,27 @@
1
1
  /*
2
- * Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React, { useEffect, useState } from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
- import { Button } from "../../bootstrap/Button";
12
- import { useAlert } from "../../context/alertContext/AlertContext";
13
- import { ALERT_TYPES } from "../../bootstrap/Alert";
14
12
  import { useAPIPost } from "../../api/hooks";
15
13
  import { API_STATE } from "../../api/utils";
14
+ import { ALERT_TYPES } from "../../bootstrap/Alert";
15
+ import Button from "../../bootstrap/Button";
16
16
  import { formFieldsSize } from "../../bootstrap/constants";
17
+ import { useAlert } from "../../context/alertContext/AlertContext";
17
18
 
18
19
  ResetWiFiSettings.propTypes = {
19
20
  ws: PropTypes.object.isRequired,
20
21
  endpoint: PropTypes.string.isRequired,
21
22
  };
22
23
 
23
- export function ResetWiFiSettings({ ws, endpoint }) {
24
+ function ResetWiFiSettings({ ws, endpoint }) {
24
25
  const [isLoading, setIsLoading] = useState(false);
25
26
 
26
27
  useEffect(() => {
@@ -44,11 +45,11 @@ export function ResetWiFiSettings({ ws, endpoint }) {
44
45
  }
45
46
  }, [postResetResponse, setAlert]);
46
47
 
47
- function onReset() {
48
+ const onReset = () => {
48
49
  dismissAlert();
49
50
  setIsLoading(true);
50
51
  postReset();
51
- }
52
+ };
52
53
 
53
54
  return (
54
55
  <div className={formFieldsSize}>
@@ -58,7 +59,7 @@ export function ResetWiFiSettings({ ws, endpoint }) {
58
59
  "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."
59
60
  )}
60
61
  </p>
61
- <div className="text-right">
62
+ <div className="text-end">
62
63
  <Button
63
64
  className="btn-primary"
64
65
  forisFormSize
@@ -72,3 +73,5 @@ export function ResetWiFiSettings({ ws, endpoint }) {
72
73
  </div>
73
74
  );
74
75
  }
76
+
77
+ export default ResetWiFiSettings;
@@ -6,15 +6,17 @@
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
- import { Switch } from "../../bootstrap/Switch";
11
- import { PasswordInput } from "../../bootstrap/PasswordInput";
12
- import { RadioSet } from "../../bootstrap/RadioSet";
13
- import { Select } from "../../bootstrap/Select";
14
- import { TextInput } from "../../bootstrap/TextInput";
15
- import WiFiQRCode from "./WiFiQRCode";
16
- import WifiGuestForm from "./WiFiGuestForm";
11
+
17
12
  import { HELP_TEXTS, HTMODES, HWMODES, ENCRYPTIONMODES } from "./constants";
13
+ import WifiGuestForm from "./WiFiGuestForm";
14
+ import WiFiQRCode from "./WiFiQRCode";
15
+ import PasswordInput from "../../bootstrap/PasswordInput";
16
+ import RadioSet from "../../bootstrap/RadioSet";
17
+ import Select from "../../bootstrap/Select";
18
+ import Switch from "../../bootstrap/Switch";
19
+ import TextInput from "../../bootstrap/TextInput";
18
20
 
19
21
  WiFiForm.propTypes = {
20
22
  formData: PropTypes.shape({ devices: PropTypes.arrayOf(PropTypes.object) })
@@ -92,7 +94,7 @@ function DeviceForm({
92
94
  return (
93
95
  <>
94
96
  <Switch
95
- label={<h2>{_(`Wi-Fi ${deviceID + 1}`)}</h2>}
97
+ label={<h2 className="mb-0">{_(`Wi-Fi ${deviceID + 1}`)}</h2>}
96
98
  checked={formData.enabled}
97
99
  onChange={setFormValue((value) => ({
98
100
  devices: {
@@ -119,12 +121,10 @@ function DeviceForm({
119
121
  }))}
120
122
  {...props}
121
123
  >
122
- <div className="input-group-append">
123
- <WiFiQRCode
124
- SSID={formData.SSID}
125
- password={formData.password}
126
- />
127
- </div>
124
+ <WiFiQRCode
125
+ SSID={formData.SSID}
126
+ password={formData.password}
127
+ />
128
128
  </TextInput>
129
129
 
130
130
  <PasswordInput
@@ -269,8 +269,8 @@ function getChannelChoices(device) {
269
269
  channelChoices[availableChannel.number.toString()] = `
270
270
  ${availableChannel.number}
271
271
  (${availableChannel.frequency} MHz ${
272
- availableChannel.radar ? " ,DFS" : ""
273
- })
272
+ availableChannel.radar ? " ,DFS" : ""
273
+ })
274
274
  `;
275
275
  });
276
276
  });
@@ -1,18 +1,19 @@
1
1
  /*
2
- * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
- import { TextInput } from "../../bootstrap/TextInput";
12
- import { Switch } from "../../bootstrap/Switch";
13
- import { PasswordInput } from "../../bootstrap/PasswordInput";
14
- import WiFiQRCode from "./WiFiQRCode";
15
12
  import { HELP_TEXTS } from "./constants";
13
+ import WiFiQRCode from "./WiFiQRCode";
14
+ import PasswordInput from "../../bootstrap/PasswordInput";
15
+ import Switch from "../../bootstrap/Switch";
16
+ import TextInput from "../../bootstrap/TextInput";
16
17
 
17
18
  WifiGuestForm.propTypes = {
18
19
  formData: PropTypes.shape({
@@ -6,18 +6,19 @@
6
6
  */
7
7
 
8
8
  import React, { useState } from "react";
9
- import QRCode from "qrcode.react";
9
+
10
10
  import PropTypes from "prop-types";
11
+ import QRCode from "qrcode.react";
11
12
 
12
- import { ForisURLs } from "../../utils/forisUrls";
13
- import { Button } from "../../bootstrap/Button";
13
+ import { createAndDownloadPdf, toQRCodeContent } from "./qrCodeHelpers";
14
+ import Button from "../../bootstrap/Button";
14
15
  import {
15
16
  Modal,
16
17
  ModalBody,
17
18
  ModalFooter,
18
19
  ModalHeader,
19
20
  } from "../../bootstrap/Modal";
20
- import { createAndDownloadPdf, toQRCodeContent } from "./qrCodeHelpers";
21
+ import { ForisURLs } from "../../utils/forisUrls";
21
22
 
22
23
  WiFiQRCode.propTypes = {
23
24
  SSID: PropTypes.string.isRequired,
@@ -87,7 +88,7 @@ function QRCodeModal({ shown, setShown, SSID, password }) {
87
88
  createAndDownloadPdf(SSID, password);
88
89
  }}
89
90
  >
90
- <i className="fas fa-arrow-down mr-2" />
91
+ <i className="fas fa-file-download me-2" />
91
92
  {_("Download PDF")}
92
93
  </Button>
93
94
  </ModalFooter>
@@ -1,16 +1,17 @@
1
1
  /*
2
- * Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
8
  import React from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
- import { ForisForm } from "../../form/components/ForisForm";
12
+ import ResetWiFiSettings from "./ResetWiFiSettings";
12
13
  import WiFiForm from "./WiFiForm";
13
- import { ResetWiFiSettings } from "./ResetWiFiSettings";
14
+ import ForisForm from "../../form/components/ForisForm";
14
15
 
15
16
  WiFiSettings.propTypes = {
16
17
  ws: PropTypes.object.isRequired,
@@ -19,7 +20,7 @@ WiFiSettings.propTypes = {
19
20
  hasGuestNetwork: PropTypes.bool,
20
21
  };
21
22
 
22
- export function WiFiSettings({ ws, endpoint, resetEndpoint, hasGuestNetwork }) {
23
+ function WiFiSettings({ ws, endpoint, resetEndpoint, hasGuestNetwork }) {
23
24
  return (
24
25
  <>
25
26
  <ForisForm
@@ -117,3 +118,5 @@ export function validator(formData) {
117
118
  });
118
119
  return JSON.stringify(formErrors).match(/\[[{},?]+\]/) ? null : formErrors;
119
120
  }
121
+
122
+ export default WiFiSettings;
@@ -1,15 +1,16 @@
1
1
  /*
2
- * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
- import React, { useState, useContext, useCallback } from "react";
8
+ import React, { useState, useContext, useCallback, useMemo } from "react";
9
+
9
10
  import PropTypes from "prop-types";
10
11
 
11
- import { Alert, ALERT_TYPES } from "../../bootstrap/Alert";
12
- import { Portal } from "../../utils/Portal";
12
+ import Alert, { ALERT_TYPES } from "../../bootstrap/Alert";
13
+ import Portal from "../../utils/Portal";
13
14
 
14
15
  AlertContextProvider.propTypes = {
15
16
  children: PropTypes.oneOfType([
@@ -30,6 +31,10 @@ function AlertContextProvider({ children }) {
30
31
  );
31
32
 
32
33
  const dismissAlert = useCallback(() => setAlert(null), [setAlert]);
34
+ const contextValue = useMemo(
35
+ () => [setAlertWrapper, dismissAlert],
36
+ [setAlertWrapper, dismissAlert]
37
+ );
33
38
 
34
39
  return (
35
40
  <>
@@ -40,7 +45,7 @@ function AlertContextProvider({ children }) {
40
45
  </Alert>
41
46
  </Portal>
42
47
  )}
43
- <AlertContext.Provider value={[setAlertWrapper, dismissAlert]}>
48
+ <AlertContext.Provider value={contextValue}>
44
49
  {children}
45
50
  </AlertContext.Provider>
46
51
  </>