diff --git a/src/components/AccessControlEdit.tsx b/src/components/AccessControlEdit.tsx index 4838c88..d88e7a2 100644 --- a/src/components/AccessControlEdit.tsx +++ b/src/components/AccessControlEdit.tsx @@ -1,21 +1,21 @@ -import React, { useEffect, useRef, useState } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "typesafe-actions"; -import { actions as policyActions } from "../store/policy"; +import React, {useEffect, useRef, useState} from "react"; +import {useDispatch, useSelector} from "react-redux"; +import {RootState} from "typesafe-actions"; +import {actions as policyActions} from "../store/policy"; import { - Button, - Col, - Divider, - Form, - Input, - Card, - Row, - Select, - SelectProps, - Switch, - Tag, - Typography, - Breadcrumb, + Button, + Col, + Divider, + Form, + Input, + Card, + Row, + Select, + SelectProps, + Switch, + Tag, + Typography, + Breadcrumb, } from "antd"; import inbound from "../assets/in_bound.svg"; import outBoundGreen from "../assets/out_bound_green.svg"; @@ -23,918 +23,868 @@ import outBoundblue from "../assets/out_bound_blue.svg"; import reverseDefault from "../assets/reverse_default.svg"; import forwardDefault from "../assets/forward_default.svg"; import reverseGreen from "../assets/reverse_green.svg"; -import type { CustomTagProps } from "rc-select/lib/BaseSelect"; -import { Policy, PolicyToSave } from "../store/policy/types"; -import { uniq } from "lodash"; -import { Header } from "antd/es/layout/layout"; -import { RuleObject } from "antd/lib/form"; -import { useGetTokenSilently } from "../utils/token"; -import { Container } from "./Container"; +import type {CustomTagProps} from "rc-select/lib/BaseSelect"; +import {Policy, PolicyToSave} from "../store/policy/types"; +import {uniq} from "lodash"; +import {Header} from "antd/es/layout/layout"; +import {RuleObject} from "antd/lib/form"; +import {useGetTokenSilently} from "../utils/token"; +import {Container} from "./Container"; +import {useGetGroupTagHelpers} from "../utils/groups"; -const { Paragraph } = Typography; -const { Option } = Select; -const { Text } = Typography; +const {Paragraph} = Typography; +const {Option} = Select; +const {Text} = Typography; interface FormPolicy { - id?: string; - name: string; - description: string; - enabled: boolean; - query: string; - bidirectional: boolean; - protocol: string; - ports: string[]; - action: string; - tagSourceGroups: string[]; - tagDestinationGroups: string[]; + id?: string; + name: string; + description: string; + enabled: boolean; + query: string; + bidirectional: boolean; + protocol: string; + ports: string[]; + action: string; + tagSourceGroups: string[]; + tagDestinationGroups: string[]; } const AccessControlEdit = () => { - const { getTokenSilently } = useGetTokenSilently(); - const dispatch = useDispatch(); - const setupEditPolicyVisible = useSelector( - (state: RootState) => state.policy.setupEditPolicyVisible - ); - const groups = useSelector((state: RootState) => state.group.data); - const actions: SelectProps["options"] = [ - { label: "Accept", value: "accept" }, - { label: "Drop", value: "drop" }, - ]; - const protocols: SelectProps["options"] = [ - { label: "All", value: "all" }, - { label: "TCP", value: "tcp" }, - { label: "UDP", value: "udp" }, - { label: "ICMP", value: "icmp" }, - ]; - const policy = useSelector((state: RootState) => state.policy.policy); - const savedPolicy = useSelector( - (state: RootState) => state.policy.savedPolicy - ); - const [editName, setEditName] = useState(false); - const [editDescription, setEditDescription] = useState(false); - const [direction, setDirection] = useState({ - biDirectional: false, - reverseDirectional: false, - }); - const [tagGroups, setTagGroups] = useState([] as string[]); - const [formPolicy, setFormPolicy] = useState({} as FormPolicy); - const [form] = Form.useForm(); - const inputNameRef = useRef(null); - const inputDescriptionRef = useRef(null); - useEffect(() => { - //Unmounting component clean - return () => { - onCancel(); - }; - }, []); + const { + optionRender, + blueTagRender, + grayTagRender + } = useGetGroupTagHelpers() - useEffect(() => { - if (editName) inputNameRef.current!.focus({ cursor: "end" }); - }, [editName]); - useEffect(() => { - if (editDescription) inputDescriptionRef.current!.focus({ cursor: "end" }); - }, [editDescription]); - useEffect(() => { - setTagGroups(groups?.map((g) => g.name) || []); - }, [groups]); - useEffect(() => { - if (!policy) return; - const fPolicy = { - id: policy.id, - name: policy.name, - description: policy.description, - enabled: policy.enabled, - query: "", - bidirectional: policy.rules[0].bidirectional, - protocol: policy.rules[0].protocol, - ports: policy.rules[0].ports, - action: policy.rules[0].action, - tagSourceGroups: policy.rules[0].sources - ? policy.rules[0].sources?.map((t) => t.name) - : [], - tagDestinationGroups: policy.rules[0].destinations - ? policy.rules[0].destinations?.map((t) => t.name) - : [], - } as FormPolicy; - setFormPolicy(fPolicy); - form.setFieldsValue(fPolicy); - if (fPolicy.bidirectional) { - setDirection({ - biDirectional: true, - reverseDirectional: true, - }); - } else { - setDirection({ + const {getTokenSilently} = useGetTokenSilently(); + const dispatch = useDispatch(); + const setupEditPolicyVisible = useSelector( + (state: RootState) => state.policy.setupEditPolicyVisible + ); + const groups = useSelector((state: RootState) => state.group.data); + const actions: SelectProps["options"] = [ + {label: "Accept", value: "accept"}, + {label: "Drop", value: "drop"}, + ]; + const protocols: SelectProps["options"] = [ + {label: "All", value: "all"}, + {label: "TCP", value: "tcp"}, + {label: "UDP", value: "udp"}, + {label: "ICMP", value: "icmp"}, + ]; + const policy = useSelector((state: RootState) => state.policy.policy); + const savedPolicy = useSelector( + (state: RootState) => state.policy.savedPolicy + ); + const [editName, setEditName] = useState(false); + const [editDescription, setEditDescription] = useState(false); + const [direction, setDirection] = useState({ biDirectional: false, reverseDirectional: false, - }); - } - }, [policy, form]); + }); + const [tagGroups, setTagGroups] = useState([] as string[]); + const [formPolicy, setFormPolicy] = useState({} as FormPolicy); + const [form] = Form.useForm(); + const inputNameRef = useRef(null); + const inputDescriptionRef = useRef(null); + useEffect(() => { + //Unmounting component clean + return () => { + onCancel(); + }; + }, []); - const createPolicyToSave = (): PolicyToSave => { - const sources = - groups - ?.filter((g) => formPolicy.tagSourceGroups.includes(g.name)) - .map((g) => g.id || "") || []; - const destinations = - groups - ?.filter((g) => formPolicy.tagDestinationGroups.includes(g.name)) - .map((g) => g.id || "") || []; - const sourcesNoId = formPolicy.tagSourceGroups.filter( - (s) => !tagGroups.includes(s) - ); - const destinationsNoId = formPolicy.tagDestinationGroups.filter( - (s) => !tagGroups.includes(s) - ); - const groupsToSave = uniq([...sourcesNoId, ...destinationsNoId]); - return { - id: formPolicy.id, - name: formPolicy.name, - description: formPolicy.description, - enabled: formPolicy.enabled, - sourcesNoId, - destinationsNoId, - groupsToSave, - rules: [ - { - id: formPolicy.id, - name: formPolicy.name, - description: formPolicy.description, - enabled: formPolicy.enabled, - sources: - direction.reverseDirectional && !direction.biDirectional - ? destinations - : sources, - destinations: - direction.reverseDirectional && !direction.biDirectional - ? sources - : destinations, - bidirectional: formPolicy.bidirectional, - protocol: formPolicy.protocol, - ports: formPolicy.ports, - action: "accept", - }, - ], - } as PolicyToSave; - }; + useEffect(() => { + if (editName) inputNameRef.current!.focus({cursor: "end"}); + }, [editName]); + useEffect(() => { + if (editDescription) inputDescriptionRef.current!.focus({cursor: "end"}); + }, [editDescription]); + useEffect(() => { + setTagGroups(groups?.map((g) => g.name) || []); + }, [groups]); + useEffect(() => { + if (!policy) return; + const fPolicy = { + id: policy.id, + name: policy.name, + description: policy.description, + enabled: policy.enabled, + query: "", + bidirectional: policy.rules[0].bidirectional, + protocol: policy.rules[0].protocol, + ports: policy.rules[0].ports, + action: policy.rules[0].action, + tagSourceGroups: policy.rules[0].sources + ? policy.rules[0].sources?.map((t) => t.name) + : [], + tagDestinationGroups: policy.rules[0].destinations + ? policy.rules[0].destinations?.map((t) => t.name) + : [], + } as FormPolicy; + setFormPolicy(fPolicy); + form.setFieldsValue(fPolicy); + if (fPolicy.bidirectional) { + setDirection({ + biDirectional: true, + reverseDirectional: true, + }); + } else { + setDirection({ + biDirectional: false, + reverseDirectional: false, + }); + } + }, [policy, form]); - const handleFormSubmit = () => { - form - .validateFields() - .then((_) => { - const policyToSave = createPolicyToSave(); - dispatch( - policyActions.savePolicy.request({ - getAccessTokenSilently: getTokenSilently, - payload: policyToSave, - }) + const createPolicyToSave = (): PolicyToSave => { + const sources = + groups + ?.filter((g) => formPolicy.tagSourceGroups.includes(g.name)) + .map((g) => g.id || "") || []; + const destinations = + groups + ?.filter((g) => formPolicy.tagDestinationGroups.includes(g.name)) + .map((g) => g.id || "") || []; + const sourcesNoId = formPolicy.tagSourceGroups.filter( + (s) => !tagGroups.includes(s) ); - }) - .catch((errorInfo) => { - console.log("errorInfo", errorInfo); - }); - }; - - const setVisibleNewRule = (status: boolean) => { - dispatch(policyActions.setSetupEditPolicyVisible(status)); - }; - - const onCancel = () => { - if (savedPolicy.loading) return; - setEditName(false); - dispatch( - policyActions.setPolicy({ - name: "", - description: "", - enabled: true, - query: "", - rules: [ - { - name: "", - description: "", - enabled: true, - sources: [], - destinations: [], - bidirectional: true, - protocol: "all", - ports: [], - action: "accept", - }, - ], - } as Policy) - ); - setVisibleNewRule(false); - }; - - const onChange = (data: any) => { - setFormPolicy({ ...formPolicy, ...data }); - }; - - const handleChangeSource = (value: string[]) => { - setFormPolicy({ - ...formPolicy, - tagSourceGroups: value, - }); - }; - - const handleChangeDestination = (value: string[]) => { - setFormPolicy({ - ...formPolicy, - tagDestinationGroups: value, - }); - }; - - const handleChangeProtocol = (value: string) => { - if (value === "all" || value === "icmp") { - setDirection({ - biDirectional: true, - reverseDirectional: true, - }); - } - setFormPolicy({ - ...formPolicy, - ports: value === "all" || value === "icmp" ? [] : formPolicy.ports, - protocol: value, - }); - }; - - const handleChangePorts = (value: string[]) => { - setFormPolicy({ - ...formPolicy, - ports: value, - }); - }; - - const handleChangeDisabled = (checked: boolean) => { - setFormPolicy({ - ...formPolicy, - enabled: checked, - }); - }; - - const handleChangeBidirect = (checked: boolean) => { - setFormPolicy({ - ...formPolicy, - bidirectional: checked, - }); - }; - - const blueTagRender = (props: CustomTagProps) => { - const { value, closable, onClose } = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); + const destinationsNoId = formPolicy.tagDestinationGroups.filter( + (s) => !tagGroups.includes(s) + ); + const groupsToSave = uniq([...sourcesNoId, ...destinationsNoId]); + return { + id: formPolicy.id, + name: formPolicy.name, + description: formPolicy.description, + enabled: formPolicy.enabled, + sourcesNoId, + destinationsNoId, + groupsToSave, + rules: [ + { + id: formPolicy.id, + name: formPolicy.name, + description: formPolicy.description, + enabled: formPolicy.enabled, + sources: + direction.reverseDirectional && !direction.biDirectional + ? destinations + : sources, + destinations: + direction.reverseDirectional && !direction.biDirectional + ? sources + : destinations, + bidirectional: formPolicy.bidirectional, + protocol: formPolicy.protocol, + ports: formPolicy.ports, + action: "accept", + }, + ], + } as PolicyToSave; }; - return ( - - {value} - - ); - }; - - const tagRender = (props: CustomTagProps) => { - const { value, closable, onClose } = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); + const handleFormSubmit = () => { + form + .validateFields() + .then((_) => { + const policyToSave = createPolicyToSave(); + dispatch( + policyActions.savePolicy.request({ + getAccessTokenSilently: getTokenSilently, + payload: policyToSave, + }) + ); + }) + .catch((errorInfo) => { + console.log("errorInfo", errorInfo); + }); }; - return ( - - {value} - - ); - }; + const setVisibleNewRule = (status: boolean) => { + dispatch(policyActions.setSetupEditPolicyVisible(status)); + }; - const optionRender = (label: string) => { - let peersCount = ""; - const g = groups.find((_g) => _g.name === label); - if (g) - peersCount = ` - ${g.peers_count || 0} ${ - !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" - } `; - return ( - <> - - {label} - - {peersCount} - - ); - }; + const onCancel = () => { + if (savedPolicy.loading) return; + setEditName(false); + dispatch( + policyActions.setPolicy({ + name: "", + description: "", + enabled: true, + query: "", + rules: [ + { + name: "", + description: "", + enabled: true, + sources: [], + destinations: [], + bidirectional: true, + protocol: "all", + ports: [], + action: "accept", + }, + ], + } as Policy) + ); + setVisibleNewRule(false); + }; - const dropDownRenderGroups = (menu: React.ReactElement) => ( - <> - {menu} - - - - + const onChange = (data: any) => { + setFormPolicy({...formPolicy, ...data}); + }; + + const handleChangeSource = (value: string[]) => { + setFormPolicy({ + ...formPolicy, + tagSourceGroups: value, + }); + }; + + const handleChangeDestination = (value: string[]) => { + setFormPolicy({ + ...formPolicy, + tagDestinationGroups: value, + }); + }; + + const handleChangeProtocol = (value: string) => { + if (value === "all" || value === "icmp") { + setDirection({ + biDirectional: true, + reverseDirectional: true, + }); + } + setFormPolicy({ + ...formPolicy, + ports: value === "all" || value === "icmp" ? [] : formPolicy.ports, + protocol: value, + }); + }; + + const handleChangePorts = (value: string[]) => { + setFormPolicy({ + ...formPolicy, + ports: value, + }); + }; + + const handleChangeDisabled = (checked: boolean) => { + setFormPolicy({ + ...formPolicy, + enabled: checked, + }); + }; + + const handleChangeBidirect = (checked: boolean) => { + setFormPolicy({ + ...formPolicy, + bidirectional: checked, + }); + }; + + const dropDownRenderGroups = (menu: React.ReactElement) => ( + <> + {menu} + + + + Add new group by pressing "Enter" - - - - - - - - - ); + + + + + + + + + ); - const dropDownRenderPorts = (menu: React.ReactElement) => ( - <> - {menu} - - - - + const dropDownRenderPorts = (menu: React.ReactElement) => ( + <> + {menu} + + + + Add new ports or range by pressing "Enter" - - - - - - - - - ); - - const toggleEditDescription = (status: boolean) => { - setEditDescription(status); - }; - - const selectValidator = (_: RuleObject, value: string[]) => { - let hasSpaceNamed = []; - if (!value.length) { - return Promise.reject(new Error("Please enter at least one group")); - } - - value.forEach(function (v: string) { - if (!v.trim().length) { - hasSpaceNamed.push(v); - } - }); - - if (hasSpaceNamed.length) { - return Promise.reject( - new Error("Group names with just spaces are not allowed") - ); - } - - return Promise.resolve(); - }; - - const selectPortRangeValidator = (_: RuleObject, value: string[]) => { - if (value) { - var failed = false; - value.forEach(function (v: string) { - let p = Number(v); - if (Number.isNaN(p) || p < 1 || p > 65535 || !Number.isInteger(p)) { - failed = true; - return; - } - }); - if (failed) { - return Promise.reject( - new Error("Port value must be in 1..65535 range") - ); - } - } - return Promise.resolve(); - }; - - const selectPortProtocolValidator = (_: RuleObject, value: string[]) => { - if (!formPolicy.bidirectional && value.length === 0) { - return Promise.reject(new Error("Directional traffic require ports")); - } - return Promise.resolve(); - }; - - const handleDirection = (directionValue: string) => { - if ( - directionValue === "forwardDirectional" && - !direction.reverseDirectional - ) { - setDirection({ - biDirectional: false, - reverseDirectional: false, - }); - } - - if ( - directionValue === "forwardDirectional" && - direction.reverseDirectional - ) { - setDirection({ - ...direction, - biDirectional: !direction.biDirectional, - }); - } - - if (directionValue === "reverseDirectional" && direction.biDirectional) { - setDirection({ - biDirectional: false, - reverseDirectional: !direction.reverseDirectional, - }); - } - - if (directionValue === "reverseDirectional" && !direction.biDirectional) { - setDirection({ - biDirectional: true, - reverseDirectional: true, - }); - } - }; - - const onBreadcrumbUsersClick = () => { - onCancel(); - }; - - const toggleEditName = (status: boolean) => { - setEditName(status); - }; - - useEffect(() => { - if (Object.keys(formPolicy).length > 0) { - setFormPolicy({ - ...formPolicy, - bidirectional: direction.biDirectional, - }); - } - }, [direction]); - return ( - <> - {policy && ( - - Access Control, - }, - { - title: policy.name, - }, - ]} - /> - -
-
- - -
+ + - {!editName && ( - toggleEditName(true)} - > - {formPolicy.name} - - )} - - - {editName && ( - <> - - Rule name - - - - - )} + + + + + + ); - {!editDescription ? ( -
toggleEditDescription(true)} + const toggleEditDescription = (status: boolean) => { + setEditDescription(status); + }; + + const selectValidator = (_: RuleObject, value: string[]) => { + let hasSpaceNamed = []; + if (!value.length) { + return Promise.reject(new Error("Please enter at least one group")); + } + + value.forEach(function (v: string) { + if (!v.trim().length) { + hasSpaceNamed.push(v); + } + }); + + if (hasSpaceNamed.length) { + return Promise.reject( + new Error("Group names with just spaces are not allowed") + ); + } + + return Promise.resolve(); + }; + + const selectPortRangeValidator = (_: RuleObject, value: string[]) => { + if (value) { + var failed = false; + value.forEach(function (v: string) { + let p = Number(v); + if (Number.isNaN(p) || p < 1 || p > 65535 || !Number.isInteger(p)) { + failed = true; + return; + } + }); + if (failed) { + return Promise.reject( + new Error("Port value must be in 1..65535 range") + ); + } + } + return Promise.resolve(); + }; + + const selectPortProtocolValidator = (_: RuleObject, value: string[]) => { + if (!formPolicy.bidirectional && value.length === 0) { + return Promise.reject(new Error("Directional traffic require ports")); + } + return Promise.resolve(); + }; + + const handleDirection = (directionValue: string) => { + if ( + directionValue === "forwardDirectional" && + !direction.reverseDirectional + ) { + setDirection({ + biDirectional: false, + reverseDirectional: false, + }); + } + + if ( + directionValue === "forwardDirectional" && + direction.reverseDirectional + ) { + setDirection({ + ...direction, + biDirectional: !direction.biDirectional, + }); + } + + if (directionValue === "reverseDirectional" && direction.biDirectional) { + setDirection({ + biDirectional: false, + reverseDirectional: !direction.reverseDirectional, + }); + } + + if (directionValue === "reverseDirectional" && !direction.biDirectional) { + setDirection({ + biDirectional: true, + reverseDirectional: true, + }); + } + }; + + const onBreadcrumbUsersClick = () => { + onCancel(); + }; + + const toggleEditName = (status: boolean) => { + setEditName(status); + }; + + useEffect(() => { + if (Object.keys(formPolicy).length > 0) { + setFormPolicy({ + ...formPolicy, + bidirectional: direction.biDirectional, + }); + } + }, [direction]); + return ( + <> + {policy && ( + + Access Control, + }, + { + title: policy.name, + }, + ]} + /> + +
+ - {formPolicy.description && - formPolicy.description.trim() !== "" ? ( - formPolicy.description - ) : ( - + + +
+ {!editName && ( + toggleEditName(true)} + > + {formPolicy.name} + + )} + + + {editName && ( + <> + + Rule name + + + toggleEditName(false)} + onBlur={() => toggleEditName(false)} + autoComplete="off" + /> + + + )} + + {!editDescription ? ( +
toggleEditDescription(true)} + > + {formPolicy.description && + formPolicy.description.trim() !== "" ? ( + formPolicy.description + ) : ( + Add description - )} -
- ) : ( - - - toggleEditDescription(false) - } - onBlur={() => toggleEditDescription(false)} - autoComplete="off" - /> - - )} - -
-
- - - -
- -
- - - {formPolicy.enabled - ? "Disable this rule to apply it later" - : "Enable this rule to apply it immediately"} - + )} +
+ ) : ( + + + toggleEditDescription(false) + } + onBlur={() => toggleEditDescription(false)} + autoComplete="off" + /> + + )} + + +
+ + + +
+ +
+ + + {formPolicy.enabled + ? "Disable this rule to apply it later" + : "Enable this rule to apply it immediately"} + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + To change traffic direction and ports, select TCP or UDP protocol below + + + + + + {formPolicy && + formPolicy.ports?.map((m) => ( + + ))} + + + +
+
- - - - - - - - - - - - - - - - - - - - - - - - To change traffic direction and ports, select TCP or UDP protocol below - - - - - - {formPolicy && - formPolicy.ports?.map((m) => ( - - ))} - - - -
- - - - - - - - - )} - - ); + + + + + + )} + + ); }; export default AccessControlEdit; diff --git a/src/components/AccessControlNew.tsx b/src/components/AccessControlNew.tsx index 59ff026..92862d2 100644 --- a/src/components/AccessControlNew.tsx +++ b/src/components/AccessControlNew.tsx @@ -29,6 +29,7 @@ import { uniq } from "lodash"; import { Header } from "antd/es/layout/layout"; import { RuleObject } from "antd/lib/form"; import { useGetTokenSilently } from "../utils/token"; +import {useGetGroupTagHelpers} from "../utils/groups"; const { Paragraph } = Typography; const { Option } = Select; @@ -49,6 +50,11 @@ interface FormPolicy { } const AccessControlNew = () => { + const { + optionRender, + grayTagRender, + blueTagRender + } = useGetGroupTagHelpers() const { getTokenSilently } = useGetTokenSilently(); const dispatch = useDispatch(); const setupNewPolicyVisible = useSelector( @@ -262,63 +268,6 @@ const AccessControlNew = () => { }); }; - const blueTagRender = (props: CustomTagProps) => { - const { value, closable, onClose } = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {value} - - ); - }; - - const tagRender = (props: CustomTagProps) => { - const { value, closable, onClose } = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {value} - - ); - }; - - const optionRender = (label: string) => { - let peersCount = ""; - const g = groups.find((_g) => _g.name === label); - if (g) - peersCount = ` - ${g.peers_count || 0} ${ - !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" - } `; - return ( - <> - - {label} - - {peersCount} - - ); - }; - const dropDownRenderGroups = (menu: React.ReactElement) => ( <> {menu} @@ -801,7 +750,7 @@ const AccessControlNew = () => { Allow only specified network protocols diff --git a/src/components/PeerUpdate.tsx b/src/components/PeerUpdate.tsx index 2be4de5..cffe0b5 100644 --- a/src/components/PeerUpdate.tsx +++ b/src/components/PeerUpdate.tsx @@ -36,6 +36,7 @@ import { RuleObject } from "antd/lib/form"; import { useGetTokenSilently } from "../utils/token"; import { timeAgo } from "../utils/common"; import { actions as routeActions } from "../store/route"; +import {useGetGroupTagHelpers} from "../utils/groups"; const { Paragraph } = Typography; const { Option } = Select; @@ -47,6 +48,9 @@ const PeerUpdate = () => { const { getTokenSilently } = useGetTokenSilently(); const { Column } = Table; const { confirm } = Modal; + const { + optionRender, + } = useGetGroupTagHelpers() const dispatch = useDispatch(); const groups = useSelector((state: RootState) => state.group.data); @@ -223,28 +227,11 @@ const PeerUpdate = () => { onClose={onClose} style={{ marginRight: 3 }} > - {value} + {value} ); }; - const optionRender = (label: string) => { - let peersCount = ""; - const g = groups.find((_g) => _g.name === label); - if (g) - peersCount = ` - ${g.peers_count || 0} ${ - !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" - } `; - return ( - <> - - {label} - - {peersCount} - - ); - }; - const dropDownRender = (menu: React.ReactElement) => ( <> {menu} @@ -640,7 +627,6 @@ const PeerUpdate = () => { diff --git a/src/components/SetupKeyEdit.tsx b/src/components/SetupKeyEdit.tsx index e0f0dc2..183ba15 100644 --- a/src/components/SetupKeyEdit.tsx +++ b/src/components/SetupKeyEdit.tsx @@ -33,6 +33,7 @@ import { Container } from "./Container"; import Paragraph from "antd/es/typography/Paragraph"; import { EditOutlined, LockOutlined } from "@ant-design/icons"; import { actions as personalAccessTokenActions } from "../store/personal-access-token"; +import {useGetGroupTagHelpers} from "../utils/groups"; const { Option } = Select; const { Text } = Typography; @@ -43,6 +44,10 @@ const customExpiresFormat = (value: Date): string | null => { }; const SetupKeyNew = () => { + const { + optionRender, + blueTagRender + } = useGetGroupTagHelpers() const { getTokenSilently } = useGetTokenSilently(); const dispatch = useDispatch(); @@ -195,46 +200,6 @@ const SetupKeyNew = () => { return Promise.resolve(); }; - const tagRender = (props: CustomTagProps) => { - const { value, closable, onClose } = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {value} - - ); - }; - - const optionRender = (label: string) => { - let peersCount = ""; - const g = groups.find((_g) => _g.name === label); - - if (g) { - peersCount = ` - ${g.peers_count || 0} ${ - !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" - } `; - } - - return ( - <> - - {label} - - {peersCount} - - ); - }; - const dropDownRender = (menu: React.ReactElement) => ( <> {menu} @@ -435,7 +400,7 @@ const SetupKeyNew = () => { mode="tags" style={{ width: "100%" }} placeholder="Associate groups with the key" - tagRender={tagRender} + tagRender={blueTagRender} dropdownRender={dropDownRender} // enabled only when we have a new key !setupkey.id or when the key is valid disabled={!(!setupKey.id || setupKey.valid)} diff --git a/src/components/SetupKeyNew.tsx b/src/components/SetupKeyNew.tsx index 1239bc4..86fcbaa 100644 --- a/src/components/SetupKeyNew.tsx +++ b/src/components/SetupKeyNew.tsx @@ -32,12 +32,16 @@ import { Container } from "./Container"; import Paragraph from "antd/es/typography/Paragraph"; import { CheckOutlined, CopyOutlined } from "@ant-design/icons"; import { copyToClipboard } from "../utils/common"; +import {useGetGroupTagHelpers} from "../utils/groups"; const { Option } = Select; const { Text } = Typography; const ExpiresInDefault: ExpiresInValue = { number: 30, interval: "day" }; const SetupKeyNew = () => { + const { + optionRender, + } = useGetGroupTagHelpers() const { getTokenSilently } = useGetTokenSilently(); const dispatch = useDispatch(); const setupNewKeyVisible = useSelector( @@ -243,26 +247,6 @@ const SetupKeyNew = () => { ); }; - const optionRender = (label: string) => { - let peersCount = ""; - const g = groups.find((_g) => _g.name === label); - - if (g) { - peersCount = ` - ${g.peers_count || 0} ${ - !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" - } `; - } - - return ( - <> - - {label} - - {peersCount} - - ); - }; - const dropDownRender = (menu: React.ReactElement) => ( <> {menu} @@ -551,7 +535,6 @@ const SetupKeyNew = () => { style={{ whiteSpace: "pre-line", margin: 0, - fontWeight: "bold", }} > Auto-assigned groups diff --git a/src/components/UserEdit.tsx b/src/components/UserEdit.tsx index 71b34b9..672340b 100644 --- a/src/components/UserEdit.tsx +++ b/src/components/UserEdit.tsx @@ -28,9 +28,9 @@ import tableSpin from "./Spin"; import AddPATPopup from "./popups/AddPATPopup"; import {fullDate} from "../utils/common"; import {ExclamationCircleOutlined} from "@ant-design/icons"; -import {Container} from "./Container"; import Column from "antd/lib/table/Column"; import {useOidcUser} from "@axa-fr/react-oidc"; +import {useGetGroupTagHelpers} from "../utils/groups"; const {Option} = Select; const {Meta} = Card; @@ -45,6 +45,10 @@ interface TokenDataTable extends PersonalAccessToken { const UserEdit = () => { const {getTokenSilently} = useGetTokenSilently() const dispatch = useDispatch() + const { + optionRender, + blueTagRender + } = useGetGroupTagHelpers() const groups = useSelector((state: RootState) => state.group.data) const users = useSelector((state: RootState) => state.user.data) @@ -151,26 +155,6 @@ const UserEdit = () => { return Promise.resolve() } - const tagRender = (props: CustomTagProps) => { - const {label, value, closable, onClose} = props; - const onPreventMouseDown = (event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - - {value} - - ); - } - const dropDownRender = (menu: React.ReactElement) => ( <> {menu} @@ -190,23 +174,6 @@ const UserEdit = () => { ) - const optionRender = (label: string) => { - let peersCount = '' - const g = groups.find(_g => _g.name === label) - if (g) peersCount = ` - ${g.peers_count || 0} ${(!g.peers_count || parseInt(g.peers_count) !== 1) ? 'peers' : 'peer'} ` - return ( - <> - - {label} - - {peersCount} - - ) - } - const transformTokenTable = (d: PersonalAccessToken[]): TokenDataTable[] => { if (!d) { return [] @@ -397,12 +364,12 @@ const UserEdit = () => { label={Auto-assigned groups} tooltip="Every peer enrolled with this user will be automatically added to these groups" rules={[{ validator: selectValidator }]} - style={{ marginRight: "70px", fontWeight: "bold" }} + style={{ marginRight: "70px" }} > diff --git a/src/index.css b/src/index.css index 21e560d..843a585 100644 --- a/src/index.css +++ b/src/index.css @@ -191,9 +191,9 @@ td.non-highlighted-table-column { font-weight: 500; } -.inconsolata-font, -.inconsolata-font * { - font-family: 'Inconsolata', monospace !important; +.menlo-font, +.menlo-font * { + font-family: 'Menlo', monospace !important; } .tag-box .ant-select-selector { diff --git a/src/utils/groups.tsx b/src/utils/groups.tsx index a8238af..0b58317 100644 --- a/src/utils/groups.tsx +++ b/src/utils/groups.tsx @@ -12,7 +12,14 @@ export const useGetGroupTagHelpers = () => { const [groupTagFilterAll, setGroupTagFilterAll] = useState(false) const [selectedTagGroups, setSelectedTagGroups] = useState([] as string[]) - const tagRender = (props: CustomTagProps) => { + const blueTagRender = (props: CustomTagProps) => { + return tagRender(props, "blue") + } + const grayTagRender = (props: CustomTagProps) => { + return tagRender(props, "") + } + + const tagRender = (props: CustomTagProps, color: string) => { const {value, closable, onClose} = props; const onPreventMouseDown = (event: React.MouseEvent) => { event.preventDefault(); @@ -21,13 +28,13 @@ export const useGetGroupTagHelpers = () => { return ( - {value} + {value} ); } @@ -62,21 +69,21 @@ export const useGetGroupTagHelpers = () => { ) const optionRender = (label: string) => { - let peersCount = '' - const g = groups.find(_g => _g.name === label) - if (g) peersCount = ` - ${g.peers_count || 0} ${(!g.peers_count || parseInt(g.peers_count) !== 1) ? 'peers' : 'peer'} ` + let peersCount = ""; + const g = groups.find((_g) => _g.name === label); + if (g) + peersCount = ` - ${g.peers_count || 0} ${ + !g.peers_count || parseInt(g.peers_count) !== 1 ? "peers" : "peer" + } `; return ( - <> - - {label} +
+ + {label} - {peersCount} - - ) - } + {peersCount} +
+ ); + }; const getExistingAndToCreateGroupsLists = (groupNameList: string[]): [string[], string[]] => { const groupIDList = groups?.filter(g => groupNameList.includes(g.name)).map(g => g.id || '') || [] @@ -127,6 +134,8 @@ export const useGetGroupTagHelpers = () => { return { tagRender, + blueTagRender, + grayTagRender, handleChangeTags, dropDownRender, optionRender, diff --git a/src/views/AccessControl.tsx b/src/views/AccessControl.tsx index afc024b..812da3b 100644 --- a/src/views/AccessControl.tsx +++ b/src/views/AccessControl.tsx @@ -435,7 +435,7 @@ export const AccessControl = () => { } `; return (
- + {_g.name} {peersCount} @@ -472,7 +472,7 @@ export const AccessControl = () => { const content = ports?.map((p, i) => { return ( - {p} + {p} ); }); @@ -739,7 +739,7 @@ export const AccessControl = () => { render={(text, record: PolicyDataTable, index) => { return ( { const dispatch = useDispatch() const { - tagRender, + blueTagRender, handleChangeTags, dropDownRender, optionRender, @@ -148,7 +148,7 @@ export const DNSSettingsForm = () => { >