diff --git a/src/components/PeerUpdate.tsx b/src/components/PeerUpdate.tsx index df6eca6..59b4791 100644 --- a/src/components/PeerUpdate.tsx +++ b/src/components/PeerUpdate.tsx @@ -20,8 +20,10 @@ import { Switch, Breadcrumb, Table, + Badge, SelectProps, Modal, + Tooltip, } from "antd"; import { Container } from "./Container"; import { Header } from "antd/es/layout/layout"; @@ -78,7 +80,7 @@ const PeerUpdate = () => { const [peerGroups, setPeerGroups] = useState([] as GroupPeer[]); const inputNameRef = useRef(null); const [editName, setEditName] = useState(false); - const options: SelectProps["options"] = []; + const options: SelectProps["options"] = []; const [estimatedName, setEstimatedName] = useState(""); const [callingPeerAPI, setCallingPeerAPI] = useState(false); const [callingGroupAPI, setCallingGroupAPI] = useState(false); @@ -150,7 +152,7 @@ const PeerUpdate = () => { (route) => route.peer !== peer.id ); setNotPeerRoutes(filterNotPeerRoutes); - }, [routes]); + }, [routes]); useEffect(() => { if (!peer) return; @@ -594,7 +596,10 @@ const PeerUpdate = () => { fontWeight: "400", }} > - {formPeer.userEmail}{" "} +
+ {" "} + {formPeer.userEmail}{" "} +
) : ( @@ -653,9 +658,26 @@ const PeerUpdate = () => { > NetBird IP - - {formPeer.connected ? "online" : "offline"} - + + {formPeer.connected ? ( + + ) : ( + + )} } > diff --git a/src/index.css b/src/index.css index 4ccc794..62e3129 100644 --- a/src/index.css +++ b/src/index.css @@ -1,11 +1,11 @@ -@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;500&display=swap'); @import 'antd/dist/reset.css'; html, body, * { - font-family: 'Roboto', sans-serif !important; + font-family: 'Arimo', sans-serif !important; } body { @@ -267,3 +267,8 @@ td.non-highlighted-table-column { .react-select__indicator { padding: 0 5px !important; } + +.ant-badge-status-dot { + width: 8px!important; + height: 8px!important; +} \ No newline at end of file diff --git a/src/views/AccessControl.tsx b/src/views/AccessControl.tsx index d8c3f21..5379277 100644 --- a/src/views/AccessControl.tsx +++ b/src/views/AccessControl.tsx @@ -541,7 +541,6 @@ export const AccessControl = () => { }) ); }; - return ( <> {!setupEditPolicyVisible && ( @@ -550,10 +549,18 @@ export const AccessControl = () => { Access Control - - Access rules help you manage access permissions in your - organisation. - + {policies.length ? ( + + Access rules help you manage access permissions in your + organisation. + + ) : ( + + Access rules help you manage access permissions in your + organisation. + + )} + { - const {onChangePageSize,pageSizeOptions,pageSize} = usePageSizeHelpers() - const {getTokenSilently} = useGetTokenSilently() - const dispatch = useDispatch() + const { onChangePageSize, pageSizeOptions, pageSize } = usePageSizeHelpers(); + const { getTokenSilently } = useGetTokenSilently(); + const dispatch = useDispatch(); - const { - getGroupNamesFromIDs, - } = useGetGroupTagHelpers() + const { getGroupNamesFromIDs } = useGetGroupTagHelpers(); - const groups = useSelector((state: RootState) => state.group.data) - const nsGroup = useSelector((state: RootState) => state.nameserverGroup.data); - const failed = useSelector((state: RootState) => state.nameserverGroup.failed); - const loading = useSelector((state: RootState) => state.nameserverGroup.loading); - const updateNameServerGroupVisible = useSelector((state: RootState) => state.nameserverGroup.setupNewNameServerGroupVisible) - const savedNSGroup = useSelector((state: RootState) => state.nameserverGroup.savedNameServerGroup) + const groups = useSelector((state: RootState) => state.group.data); + const nsGroup = useSelector((state: RootState) => state.nameserverGroup.data); + const failed = useSelector( + (state: RootState) => state.nameserverGroup.failed + ); + const loading = useSelector( + (state: RootState) => state.nameserverGroup.loading + ); + const updateNameServerGroupVisible = useSelector( + (state: RootState) => state.nameserverGroup.setupNewNameServerGroupVisible + ); + const savedNSGroup = useSelector( + (state: RootState) => state.nameserverGroup.savedNameServerGroup + ); - const [groupPopupVisible, setGroupPopupVisible] = useState("") - const [nsGroupToAction, setNsGroupToAction] = useState(null as NameserverGroupDataTable | null); - const [textToSearch, setTextToSearch] = useState(''); - const [optionAllEnable, setOptionAllEnable] = useState('enabled'); - const [dataTable, setDataTable] = useState([] as NameserverGroupDataTable[]); - const [showTutorial, setShowTutorial] = useState(false) + const [groupPopupVisible, setGroupPopupVisible] = useState(""); + const [nsGroupToAction, setNsGroupToAction] = useState( + null as NameserverGroupDataTable | null + ); + const [textToSearch, setTextToSearch] = useState(""); + const [optionAllEnable, setOptionAllEnable] = useState("enabled"); + const [dataTable, setDataTable] = useState([] as NameserverGroupDataTable[]); + const [showTutorial, setShowTutorial] = useState(false); + const optionsAllEnabled = [ + { label: "Enabled", value: "enabled" }, + { label: "All", value: "all" }, + ]; - const optionsAllEnabled = [{label: 'Enabled', value: 'enabled'}, {label: 'All', value: 'all'}] + // setUserAndView makes the UserUpdate drawer visible (right side) and sets the user object + const setUserAndView = (nsGroup: NameServerGroup) => { + dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(true)); + dispatch( + nsGroupActions.setNameServerGroup({ + id: nsGroup.id, + name: nsGroup.name, + primary: nsGroup.primary, + domains: nsGroup.domains, + description: nsGroup.description, + nameservers: nsGroup.nameservers, + groups: nsGroup.groups, + enabled: nsGroup.enabled, + } as NameServerGroup) + ); + }; - // setUserAndView makes the UserUpdate drawer visible (right side) and sets the user object - const setUserAndView = (nsGroup: NameServerGroup) => { - dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(true)); - dispatch(nsGroupActions.setNameServerGroup({ - id: nsGroup.id, - name: nsGroup.name, - primary: nsGroup.primary, - domains: nsGroup.domains, - description: nsGroup.description, - nameservers: nsGroup.nameservers, - groups: nsGroup.groups, - enabled: nsGroup.enabled, - } as NameServerGroup)); + const transformDataTable = ( + d: NameServerGroup[] + ): NameserverGroupDataTable[] => { + return d.map((p) => ({ key: p.id, ...p } as NameserverGroupDataTable)); + }; + + useEffect(() => { + dispatch( + nsGroupActions.getNameServerGroups.request({ + getAccessTokenSilently: getTokenSilently, + payload: null, + }) + ); + dispatch( + groupActions.getGroups.request({ + getAccessTokenSilently: getTokenSilently, + payload: null, + }) + ); + }, []); + + useEffect(() => { + if (nsGroup.length > 0) { + setShowTutorial(false); + } else { + setShowTutorial(true); } + setDataTable(transformDataTable(filterDataTable())); + }, [nsGroup]); - const transformDataTable = (d: NameServerGroup[]): NameserverGroupDataTable[] => { - return d.map(p => ({key: p.id, ...p} as NameserverGroupDataTable)) + useEffect(() => { + setDataTable(transformDataTable(filterDataTable())); + }, [textToSearch, optionAllEnable]); + + const filterDataTable = (): NameServerGroup[] => { + const t = textToSearch.toLowerCase().trim(); + let f = filter( + nsGroup, + (f: NameServerGroup) => + f.name.toLowerCase().includes(t) || + f.name.includes(t) || + t === "" || + getGroupNamesFromIDs(f.groups).find((u) => + u.toLowerCase().trim().includes(t) + ) || + f.domains.find((d) => d.toLowerCase().trim().includes(t)) || + f.nameservers.find((n) => n.ip.includes(t)) + ) as NameServerGroup[]; + if (optionAllEnable !== "all") { + f = filter(f, (f) => f.enabled); } + return f; + }; - useEffect(() => { - dispatch(nsGroupActions.getNameServerGroups.request({ + const onChangeAllEnabled = ({ target: { value } }: RadioChangeEvent) => { + setOptionAllEnable(value); + }; + + const onChangeTextToSearch = ( + e: React.ChangeEvent + ) => { + setTextToSearch(e.target.value); + }; + + const searchDataTable = () => { + setDataTable(transformDataTable(filterDataTable())); + }; + + const onClickEdit = () => { + dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(true)); + dispatch( + nsGroupActions.setNameServerGroup({ + id: nsGroupToAction?.id, + name: nsGroupToAction?.name, + primary: nsGroupToAction?.primary, + domains: nsGroupToAction?.domains, + description: nsGroupToAction?.description, + groups: nsGroupToAction?.groups, + enabled: nsGroupToAction?.enabled, + nameservers: nsGroupToAction?.nameservers, + } as NameServerGroup) + ); + }; + + const showConfirmDelete = () => { + let name = nsGroupToAction ? nsGroupToAction.name : ""; + confirm({ + icon: , + title: 'Delete Nameserver group "' + name + '"', + width: 600, + content: ( + + + Are you sure you want to delete this nameserver group from your + account? + + + ), + okType: "danger", + onOk() { + dispatch( + nsGroupActions.deleteNameServerGroup.request({ getAccessTokenSilently: getTokenSilently, - payload: null - })); - dispatch(groupActions.getGroups.request({getAccessTokenSilently: getTokenSilently, payload: null})); - }, []) + payload: nsGroupToAction?.id || "", + }) + ); + }, + onCancel() { + setNsGroupToAction(null); + }, + }); + }; - useEffect(() => { - if (nsGroup.length > 0) { - setShowTutorial(false) - } else { - setShowTutorial(true) - } - setDataTable(transformDataTable(filterDataTable())) - }, [nsGroup]) + const renderPopoverGroups = ( + label: string, + rowGroups: string[] | null, + userToAction: NameserverGroupDataTable + ) => { + let groupsMap = new Map(); + groups.forEach((g) => { + groupsMap.set(g.id!, g); + }); - useEffect(() => { - setDataTable(transformDataTable(filterDataTable())) - }, [textToSearch, optionAllEnable]) - - const filterDataTable = (): NameServerGroup[] => { - const t = textToSearch.toLowerCase().trim() - let f = filter(nsGroup, (f: NameServerGroup) => - ((f.name).toLowerCase().includes(t) || - f.name.includes(t) || t === "" || - getGroupNamesFromIDs(f.groups).find(u => u.toLowerCase().trim().includes(t)) || - f.domains.find(d => d.toLowerCase().trim().includes(t)) || - f.nameservers.find(n => n.ip.includes(t))) - ) as NameServerGroup[] - if (optionAllEnable !== "all") { - f = filter(f, (f) => f.enabled) - } - return f + let displayGroups: Group[] = []; + if (rowGroups) { + displayGroups = rowGroups + .filter((g) => groupsMap.get(g)) + .map((g) => groupsMap.get(g)!); } - const onChangeAllEnabled = ({target: {value}}: RadioChangeEvent) => { - setOptionAllEnable(value) + let btn = ( + + ); + if (!displayGroups || displayGroups!.length < 1) { + return btn; } - const onChangeTextToSearch = (e: React.ChangeEvent) => { - setTextToSearch(e.target.value) - }; - - const searchDataTable = () => { - setDataTable(transformDataTable(filterDataTable())) - } - - const onClickEdit = () => { - dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(true)); - dispatch(nsGroupActions.setNameServerGroup({ - id: nsGroupToAction?.id, - name: nsGroupToAction?.name, - primary: nsGroupToAction?.primary, - domains: nsGroupToAction?.domains, - description: nsGroupToAction?.description, - groups: nsGroupToAction?.groups, - enabled: nsGroupToAction?.enabled, - nameservers: nsGroupToAction?.nameservers, - } as NameServerGroup)); - } - - const showConfirmDelete = () => { - let name = nsGroupToAction ? nsGroupToAction.name : ''; - confirm({ - icon: , - title: "Delete Nameserver group \"" + name + "\"", - width: 600, - content: - Are you sure you want to delete this nameserver group from your account? - , - okType: 'danger', - onOk() { - dispatch(nsGroupActions.deleteNameServerGroup.request({ - getAccessTokenSilently: getTokenSilently, - payload: nsGroupToAction?.id || '' - })); - }, - onCancel() { - setNsGroupToAction(null); - }, - }); - } - - const renderPopoverGroups = (label: string, rowGroups: string[] | null, userToAction: NameserverGroupDataTable) => { - - let groupsMap = new Map(); - groups.forEach(g => { - groupsMap.set(g.id!, g) - }) - - let displayGroups: Group[] = [] - if (rowGroups) { - displayGroups = rowGroups.filter(g => groupsMap.get(g)).map(g => groupsMap.get(g)!) - } - - let btn = - if (!displayGroups || displayGroups!.length < 1) { - return btn - } - - const content = displayGroups?.map((g, i) => { - const _g = g as Group - const peersCount = ` - ${_g.peers_count || 0} ${(!_g.peers_count || parseInt(_g.peers_count) !== 1) ? 'peers' : 'peer'} ` - return ( -
- - {_g.name} - - {peersCount} -
- ) - }) - const mainContent = ({content}) - let popoverPlacement = "top" - if (content && content.length > 5) { - popoverPlacement = "rightTop" - } - - return ( - onPopoverVisibleChange(b, userToAction.key+"group")} - open={groupPopupVisible === userToAction.key+"group"} - content={mainContent} - title={null}> - {btn} - - ) - } - - const renderPopoverDomains = (_: string, inputDomains: string[] | null, userToAction: NameserverGroupDataTable) => { - var domains = [] as string[] - if (inputDomains?.length) { - domains = inputDomains - } - - let btn = - if (!domains || domains!.length < 1) { - return btn - } - - const content = domains?.map((d, i) => { - return ( -
- - {d} - -
- ) - }) - - const mainContent = ({content}) - let popoverPlacement = "top" - if (content && content.length > 5) { - popoverPlacement = "rightTop" - } - - return ( - onPopoverVisibleChange(b, userToAction.key+"domain")} - open={groupPopupVisible === userToAction.key+"domain"} - content={mainContent} - title={null}> - {btn} - - ) - } - - useEffect(() => { - if (updateNameServerGroupVisible) { - setGroupPopupVisible("") - } - }, [updateNameServerGroupVisible]) - - const createKey = 'saving'; - useEffect(() => { - if (savedNSGroup.loading) { - message.loading({content: 'Saving...', key: createKey, duration: 0, style: styleNotification}); - } else if (savedNSGroup.success) { - message.success({ - content: 'Nameserver has been successfully saved.', - key: createKey, - duration: 2, - style: styleNotification - }); - dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(false)); - dispatch(nsGroupActions.setSavedNameServerGroup({...savedNSGroup, success: false})); - dispatch(nsGroupActions.resetSavedNameServerGroup(null)) - } else if (savedNSGroup.error) { - let errorMsg = "Failed to update nameserver group" - switch (savedNSGroup.error.statusCode) { - case 403: - errorMsg = "Failed to update nameserver group. You might not have enough permissions." - break - default: - errorMsg = savedNSGroup.error.data.message ? savedNSGroup.error.data.message : errorMsg - break - } - message.error({ - content: errorMsg, - key: createKey, - duration: 5, - style: styleNotification - }); - dispatch(nsGroupActions.setSavedNameServerGroup({...savedNSGroup, error: null})); - dispatch(nsGroupActions.resetSavedNameServerGroup(null)) - } - }, [savedNSGroup]) - - const onPopoverVisibleChange = (b:boolean, key: string) => { - if (updateNameServerGroupVisible) { - setGroupPopupVisible("") - } else { - if (b) { - setGroupPopupVisible(key) - } else { - setGroupPopupVisible("") - } - } - } - - const itemsMenuAction = [ - { - key: "edit", - label: () - }, - { - key: "delete", - label: () - }, - ] - - const actionsMenu = () - - const onClickAddNewNSGroup = () => { - dispatch(nsGroupActions.setSetupNewNameServerGroupVisible(true)); - dispatch(nsGroupActions.setNameServerGroup({ - enabled: true, - primary: true, - } as NameServerGroup)) + const content = displayGroups?.map((g, i) => { + const _g = g as Group; + const peersCount = ` - ${_g.peers_count || 0} ${ + !_g.peers_count || parseInt(_g.peers_count) !== 1 ? "peers" : "peer" + } `; + return ( +
+ + {_g.name} + + {peersCount} +
+ ); + }); + const mainContent = {content}; + let popoverPlacement = "top"; + if (content && content.length > 5) { + popoverPlacement = "rightTop"; } return ( - <> - Add nameservers for domain name resolution in your NetBird network - - - - - - - - - + + + + +