diff --git a/src/views/AccessControl.tsx b/src/views/AccessControl.tsx
index 9ff73c8..8efa7bf 100644
--- a/src/views/AccessControl.tsx
+++ b/src/views/AccessControl.tsx
@@ -21,6 +21,7 @@ import {
Tooltip,
Typography,
} from "antd";
+import { ReloadOutlined } from "@ant-design/icons";
import { Container } from "../components/Container";
import { useDispatch, useSelector } from "react-redux";
import { storeFilterState, getFilterState } from "../utils/filterState";
@@ -72,7 +73,7 @@ export const AccessControl = () => {
const { onChangePageSize, pageSizeOptions, pageSize } = usePageSizeHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
-
+
const policies = useSelector((state: RootState) => state.policy.data);
const failed = useSelector((state: RootState) => state.policy.failed);
const loading = useSelector((state: RootState) => state.policy.loading);
@@ -84,6 +85,7 @@ export const AccessControl = () => {
);
const [showTutorial, setShowTutorial] = useState(true);
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [textToSearch, setTextToSearch] = useState("");
const [optionAllEnable, setOptionAllEnable] = useState("all");
const [currentPage, setCurrentPage] = useState(1);
@@ -184,6 +186,26 @@ export const AccessControl = () => {
);
}, []);
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ policyActions.getPolicies.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
useEffect(() => {
if (failed) {
setShowTutorial(false);
@@ -298,7 +320,11 @@ export const AccessControl = () => {
setPolicyToAction(record as PolicyDataTable);
confirm({
icon: ,
- title: Delete rule {record.name},
+ title: (
+
+ Delete rule {record.name}
+
+ ),
width: 500,
content: (
@@ -420,7 +446,6 @@ export const AccessControl = () => {
);
};
-
const toggleModalGroups = (
title: string,
groups: Group[] | string[] | null,
@@ -643,6 +668,7 @@ export const AccessControl = () => {
disabled={showTutorial}
/>
+
+
+
+
{!showTutorial && (
{
const setupKeys = useSelector((state: RootState) => state.setupKey.data);
const [textToSearch, setTextToSearch] = useState("");
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [dataTable, setDataTable] = useState([] as EventDataTable[]);
const transformDataTable = (d: Event[]): EventDataTable[] => {
@@ -58,6 +60,21 @@ export const Activity = () => {
})
);
}, []);
+
+ const fetchData = async() => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ eventActions.getEvents.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
// useEffect(() => {
// setDataTable(transformDataTable(events));
// }, [events]);
@@ -427,6 +444,7 @@ export const Activity = () => {
+
+
+
+
{failed && (
diff --git a/src/views/Nameservers.tsx b/src/views/Nameservers.tsx
index 24d2014..6d5b6e7 100644
--- a/src/views/Nameservers.tsx
+++ b/src/views/Nameservers.tsx
@@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "typesafe-actions";
import { actions as nsGroupActions } from "../store/nameservers";
-import { Container } from "../components/Container";
import {
Alert,
Button,
@@ -21,8 +20,10 @@ import {
Table,
Tag,
Typography,
+ Tooltip,
} from "antd";
import { filter } from "lodash";
+import { ReloadOutlined } from "@ant-design/icons";
import tableSpin from "../components/Spin";
import { storeFilterState, getFilterState } from "../utils/filterState";
import { useGetTokenSilently } from "../utils/token";
@@ -77,6 +78,7 @@ export const Nameservers = () => {
);
const [textToSearch, setTextToSearch] = useState("");
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [optionAllEnable, setOptionAllEnable] = useState("all");
const [dataTable, setDataTable] = useState([] as NameserverGroupDataTable[]);
const [showTutorial, setShowTutorial] = useState(false);
@@ -192,6 +194,26 @@ export const Nameservers = () => {
);
}, []);
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ nsGroupActions.getNameServerGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
const onChangeAllEnabled = ({ target: { value } }: RadioChangeEvent) => {
setOptionAllEnable(value);
storeFilterState("nameServerFilter", "quickFilter", value);
@@ -554,6 +576,22 @@ export const Nameservers = () => {
className="select-rows-per-page-en"
disabled={showTutorial}
/>
+
+
+
+
diff --git a/src/views/Peers.tsx b/src/views/Peers.tsx
index 22782a6..7225929 100644
--- a/src/views/Peers.tsx
+++ b/src/views/Peers.tsx
@@ -94,6 +94,7 @@ export const Peers = () => {
const [groupPopupVisible, setGroupPopupVisible] = useState("");
const [showTutorial, setShowTutorial] = useState(false);
const [hadFirstRun, setHadFirstRun] = useState(true);
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [confirmModal, confirmModalContextHolder] = Modal.useModal();
const optionsOnOff = [
@@ -182,6 +183,33 @@ export const Peers = () => {
);
};
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ userActions.getUsers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ peerActions.getPeers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
useEffect(() => {
getLocalItem(StorageKey.hadFirstRun).then((f) =>
setHadFirstRun(f === null ? false : f)
@@ -694,7 +722,7 @@ export const Peers = () => {
{isAdmin && (
)}
-
+
diff --git a/src/views/RegularUsers.tsx b/src/views/RegularUsers.tsx
index 7620945..ff8a2db 100644
--- a/src/views/RegularUsers.tsx
+++ b/src/views/RegularUsers.tsx
@@ -41,7 +41,7 @@ import { usePageSizeHelpers } from "../utils/pageSize";
import AddServiceUserPopup from "../components/popups/AddServiceUserPopup";
import InviteUserPopup from "../components/popups/InviteUserPopup";
import { Peer, PeerDataTable } from "../store/peer/types";
-import { ExclamationCircleOutlined, MinusOutlined } from "@ant-design/icons";
+import { ExclamationCircleOutlined, ReloadOutlined } from "@ant-design/icons";
import { actions as peerActions } from "../store/peer";
import { useOidcUser } from "@axa-fr/react-oidc";
import { storeFilterState, getFilterState } from "../utils/filterState";
@@ -79,6 +79,7 @@ export const RegularUsers = () => {
null as UserDataTable | null
);
const [textToSearch, setTextToSearch] = useState("");
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [dataTable, setDataTable] = useState([] as UserDataTable[]);
const [confirmModal, confirmModalContextHolder] = Modal.useModal();
@@ -166,6 +167,31 @@ export const RegularUsers = () => {
);
}, [savedUser]);
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+ dispatch(
+ userActions.getUsers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ userActions.getRegularUsers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
useEffect(() => {
if (!loading && groups.length && users) {
const searchText = getFilterState("userFilter", "search");
@@ -396,7 +422,7 @@ export const RegularUsers = () => {
icon: ,
title: (
- Are you sure you want to block {user.name? user.name : user.id}?
+ Are you sure you want to block {user.name ? user.name : user.id}?
),
width: 600,
@@ -450,12 +476,18 @@ export const RegularUsers = () => {
const handleDeleteUser = (user: UserDataTable) => {
confirmModal.confirm({
icon: ,
- title: Are you sure you want to delete {user.name? user.name : user.id}?,
+ title: (
+
+ Are you sure you want to delete {user.name ? user.name : user.id}?
+
+ ),
width: 500,
content: (
- Deleting this user will remove their devices and remove dashboard access.
+ Deleting this user will remove their devices and remove dashboard
+ access.
+
),
onOk() {
@@ -510,6 +542,7 @@ export const RegularUsers = () => {
+
+
+
{(isNetBirdHosted() || isLocalDev()) && (
@@ -583,47 +631,87 @@ export const RegularUsers = () => {
if ((record as User).is_current) {
return (
- <>
-
- {btn}
- me
-
- {(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && Last login: {String(timeAgo((record as User).last_login))})}
- >
+ <>
+
+ {btn}
+ me
+
+ {(isNetBirdHosted() || isLocalDev()) &&
+ (record as User).last_login && (
+
+ Last login:{" "}
+ {String(timeAgo((record as User).last_login))}
+
+ )}
+ >
);
}
if ((record as User).status === "invited") {
return (
- <>
-
- {btn}
- invited
-
- {(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && Last login: {String(timeAgo((record as User).last_login))})}
- >
+ <>
+
+ {btn}
+ invited
+
+ {(isNetBirdHosted() || isLocalDev()) &&
+ (record as User).last_login && (
+
+ Last login:{" "}
+ {String(timeAgo((record as User).last_login))}
+
+ )}
+ >
);
}
if ((record as User).status === "blocked") {
return (
- <>
-
- {btn}
- blocked
-
- {(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && Last login: {String(timeAgo((record as User).last_login))})}
- >
+ <>
+
+ {btn}
+ blocked
+
+ {(isNetBirdHosted() || isLocalDev()) &&
+ (record as User).last_login && (
+
+ Last login:{" "}
+ {String(timeAgo((record as User).last_login))}
+
+ )}
+ >
);
}
return (
- <>
-
- {btn}
-
- {(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && Last login: {String(timeAgo((record as User).last_login))})}
- >
+ <>
+ {btn}
+ {(isNetBirdHosted() || isLocalDev()) &&
+ (record as User).last_login && (
+
+ Last login:{" "}
+ {String(timeAgo((record as User).last_login))}
+
+ )}
+ >
);
}}
/>
diff --git a/src/views/Routes.tsx b/src/views/Routes.tsx
index 39b64bf..138ef09 100644
--- a/src/views/Routes.tsx
+++ b/src/views/Routes.tsx
@@ -34,6 +34,7 @@ import {
EllipsisOutlined,
ExclamationCircleOutlined,
ExclamationCircleFilled,
+ ReloadOutlined,
} from "@ant-design/icons";
import { storeFilterState, getFilterState } from "../utils/filterState";
import RouteAddNew from "../components/RouteAddNew";
@@ -89,6 +90,7 @@ export const Routes = () => {
(state: RootState) => state.route.setupEditRouteVisible
);
const [showTutorial, setShowTutorial] = useState(true);
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [textToSearch, setTextToSearch] = useState("");
const [optionAllEnable, setOptionAllEnable] = useState("enabled");
const [dataTable, setDataTable] = useState([] as RouteDataTable[]);
@@ -184,8 +186,29 @@ export const Routes = () => {
payload: null,
})
);
+
}, []);
+ const fetchData = async() => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ peerActions.getPeers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
const filterGroupedDataTable = (
routes: GroupedDataTable[],
searchText: string
@@ -861,6 +884,7 @@ export const Routes = () => {
>
{
disabled={showTutorial}
/>
+
+
+
{!showTutorial && (
{
);
const savedUser = useSelector((state: RootState) => state.user.savedUser);
const deletedUser = useSelector((state: RootState) => state.user.deletedUser);
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const [showTutorial, setShowTutorial] = useState(false);
const [confirmModal, confirmModalContextHolder] = Modal.useModal();
@@ -78,18 +81,42 @@ export const ServiceUsers = () => {
);
}, [savedUser, deletedUser]);
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+ dispatch(
+ userActions.getUsers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ userActions.getServiceUsers.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
// useEffect(() => {
// setDataTable(transformDataTable(users));
// }, [users, groups]);
- useEffect(() => {
- if (users.length > 0) {
- setShowTutorial(false);
- } else {
- setShowTutorial(true);
- }
- // setDataTable(transformDataTable(filterDataTable()));
- }, [users]);
+ useEffect(() => {
+ if (users.length > 0) {
+ setShowTutorial(false);
+ } else {
+ setShowTutorial(true);
+ }
+ // setDataTable(transformDataTable(filterDataTable()));
+ }, [users]);
useEffect(() => {
if (!loading && groups.length) {
@@ -227,8 +254,6 @@ export const ServiceUsers = () => {
});
};
-
-
return (
<>
{!user && (
@@ -289,6 +314,7 @@ export const ServiceUsers = () => {
>
+
+
+
{!showTutorial && (
diff --git a/src/views/SetupKeys.tsx b/src/views/SetupKeys.tsx
index 259ebd5..4452314 100644
--- a/src/views/SetupKeys.tsx
+++ b/src/views/SetupKeys.tsx
@@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux";
import { RootState } from "typesafe-actions";
import { actions as setupKeyActions } from "../store/setup-key";
import { Container } from "../components/Container";
+import { ReloadOutlined } from "@ant-design/icons";
import {
Alert,
Button,
@@ -51,6 +52,7 @@ export const SetupKeys = () => {
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
const [showGroupModal, setShowGroupModal] = useState(false);
+ const [isRefreshButtonDisabled, setIsRefreshButtonDisabled] = useState(false);
const setupKeys = useSelector((state: RootState) => state.setupKey.data);
const failed = useSelector((state: RootState) => state.setupKey.failed);
@@ -109,6 +111,26 @@ export const SetupKeys = () => {
);
}, []);
+ const fetchData = async () => {
+ setIsRefreshButtonDisabled(true);
+
+ dispatch(
+ setupKeyActions.getSetupKeys.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ dispatch(
+ groupActions.getGroups.request({
+ getAccessTokenSilently: getTokenSilently,
+ payload: null,
+ })
+ );
+ await new Promise((resolve) => setTimeout(resolve, 5000)).then(() =>
+ setIsRefreshButtonDisabled(false)
+ );
+ };
+
useEffect(() => {
setDataTable(transformDataTable(filterDataTable("")));
}, [textToSearch, optionValidAll]);
@@ -475,6 +497,7 @@ export const SetupKeys = () => {
disabled={!dataTable?.length}
/>