mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-01-26 01:21:04 +00:00
Add a refresh button to the table views (#287)
Co-authored-by: braginini <bangvalo@gmail.com>
This commit is contained in:
@@ -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: <ExclamationCircleOutlined />,
|
||||
title: <span data-testid="confirm-delete-modal-title" className="font-500">Delete rule {record.name}</span>,
|
||||
title: (
|
||||
<span data-testid="confirm-delete-modal-title" className="font-500">
|
||||
Delete rule {record.name}
|
||||
</span>
|
||||
),
|
||||
width: 500,
|
||||
content: (
|
||||
<Space direction="vertical" size="small">
|
||||
@@ -420,7 +446,6 @@ export const AccessControl = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const toggleModalGroups = (
|
||||
title: string,
|
||||
groups: Group[] | string[] | null,
|
||||
@@ -643,6 +668,7 @@ export const AccessControl = () => {
|
||||
disabled={showTutorial}
|
||||
/>
|
||||
<Select
|
||||
style={{ marginRight: "10px" }}
|
||||
value={pageSize.toString()}
|
||||
options={pageSizeOptions}
|
||||
onChange={(value) => {
|
||||
@@ -652,6 +678,22 @@ export const AccessControl = () => {
|
||||
disabled={showTutorial}
|
||||
/>
|
||||
</Space>
|
||||
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{!showTutorial && (
|
||||
<Col
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Space,
|
||||
Table,
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from "antd";
|
||||
import { Event } from "../store/event/types";
|
||||
import { filter } from "lodash";
|
||||
@@ -23,7 +24,7 @@ import { useOidcUser } from "@axa-fr/react-oidc";
|
||||
import { capitalize, formatDateTime } from "../utils/common";
|
||||
import { User } from "../store/user/types";
|
||||
import { usePageSizeHelpers } from "../utils/pageSize";
|
||||
import { QuestionCircleFilled } from "@ant-design/icons";
|
||||
import { ReloadOutlined } from "@ant-design/icons";
|
||||
import { storeFilterState, getFilterState } from "../utils/filterState";
|
||||
|
||||
const { Title, Paragraph, Text } = Typography;
|
||||
@@ -44,6 +45,7 @@ export const Activity = () => {
|
||||
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 = () => {
|
||||
<Col xs={24} sm={24} md={11} lg={11} xl={11} xxl={11} span={11}>
|
||||
<Space size="middle">
|
||||
<Select
|
||||
style={{ marginRight: "10px" }}
|
||||
value={pageSize.toString()}
|
||||
options={pageSizeOptions}
|
||||
onChange={(value) => {
|
||||
@@ -435,6 +453,22 @@ export const Activity = () => {
|
||||
className="select-rows-per-page-en"
|
||||
/>
|
||||
</Space>
|
||||
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
</Row>
|
||||
{failed && (
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
</Col>
|
||||
<Col xs={24} sm={24} md={5} lg={5} xl={5} xxl={5} span={5}>
|
||||
|
||||
@@ -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<boolean>(StorageKey.hadFirstRun).then((f) =>
|
||||
setHadFirstRun(f === null ? false : f)
|
||||
@@ -694,7 +722,7 @@ export const Peers = () => {
|
||||
{isAdmin && (
|
||||
<Select
|
||||
mode="tags"
|
||||
style={{ marginRight: "15px" }}
|
||||
style={{ marginRight: "10px" }}
|
||||
placeholder="Filter by groups"
|
||||
tagRender={blueTagRender}
|
||||
// dropdownRender={dropDownRender}
|
||||
@@ -715,10 +743,17 @@ export const Peers = () => {
|
||||
</Select>
|
||||
)}
|
||||
|
||||
<Tooltip title="Refersh">
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={refresh}
|
||||
style={{color: "#1890ff" }}
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
|
||||
@@ -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: <ExclamationCircleOutlined />,
|
||||
title: (
|
||||
<span className="font-500">
|
||||
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}?
|
||||
</span>
|
||||
),
|
||||
width: 600,
|
||||
@@ -450,12 +476,18 @@ export const RegularUsers = () => {
|
||||
const handleDeleteUser = (user: UserDataTable) => {
|
||||
confirmModal.confirm({
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
title: <span className="font-500">Are you sure you want to delete {user.name? user.name : user.id}?</span>,
|
||||
title: (
|
||||
<span className="font-500">
|
||||
Are you sure you want to delete {user.name ? user.name : user.id}?
|
||||
</span>
|
||||
),
|
||||
width: 500,
|
||||
content: (
|
||||
<Space direction="vertical" size="small">
|
||||
<Paragraph>
|
||||
Deleting this user will remove their devices and remove dashboard access.</Paragraph>
|
||||
Deleting this user will remove their devices and remove dashboard
|
||||
access.
|
||||
</Paragraph>
|
||||
</Space>
|
||||
),
|
||||
onOk() {
|
||||
@@ -510,6 +542,7 @@ export const RegularUsers = () => {
|
||||
<Col xs={24} sm={24} md={11} lg={11} xl={11} xxl={11} span={11}>
|
||||
<Space size="middle">
|
||||
<Select
|
||||
style={{ marginRight: "10px" }}
|
||||
value={pageSize.toString()}
|
||||
options={pageSizeOptions}
|
||||
onChange={(value) => {
|
||||
@@ -518,6 +551,21 @@ export const RegularUsers = () => {
|
||||
className="select-rows-per-page-en"
|
||||
/>
|
||||
</Space>
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
<Col xs={24} sm={24} md={5} lg={5} xl={5} xxl={5} span={5}>
|
||||
{(isNetBirdHosted() || isLocalDev()) && (
|
||||
@@ -583,47 +631,87 @@ export const RegularUsers = () => {
|
||||
|
||||
if ((record as User).is_current) {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="blue">me</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && <Text type={"secondary"} style={{paddingLeft: "15px"}}>Last login: {String(timeAgo((record as User).last_login))}</Text>)}
|
||||
</>
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="blue">me</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) &&
|
||||
(record as User).last_login && (
|
||||
<Text
|
||||
type={"secondary"}
|
||||
style={{ paddingLeft: "15px" }}
|
||||
>
|
||||
Last login:{" "}
|
||||
{String(timeAgo((record as User).last_login))}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if ((record as User).status === "invited") {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="gold">invited</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && <Text type={"secondary"} style={{paddingLeft: "15px", paddingTop: "0px"}}>Last login: {String(timeAgo((record as User).last_login))}</Text>)}
|
||||
</>
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="gold">invited</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) &&
|
||||
(record as User).last_login && (
|
||||
<Text
|
||||
type={"secondary"}
|
||||
style={{
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "0px",
|
||||
}}
|
||||
>
|
||||
Last login:{" "}
|
||||
{String(timeAgo((record as User).last_login))}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if ((record as User).status === "blocked") {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="red">blocked</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && <Text type={"secondary"} style={{paddingLeft: "15px"}}>Last login: {String(timeAgo((record as User).last_login))}</Text>)}
|
||||
</>
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
<Tag color="red">blocked</Tag>
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) &&
|
||||
(record as User).last_login && (
|
||||
<Text
|
||||
type={"secondary"}
|
||||
style={{ paddingLeft: "15px" }}
|
||||
>
|
||||
Last login:{" "}
|
||||
{String(timeAgo((record as User).last_login))}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{btn}
|
||||
</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) && ((record as User).last_login && <Text type={"secondary"} style={{paddingLeft: "15px", paddingTop: "0px"}}>Last login: {String(timeAgo((record as User).last_login))}</Text>)}
|
||||
</>
|
||||
<>
|
||||
<div>{btn}</div>
|
||||
{(isNetBirdHosted() || isLocalDev()) &&
|
||||
(record as User).last_login && (
|
||||
<Text
|
||||
type={"secondary"}
|
||||
style={{
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "0px",
|
||||
}}
|
||||
>
|
||||
Last login:{" "}
|
||||
{String(timeAgo((record as User).last_login))}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -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 = () => {
|
||||
>
|
||||
<Space size="middle">
|
||||
<Radio.Group
|
||||
style={{ marginRight: "10px" }}
|
||||
options={optionsAllEnabled}
|
||||
onChange={onChangeAllEnabled}
|
||||
value={optionAllEnable}
|
||||
@@ -869,6 +893,21 @@ export const Routes = () => {
|
||||
disabled={showTutorial}
|
||||
/>
|
||||
</Space>
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{!showTutorial && (
|
||||
<Col
|
||||
|
||||
@@ -17,11 +17,13 @@ import {
|
||||
Table,
|
||||
Tag,
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from "antd";
|
||||
import { User } from "../store/user/types";
|
||||
import { filter } from "lodash";
|
||||
import tableSpin from "../components/Spin";
|
||||
import { useGetTokenSilently } from "../utils/token";
|
||||
import { ReloadOutlined } from "@ant-design/icons";
|
||||
import { actions as groupActions } from "../store/group";
|
||||
import { capitalize, isLocalDev, isNetBirdHosted } from "../utils/common";
|
||||
import { usePageSizeHelpers } from "../utils/pageSize";
|
||||
@@ -53,6 +55,7 @@ export const ServiceUsers = () => {
|
||||
);
|
||||
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 = () => {
|
||||
>
|
||||
<Space size="middle">
|
||||
<Select
|
||||
style={{ marginRight: "10px" }}
|
||||
value={pageSize.toString()}
|
||||
options={pageSizeOptions}
|
||||
onChange={(value) => {
|
||||
@@ -298,6 +324,21 @@ export const ServiceUsers = () => {
|
||||
disabled={showTutorial}
|
||||
/>
|
||||
</Space>
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{!showTutorial && (
|
||||
<Col xs={24} sm={24} md={5} lg={5} xl={5} xxl={5} span={5}>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
<Select
|
||||
style={{ marginRight: "10px" }}
|
||||
disabled={!dataTable?.length}
|
||||
value={pageSize.toString()}
|
||||
options={pageSizeOptions}
|
||||
@@ -484,6 +507,22 @@ export const SetupKeys = () => {
|
||||
className="select-rows-per-page-en"
|
||||
/>
|
||||
</Space>
|
||||
|
||||
<Tooltip
|
||||
title={
|
||||
isRefreshButtonDisabled
|
||||
? "You can refresh it again in 5 seconds"
|
||||
: "Refresh"
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={fetchData}
|
||||
disabled={isRefreshButtonDisabled}
|
||||
style={{ marginLeft: "5px", color: "#1890ff" }}
|
||||
>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{dataTable.length ? (
|
||||
<Col xs={24} sm={24} md={5} lg={5} xl={5} xxl={5} span={5}>
|
||||
|
||||
Reference in New Issue
Block a user