mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-15 13:36:35 +02:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
a352f12279 | |||
acfbeb2c43 | |||
3bef624ce4 | |||
7d0d52666d | |||
52fe5d65a6 | |||
b99add91cf | |||
b7a4613cf4 | |||
9e2278e016 | |||
83a6ff75f6 | |||
02f3803265 | |||
bb559cbe53 | |||
c86e2c8944 | |||
b96ccde81c | |||
cfa6eade17 | |||
380a388a38 | |||
cc19b4b293 | |||
e7ec494bb2 | |||
ea590e443c | |||
b127bf5edf | |||
40e4a9a4e3 | |||
bcb7c43863 |
30
CHANGELOG.md
30
CHANGELOG.md
@ -8,6 +8,32 @@ and this project adheres to
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [6.2.0] - 2024-09-20
|
||||
|
||||
### Added
|
||||
|
||||
- Added useFocusTrap hook
|
||||
- Added extendSession endpoint
|
||||
|
||||
### Changed
|
||||
|
||||
- Refactored Spinner.css to use CSS variable for color
|
||||
- Refactored Modal component to use useFocusTrap hook
|
||||
- Refactored Alert component to use useFocusTrap hook
|
||||
|
||||
## [6.1.1] - 2024-08-30
|
||||
|
||||
### Added
|
||||
|
||||
- Added & updated Weblate translations
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated icon color classes to use "text-secondary" instead of "text-dark"
|
||||
- Updated Wi-Fi QRCodeModal component to use new styles & added close button
|
||||
- Refactored WiFiGuestForm component to get rid of obsolete div element
|
||||
- NPM audit fix
|
||||
|
||||
## [6.1.0] - 2024-08-23
|
||||
|
||||
### Added
|
||||
@ -348,7 +374,9 @@ and this project adheres to
|
||||
## [0.0.7] - 2019-09-02
|
||||
|
||||
[unreleased]:
|
||||
https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.1.0...master
|
||||
https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.2.0...dev
|
||||
[6.2.0]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.1.1...v6.2.0
|
||||
[6.1.1]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.1.0...v6.1.1
|
||||
[6.1.0]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.0.3...v6.1.0
|
||||
[6.0.3]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.0.2...v6.0.3
|
||||
[6.0.2]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.0.1...v6.0.2
|
||||
|
73
package-lock.json
generated
73
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "foris",
|
||||
"version": "6.1.0",
|
||||
"version": "6.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "foris",
|
||||
"version": "6.1.0",
|
||||
"version": "6.2.0",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
||||
@ -3722,21 +3722,13 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
|
||||
"integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "*",
|
||||
"@types/json-schema": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint-scope": {
|
||||
"version": "3.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
|
||||
"integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/eslint": "*",
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
@ -6731,10 +6723,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.17.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz",
|
||||
"integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==",
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
@ -6748,6 +6741,7 @@
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@ -13785,10 +13779,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
@ -17822,13 +17817,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.92.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz",
|
||||
"integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==",
|
||||
"version": "5.94.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^1.0.5",
|
||||
"@webassemblyjs/ast": "^1.12.1",
|
||||
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||
@ -17837,7 +17831,7 @@
|
||||
"acorn-import-attributes": "^1.9.5",
|
||||
"browserslist": "^4.21.10",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.17.0",
|
||||
"enhanced-resolve": "^5.17.1",
|
||||
"es-module-lexer": "^1.2.1",
|
||||
"eslint-scope": "5.1.1",
|
||||
"events": "^3.2.0",
|
||||
@ -21181,21 +21175,13 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
|
||||
"integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@types/estree": "*",
|
||||
"@types/json-schema": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint-scope": {
|
||||
"version": "3.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
|
||||
"integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint": "*",
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
@ -23537,9 +23523,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "5.17.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz",
|
||||
"integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==",
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
@ -28840,9 +28826,9 @@
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"braces": "^3.0.3",
|
||||
@ -31815,12 +31801,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.92.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz",
|
||||
"integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==",
|
||||
"version": "5.94.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^1.0.5",
|
||||
"@webassemblyjs/ast": "^1.12.1",
|
||||
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||
@ -31829,7 +31814,7 @@
|
||||
"acorn-import-attributes": "^1.9.5",
|
||||
"browserslist": "^4.21.10",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.17.0",
|
||||
"enhanced-resolve": "^5.17.1",
|
||||
"es-module-lexer": "^1.2.1",
|
||||
"eslint-scope": "5.1.1",
|
||||
"events": "^3.2.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "foris",
|
||||
"version": "6.1.0",
|
||||
"version": "6.2.0",
|
||||
"description": "Foris JS library is a set of components and utils for reForis application and plugins.",
|
||||
"author": "CZ.NIC, z.s.p.o.",
|
||||
"repository": {
|
||||
|
@ -5,10 +5,12 @@
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { useRef } from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { useFocusTrap } from "../utils/hooks";
|
||||
|
||||
export const ALERT_TYPES = Object.freeze({
|
||||
PRIMARY: "primary",
|
||||
SECONDARY: "secondary",
|
||||
@ -37,11 +39,15 @@ Alert.defaultProps = {
|
||||
};
|
||||
|
||||
function Alert({ type, onDismiss, children }) {
|
||||
const alertRef = useRef();
|
||||
useFocusTrap(alertRef, !!onDismiss);
|
||||
return (
|
||||
<div
|
||||
ref={alertRef}
|
||||
className={`alert alert-${type} ${
|
||||
onDismiss ? "alert-dismissible" : ""
|
||||
}`.trim()}
|
||||
role="alert"
|
||||
>
|
||||
{onDismiss && (
|
||||
<button
|
||||
|
@ -9,7 +9,7 @@ import React, { useRef, useEffect } from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { useClickOutside } from "../utils/hooks";
|
||||
import { useClickOutside, useFocusTrap } from "../utils/hooks";
|
||||
import Portal from "../utils/Portal";
|
||||
import "./Modal.css";
|
||||
|
||||
@ -29,10 +29,11 @@ Modal.propTypes = {
|
||||
};
|
||||
|
||||
export function Modal({ shown, setShown, scrollable, size, children }) {
|
||||
const dialogRef = useRef();
|
||||
const modalRef = useRef();
|
||||
let modalSize = "modal-";
|
||||
|
||||
useClickOutside(dialogRef, () => setShown(false));
|
||||
useClickOutside(modalRef, () => setShown(false));
|
||||
useFocusTrap(modalRef, shown);
|
||||
|
||||
useEffect(() => {
|
||||
const handleEsc = (event) => {
|
||||
@ -65,11 +66,13 @@ export function Modal({ shown, setShown, scrollable, size, children }) {
|
||||
return (
|
||||
<Portal containerId="modal-container">
|
||||
<div
|
||||
ref={modalRef}
|
||||
className={`modal fade ${shown ? "show" : ""}`.trim()}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-title"
|
||||
>
|
||||
<div
|
||||
ref={dialogRef}
|
||||
className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
|
||||
scrollable ? "modal-dialog-scrollable" : ""
|
||||
}`.trim()}
|
||||
@ -90,7 +93,7 @@ ModalHeader.propTypes = {
|
||||
export function ModalHeader({ setShown, title }) {
|
||||
return (
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title">{title}</h5>
|
||||
<h1 className="modal-title fs-5">{title}</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close"
|
||||
|
@ -49,7 +49,7 @@ function PasswordInput({ withEye, newPass, ...props }) {
|
||||
<FontAwesomeIcon
|
||||
icon={isHidden ? faEye : faEyeSlash}
|
||||
style={{ width: "1.25rem" }}
|
||||
className="text-dark"
|
||||
className="text-secondary"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
|
@ -9,7 +9,7 @@
|
||||
.spinner-wrapper .spinner-border {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
color: #00a2e2;
|
||||
color: var(--bs-primary);
|
||||
}
|
||||
|
||||
.spinner-fs-background {
|
||||
|
@ -68,14 +68,11 @@ export default function WifiGuestForm({
|
||||
}))}
|
||||
{...props}
|
||||
>
|
||||
<div className="input-group-append">
|
||||
<WiFiQRCode
|
||||
SSID={formData.SSID}
|
||||
password={formData.password}
|
||||
/>
|
||||
</div>
|
||||
<WiFiQRCode
|
||||
SSID={formData.SSID}
|
||||
password={formData.password}
|
||||
/>
|
||||
</TextInput>
|
||||
|
||||
<PasswordInput
|
||||
withEye
|
||||
label={_("Password")}
|
||||
|
@ -42,7 +42,7 @@ export default function WiFiQRCode({ SSID, password }) {
|
||||
icon="fa-solid fa-qrcode"
|
||||
title={_("Show QR code")}
|
||||
aria-label={_("Show QR code")}
|
||||
className="text-dark"
|
||||
className="text-secondary"
|
||||
/>
|
||||
</button>
|
||||
{modal ? (
|
||||
@ -70,17 +70,26 @@ function QRCodeModal({ shown, setShown, SSID, password }) {
|
||||
<ModalHeader setShown={setShown} title={_("Wi-Fi QR Code")} />
|
||||
<ModalBody>
|
||||
<QRCode
|
||||
className="d-block mx-auto img-logo-black"
|
||||
renderAs="svg"
|
||||
value={toQRCodeContent(SSID, password)}
|
||||
level="M"
|
||||
size={350}
|
||||
includeMargin
|
||||
style={{ display: "block", margin: "auto" }}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button
|
||||
className="btn-outline-primary"
|
||||
className="btn-secondary"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setShown(false);
|
||||
}}
|
||||
>
|
||||
{_("Close")}
|
||||
</Button>
|
||||
<Button
|
||||
className="btn-primary"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
createAndDownloadPdf(SSID, password);
|
||||
|
@ -339,7 +339,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -524,10 +524,91 @@
|
||||
@@ -524,10 +524,87 @@
|
||||
<small>
|
||||
Enables Wi-Fi for guests, which is separated from LAN network. Devices connected to this network are allowed to access the internet, but aren't allowed to access other devices and the configuration interface of the router. Parameters of the guest network can be set in the Guest network tab.
|
||||
</small>
|
||||
@ -363,18 +363,14 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
+ type="text"
|
||||
+ value="TestGuestSSID"
|
||||
+ />
|
||||
+ <div
|
||||
+ class="input-group-append"
|
||||
+ <button
|
||||
+ class="input-group-text"
|
||||
+ type="button"
|
||||
+ >
|
||||
+ <button
|
||||
+ class="input-group-text"
|
||||
+ type="button"
|
||||
+ >
|
||||
+ <i
|
||||
+ class="fa"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ <i
|
||||
+ class="fa"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class="form-text"
|
||||
@ -431,7 +427,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
class="form-check form-switch mb-3 d-flex align-items-center"
|
||||
>
|
||||
<input
|
||||
@@ -550,10 +631,11 @@
|
||||
@@ -550,10 +627,11 @@
|
||||
<div
|
||||
class="text-end"
|
||||
>
|
||||
|
@ -6,6 +6,8 @@ exports[`<RebootButton/> Render modal. 1`] = `
|
||||
id="modal-container"
|
||||
>
|
||||
<div
|
||||
aria-labelledby="modal-title"
|
||||
aria-modal="true"
|
||||
class="modal fade show"
|
||||
role="dialog"
|
||||
>
|
||||
@ -19,11 +21,11 @@ exports[`<RebootButton/> Render modal. 1`] = `
|
||||
<div
|
||||
class="modal-header"
|
||||
>
|
||||
<h5
|
||||
class="modal-title"
|
||||
<h1
|
||||
class="modal-title fs-5"
|
||||
>
|
||||
Warning!
|
||||
</h5>
|
||||
</h1>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="btn-close"
|
||||
|
@ -7,6 +7,7 @@ exports[`AlertContext should render alert 1`] = `
|
||||
>
|
||||
<div
|
||||
class="alert alert-danger alert-dismissible"
|
||||
role="alert"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -9,8 +9,10 @@ export const REFORIS_URL_PREFIX = "/reforis";
|
||||
export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
|
||||
|
||||
export const ForisURLs = {
|
||||
// turris-auth
|
||||
login: `/login?${REFORIS_URL_PREFIX}/`,
|
||||
logout: `/logout`,
|
||||
extendSession: `/extend-session`,
|
||||
|
||||
static: `${REFORIS_URL_PREFIX}/static/reforis`,
|
||||
wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
|
||||
|
@ -40,3 +40,40 @@ export function useClickOutside(element, callback) {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* Trap focus inside element. */
|
||||
export function useFocusTrap(elementRef, condition = true) {
|
||||
useEffect(() => {
|
||||
if (!condition) {
|
||||
return;
|
||||
}
|
||||
const currentElement = elementRef.current;
|
||||
const focusableElements = currentElement.querySelectorAll(
|
||||
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
||||
);
|
||||
const firstElement = focusableElements[0];
|
||||
const lastElement = focusableElements[focusableElements.length - 1];
|
||||
|
||||
const handleTab = (event) => {
|
||||
if (event.key === "Tab") {
|
||||
if (event.shiftKey) {
|
||||
if (document.activeElement === firstElement) {
|
||||
lastElement.focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
} else if (document.activeElement === lastElement) {
|
||||
firstElement.focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
currentElement.addEventListener("keydown", handleTab);
|
||||
|
||||
firstElement.focus();
|
||||
|
||||
return () => {
|
||||
currentElement.removeEventListener("keydown", handleTab);
|
||||
};
|
||||
}, [elementRef, condition]);
|
||||
}
|
||||
|
@ -8,15 +8,16 @@ msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2024-08-23 14:02+0200\n"
|
||||
"PO-Revision-Date: 2022-09-11 17:15+0000\n"
|
||||
"Last-Translator: Dan Cybersec <dan.cybersec@protonmail.com>\n"
|
||||
"PO-Revision-Date: 2024-08-24 13:09+0000\n"
|
||||
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
|
||||
"Language-Team: Spanish <https://hosted.weblate.org/projects/turris/foris-js/"
|
||||
"es/>\n"
|
||||
"Language: es\n"
|
||||
"Language-Team: Spanish <https://hosted.weblate.org/projects/turris/foris-"
|
||||
"js/es/>\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7.1-dev\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: src/api/utils.js:61
|
||||
@ -39,7 +40,7 @@ msgstr ""
|
||||
|
||||
#: src/bootstrap/Alert.js:51 src/bootstrap/Modal.js:98
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
msgstr "Cerrar"
|
||||
|
||||
#: src/bootstrap/CopyInput.js:57
|
||||
msgid "Copied!"
|
||||
@ -123,13 +124,15 @@ msgstr "Cifrado"
|
||||
|
||||
#: src/common/WiFiSettings/WiFiForm.js:226
|
||||
msgid "Disable Management Frame Protection"
|
||||
msgstr ""
|
||||
msgstr "Desactivar Protected Management Frames"
|
||||
|
||||
#: src/common/WiFiSettings/WiFiForm.js:227
|
||||
msgid ""
|
||||
"In case you have trouble connecting to WiFi Access Point, try disabling "
|
||||
"Management Frame Protection."
|
||||
msgstr ""
|
||||
"Si tienes problemas para conectarte a un punto de acceso Wi-Fi, intenta "
|
||||
"desactivar Management Frame Protection."
|
||||
|
||||
#: src/common/WiFiSettings/WiFiForm.js:262
|
||||
msgid "auto"
|
||||
@ -145,9 +148,8 @@ msgstr "Activar el modo Wi-Fi de invitados"
|
||||
|
||||
#: src/common/WiFiSettings/WiFiQRCode.js:43
|
||||
#: src/common/WiFiSettings/WiFiQRCode.js:44
|
||||
#, fuzzy
|
||||
msgid "Show QR code"
|
||||
msgstr "Código QR Wi-Fi"
|
||||
msgstr "Mostrar el código QR"
|
||||
|
||||
#: src/common/WiFiSettings/WiFiQRCode.js:70
|
||||
msgid "Wi-Fi QR Code"
|
||||
@ -444,4 +446,3 @@ msgstr "No contiene una lista de correos electrónicos separados por comas."
|
||||
#~ " default option with 20 MHz wide "
|
||||
#~ "channel."
|
||||
#~ msgstr ""
|
||||
|
||||
|
Reference in New Issue
Block a user