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} /> { @@ -435,6 +453,22 @@ export const Activity = () => { className="select-rows-per-page-en" /> + + + + {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 = () => { { @@ -298,6 +324,21 @@ export const ServiceUsers = () => { disabled={showTutorial} /> + + + {!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} />