mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2024-11-14 17:35:35 +01:00
Compare commits
No commits in common. "a352f12279704f4db659983b5f39abcdbdb75cd2" and "bb559cbe5378be4bf1baeb38ae18c0be33320295" have entirely different histories.
a352f12279
...
bb559cbe53
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -8,19 +8,6 @@ and this project adheres to
|
||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [6.1.1] - 2024-08-30
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -374,8 +361,7 @@ and this project adheres to
|
||||||
## [0.0.7] - 2019-09-02
|
## [0.0.7] - 2019-09-02
|
||||||
|
|
||||||
[unreleased]:
|
[unreleased]:
|
||||||
https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.2.0...dev
|
https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.1.1...master
|
||||||
[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.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.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.3]: https://gitlab.nic.cz/turris/reforis/foris-js/-/compare/v6.0.2...v6.0.3
|
||||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "foris",
|
"name": "foris",
|
||||||
"version": "6.2.0",
|
"version": "6.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "foris",
|
"name": "foris",
|
||||||
"version": "6.2.0",
|
"version": "6.1.1",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "foris",
|
"name": "foris",
|
||||||
"version": "6.2.0",
|
"version": "6.1.1",
|
||||||
"description": "Foris JS library is a set of components and utils for reForis application and 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": {
|
||||||
|
|
|
@ -5,12 +5,10 @@
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useRef } from "react";
|
import React from "react";
|
||||||
|
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
import { useFocusTrap } from "../utils/hooks";
|
|
||||||
|
|
||||||
export const ALERT_TYPES = Object.freeze({
|
export const ALERT_TYPES = Object.freeze({
|
||||||
PRIMARY: "primary",
|
PRIMARY: "primary",
|
||||||
SECONDARY: "secondary",
|
SECONDARY: "secondary",
|
||||||
|
@ -39,15 +37,11 @@ Alert.defaultProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function Alert({ type, onDismiss, children }) {
|
function Alert({ type, onDismiss, children }) {
|
||||||
const alertRef = useRef();
|
|
||||||
useFocusTrap(alertRef, !!onDismiss);
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={alertRef}
|
|
||||||
className={`alert alert-${type} ${
|
className={`alert alert-${type} ${
|
||||||
onDismiss ? "alert-dismissible" : ""
|
onDismiss ? "alert-dismissible" : ""
|
||||||
}`.trim()}
|
}`.trim()}
|
||||||
role="alert"
|
|
||||||
>
|
>
|
||||||
{onDismiss && (
|
{onDismiss && (
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -9,7 +9,7 @@ import React, { useRef, useEffect } from "react";
|
||||||
|
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
import { useClickOutside, useFocusTrap } from "../utils/hooks";
|
import { useClickOutside } from "../utils/hooks";
|
||||||
import Portal from "../utils/Portal";
|
import Portal from "../utils/Portal";
|
||||||
import "./Modal.css";
|
import "./Modal.css";
|
||||||
|
|
||||||
|
@ -29,11 +29,10 @@ Modal.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Modal({ shown, setShown, scrollable, size, children }) {
|
export function Modal({ shown, setShown, scrollable, size, children }) {
|
||||||
const modalRef = useRef();
|
const dialogRef = useRef();
|
||||||
let modalSize = "modal-";
|
let modalSize = "modal-";
|
||||||
|
|
||||||
useClickOutside(modalRef, () => setShown(false));
|
useClickOutside(dialogRef, () => setShown(false));
|
||||||
useFocusTrap(modalRef, shown);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleEsc = (event) => {
|
const handleEsc = (event) => {
|
||||||
|
@ -66,13 +65,11 @@ export function Modal({ shown, setShown, scrollable, size, children }) {
|
||||||
return (
|
return (
|
||||||
<Portal containerId="modal-container">
|
<Portal containerId="modal-container">
|
||||||
<div
|
<div
|
||||||
ref={modalRef}
|
|
||||||
className={`modal fade ${shown ? "show" : ""}`.trim()}
|
className={`modal fade ${shown ? "show" : ""}`.trim()}
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
|
||||||
aria-labelledby="modal-title"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
ref={dialogRef}
|
||||||
className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
|
className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
|
||||||
scrollable ? "modal-dialog-scrollable" : ""
|
scrollable ? "modal-dialog-scrollable" : ""
|
||||||
}`.trim()}
|
}`.trim()}
|
||||||
|
@ -93,7 +90,7 @@ ModalHeader.propTypes = {
|
||||||
export function ModalHeader({ setShown, title }) {
|
export function ModalHeader({ setShown, title }) {
|
||||||
return (
|
return (
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h1 className="modal-title fs-5">{title}</h1>
|
<h5 className="modal-title">{title}</h5>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn-close"
|
className="btn-close"
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
.spinner-wrapper .spinner-border {
|
.spinner-wrapper .spinner-border {
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
color: var(--bs-primary);
|
color: #00a2e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner-fs-background {
|
.spinner-fs-background {
|
||||||
|
|
|
@ -6,8 +6,6 @@ exports[`<RebootButton/> Render modal. 1`] = `
|
||||||
id="modal-container"
|
id="modal-container"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-labelledby="modal-title"
|
|
||||||
aria-modal="true"
|
|
||||||
class="modal fade show"
|
class="modal fade show"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
>
|
>
|
||||||
|
@ -21,11 +19,11 @@ exports[`<RebootButton/> Render modal. 1`] = `
|
||||||
<div
|
<div
|
||||||
class="modal-header"
|
class="modal-header"
|
||||||
>
|
>
|
||||||
<h1
|
<h5
|
||||||
class="modal-title fs-5"
|
class="modal-title"
|
||||||
>
|
>
|
||||||
Warning!
|
Warning!
|
||||||
</h1>
|
</h5>
|
||||||
<button
|
<button
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
class="btn-close"
|
class="btn-close"
|
||||||
|
|
|
@ -7,7 +7,6 @@ exports[`AlertContext should render alert 1`] = `
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="alert alert-danger alert-dismissible"
|
class="alert alert-danger alert-dismissible"
|
||||||
role="alert"
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://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.
|
* This is free software, licensed under the GNU General Public License v3.
|
||||||
* See /LICENSE for more information.
|
* See /LICENSE for more information.
|
||||||
|
@ -9,10 +9,8 @@ export const REFORIS_URL_PREFIX = "/reforis";
|
||||||
export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
|
export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
|
||||||
|
|
||||||
export const ForisURLs = {
|
export const ForisURLs = {
|
||||||
// turris-auth
|
|
||||||
login: `/login?${REFORIS_URL_PREFIX}/`,
|
login: `/login?${REFORIS_URL_PREFIX}/`,
|
||||||
logout: `/logout`,
|
logout: `/logout`,
|
||||||
extendSession: `/extend-session`,
|
|
||||||
|
|
||||||
static: `${REFORIS_URL_PREFIX}/static/reforis`,
|
static: `${REFORIS_URL_PREFIX}/static/reforis`,
|
||||||
wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
|
wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
|
||||||
|
|
|
@ -40,40 +40,3 @@ 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]);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user