Compare commits

...
14 Commits
Author SHA1 Message Date
Sarooj bukhari 30b858c1bc Make all modals UI consistent (#229) 2023-07-12 17:35:55 +02:00
Sarooj bukhari e82b269ff5 fix network routes pages (#228) 2023-07-11 09:06:08 +02:00
braginini 23a4b79f01 Fix disabled links 2023-07-10 18:13:08 +02:00
Sarooj bukhari cc5a9b1033 Fix table loading glitch (#227) 2023-07-10 16:49:52 +02:00
Sarooj bukhari 09ae157be3 Re-work DNS layout (#222) 2023-07-10 09:03:27 +02:00
pascal-fischer cb89eeb921 Fix default value for expiration for setup keys (#221)
* fix initial value for setup keys so default works

* fix initial value for setup keys so default works
2023-07-07 12:40:51 +02:00
pascal-fischer 79446c0e77 remove formatted expiry logic and fix sent expires_in (#220) 2023-07-06 17:16:10 +02:00
Zoltan Papp 1f258e4e2c Update copyright title at the bottom of the page (#219) 2023-07-06 16:38:02 +02:00
braginini bae95d2e11 Fix peer groups control in the peer update view 2023-07-01 20:40:26 +02:00
Sarooj bukhari 3d95a826e7 Improve ACL Ui layout 2023-07-01 20:06:46 +02:00
Sarooj bukhariandSarooj Bukhari d8d13aff01 Add copy on add peer code (#217)
Co-authored-by: Sarooj Bukhari <120650489+saroojbukhari2022@users.noreply.github.com>
2023-06-27 15:01:59 +02:00
695b571a50 table route layout (#213)
Co-authored-by: Sarooj Bukhari <120650489+saroojbukhari2022@users.noreply.github.com>
Co-authored-by: braginini <misha@netbird.io>
2023-06-27 11:08:49 +03:00
Sarooj bukhariandSarooj Bukhari ddfb6a6179 Add copy button on add peer code box and remove check to shoe default rule
Co-authored-by: Sarooj Bukhari <120650489+saroojbukhari2022@users.noreply.github.com>
2023-06-27 07:06:21 +02:00
pascal-fischer 8c94119c6a extend gitignore to ignore all config files (#212) 2023-06-19 17:16:57 +02:00
39 changed files with 5723 additions and 3470 deletions

No files matched your search

+1 -1
View File
@@ -26,6 +26,6 @@ yarn-error.log*
src/auth_config.json
.idea
.eslintcache
src/.local-config.json
src/.local-config*.json
/public/OidcServiceWorker.js
/public/OidcTrustedDomains.js
+11
View File
@@ -0,0 +1,11 @@
{
"auth0Auth": "true",
"authAuthority": "https://netbird-localdev.eu.auth0.com",
"authClientId": "kBRMAOqIZ7hvpVCaypQLCJvTzkYYIXVt",
"authScopesSupported": "openid profile email api offline_access email_verified",
"authAudience": "http://localhost:3000/",
"apiOrigin": "http://0.0.0.0",
"grpcApiOrigin": "http://0.0.0.0:80",
"latestVersion": "v0.6.3"
}
File diff suppressed because it is too large. Load diff
+99 -66
View File
@@ -29,7 +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";
import { useGetGroupTagHelpers } from "../utils/groups";
const { Paragraph } = Typography;
const { Option } = Select;
@@ -50,11 +50,8 @@ interface FormPolicy {
}
const AccessControlNew = () => {
const {
optionRender,
grayTagRender,
blueTagRender
} = useGetGroupTagHelpers()
const { optionRender, grayTagRender, blueTagRender } =
useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
const setupNewPolicyVisible = useSelector(
@@ -71,6 +68,8 @@ const AccessControlNew = () => {
{ label: "UDP", value: "udp" },
{ label: "ICMP", value: "icmp" },
];
const formPolicyCopy: any = ["ALL"];
const policy = useSelector((state: RootState) => state.policy.policy);
const savedPolicy = useSelector(
(state: RootState) => state.policy.savedPolicy
@@ -274,9 +273,7 @@ const AccessControlNew = () => {
<Divider style={{ margin: "8px 0" }} />
<Row style={{ padding: "0 8px 4px" }}>
<Col flex="auto">
<Text type={"secondary"}>
Add new ports by pressing "Enter"
</Text>
<Text type={"secondary"}>Add new ports by pressing "Enter"</Text>
</Col>
<Col flex="none">
<svg
@@ -459,19 +456,21 @@ const AccessControlNew = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
margin: "0px",
fontWeight:"500"
fontWeight: "500",
}}
>
Create Rule
Create rule
</Paragraph>
<Paragraph
type={"secondary"}
style={{
textAlign: "start",
whiteSpace: "pre-line",
paddingBottom: "15px",
}}
type={"secondary"}
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-20px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
}}
>
Use this rule to restrict access to groups of resources
</Paragraph>
@@ -727,10 +726,11 @@ const AccessControlNew = () => {
</Col>
<Col span={24}>
<Paragraph
type={"secondary"}
style={{ marginTop: "-15px", marginBottom: "30px" }}
type={"secondary"}
style={{ marginTop: "-15px", marginBottom: "30px" }}
>
To change traffic direction and ports, select TCP or UDP protocol below
To change traffic direction and ports, select TCP or UDP
protocol below
</Paragraph>
</Col>
<Col span={24}>
@@ -769,6 +769,8 @@ const AccessControlNew = () => {
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
padding: "0 0 2px",
display: "inline-block",
}}
>
Ports
@@ -784,50 +786,80 @@ const AccessControlNew = () => {
Allow network traffic and access only to specified ports
</Paragraph>
</div>
<Form.Item
name="ports"
label=""
style={{ fontWeight: "500" }}
rules={[
{
message: "Directional traffic requires at least one port",
validator: selectPortProtocolValidator,
required: false,
},
{
message: "Port value must be in 1..65535 range",
validator: selectPortRangeValidator,
required: false,
},
]}
>
<Select
mode="tags"
style={{
width: "100%",
maxWidth: "280px",
fontWeight: "500",
}}
className="menlo-font"
placeholder={ (formPolicy.protocol === "all" || formPolicy.protocol === "icmp") ? "Change protocol to add ports" : "Add ports"}
tagRender={grayTagRender}
onChange={handleChangePorts}
dropdownRender={dropDownRenderPorts}
disabled={
formPolicy.protocol === "all" ||
formPolicy.protocol === "icmp"
}
{formPolicy.protocol === "all" ||
formPolicy.protocol === "icmp" ? (
<Form.Item>
<Select
mode="tags"
style={{
width: "100%",
maxWidth: "260px",
fontWeight: "500",
}}
placeholder={<Text>Select ports</Text>}
className="menlo-font"
value={formPolicyCopy}
disabled={true}
></Select>
</Form.Item>
) : (
<Form.Item
name="ports"
label=""
style={{ fontWeight: "500" }}
rules={[
{
message:
"Directional traffic requires at least one port",
validator: selectPortProtocolValidator,
required: false,
},
{
message: "Port value must be in 1..65535 range",
validator: selectPortRangeValidator,
required: false,
},
]}
>
{formPolicy &&
formPolicy.ports?.map((m) => (
<Option key={m}>
<Tag style={{ marginRight: 3 }}>
{m}
</Tag>
</Option>
))}
</Select>
</Form.Item>
<Select
mode="tags"
style={{
width: "100%",
maxWidth: "280px",
fontWeight: "500",
}}
className="menlo-font"
placeholder={
formPolicy.protocol === "all" ||
formPolicy.protocol === "icmp" ? (
"All"
) : (
<div
color={"rgba(0,0,0,0.25)"}
className="arimo-font"
>
Select ports
</div>
)
}
tagRender={grayTagRender}
onChange={handleChangePorts}
dropdownRender={dropDownRenderPorts}
disabled={
formPolicy.protocol === "all" ||
formPolicy.protocol === "icmp"
}
>
{formPolicy &&
formPolicy.ports?.map((m) => (
<Option key={m}>
<Tag style={{ marginRight: 3 }}>{m}</Tag>
</Option>
))}
</Select>
</Form.Item>
)}
</Col>
<Col span={24}>
<Form.Item name="enabled" label="">
@@ -838,6 +870,7 @@ const AccessControlNew = () => {
}}
>
<Switch
size="small"
onChange={handleChangeDisabled}
defaultChecked={true}
/>
@@ -869,7 +902,7 @@ const AccessControlNew = () => {
</Col>
<Col
span={24}
style={{ marginTop: "20px", marginBottom: "25px" }}
style={{ marginTop: "10px", marginBottom: "24px" }}
>
<Text type={"secondary"}>
Learn more about
@@ -879,7 +912,7 @@ const AccessControlNew = () => {
href="https://docs.netbird.io/how-to/manage-network-access"
>
{" "}
Access Controls
access controls
</a>
</Text>
</Col>
+2 -2
View File
@@ -6,7 +6,7 @@ const { Footer } = Layout
export default () => {
return (
<Footer style={{ textAlign: 'center', bottom: "0"}}>
Copyright © 2022 <a href="https://netbird.io">NetBird Authors</a>
Copyright © 2023 <a href="https://netbird.io">NetBird Authors</a>
</Footer>
);
};
};
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+13 -3
View File
@@ -366,7 +366,6 @@ const PeerUpdate = () => {
noUpdateToName() &&
noUpdateToLoginExpiration()
) {
console.log("no group update==<");
const style = { marginTop: 85 };
if (savedGroups.loading) {
message.loading({
@@ -863,15 +862,26 @@ const PeerUpdate = () => {
</Form.Item>
</Col>
<Col span={8}>
<Paragraph
style={{
whiteSpace: "pre-line",
margin: 0,
fontWeight: "500",
}}
>
Groups
</Paragraph>
<Text type={"secondary"}>
Use groups to control what this peer can access
</Text>
<Form.Item
name="groupsNames"
label="Select peer groups"
rules={[{ validator: selectValidator }]}
style={{ fontWeight: "500" }}
>
<Select
mode="tags"
style={{ width: "100%" }}
style={{ width: "100%", marginTop: 5 }}
placeholder="Select groups..."
tagRender={tagRender}
dropdownRender={dropDownRender}
+60 -77
View File
@@ -5,12 +5,11 @@ import { actions as routeActions } from "../store/route";
import {
Button,
Col,
Divider,
Collapse,
Form,
Input,
message,
InputNumber,
Radio,
Row,
Select,
SelectProps,
@@ -19,11 +18,6 @@ import {
Modal,
Typography,
} from "antd";
import {
CloseOutlined,
FlagFilled,
QuestionCircleFilled,
} from "@ant-design/icons";
import CreatableSelect from "react-select/creatable";
import { Route, RouteToSave } from "../store/route/types";
import { Header } from "antd/es/layout/layout";
@@ -31,7 +25,6 @@ import { RuleObject } from "antd/lib/form";
import cidrRegex from "cidr-regex";
import {
initPeerMaps,
masqueradeDisabledMSG,
peerToPeerIP,
routePeerSeparator,
transformGroupedDataTable,
@@ -55,8 +48,7 @@ const RouteAddNew = (selectedPeer: any) => {
getGroupNamesFromIDs,
selectValidator,
} = useGetGroupTagHelpers();
// const { optionRender, blueTagRender, grayTagRender } =
// useGetGroupTagHelpers();
const { Option } = Select;
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
@@ -79,29 +71,10 @@ const RouteAddNew = (selectedPeer: any) => {
const [form] = Form.useForm();
const inputNameRef = useRef<any>(null);
const inputDescriptionRef = useRef<any>(null);
const defaultRoutingPeerMSG = "Routing Peer";
const [routingPeerMSG, setRoutingPeerMSG] = useState(defaultRoutingPeerMSG);
const defaultMasqueradeMSG = "Masquerade";
const [masqueradeMSG, setMasqueradeMSG] = useState(defaultMasqueradeMSG);
const defaultStatusMSG = "Status";
const [statusMSG, setStatusMSG] = useState(defaultStatusMSG);
const [enableNetwork, setEnableNetwork] = useState(false);
const [peerNameToIP, peerIPToName, peerIPToID] = initPeerMaps(peers);
const [newRoute, setNewRoute] = useState(false);
useEffect(() => {
if (!newRoute) {
setRoutingPeerMSG(defaultRoutingPeerMSG);
setMasqueradeMSG("Update Masquerade");
setStatusMSG("Update Status");
} else {
setRoutingPeerMSG(defaultRoutingPeerMSG);
setMasqueradeMSG(defaultMasqueradeMSG);
setStatusMSG(defaultStatusMSG);
setPreviousRouteKey("");
}
}, [newRoute]);
useEffect(() => {
if (editName)
inputNameRef.current!.focus({
@@ -151,8 +124,7 @@ const RouteAddNew = (selectedPeer: any) => {
setNewRoute(false);
}
// let options = [];
}, [route]);
}, [route]);
selectedPeer &&
selectedPeer.notPeerRoutes &&
@@ -368,7 +340,7 @@ const RouteAddNew = (selectedPeer: any) => {
};
form.setFieldsValue(updateNetwork);
setFormRoute(updateNetwork);
setEnableNetwork(false)
setEnableNetwork(false);
} else if (!!selectedOption.__isNew__) {
const updateNetwork = {
...formRoute,
@@ -390,6 +362,54 @@ const RouteAddNew = (selectedPeer: any) => {
}
};
const styleNotification = { marginTop: 85 };
const saveKey = "saving";
useEffect(() => {
if (savedRoute.loading) {
message.loading({
content: "Saving...",
key: saveKey,
duration: 0,
style: styleNotification,
});
} else if (savedRoute.success) {
message.success({
content: "Route has been successfully added.",
key: saveKey,
duration: 2,
style: styleNotification,
});
dispatch(routeActions.setSetupNewRouteVisible(false));
dispatch(routeActions.setSetupEditRouteVisible(false));
dispatch(routeActions.setSetupEditRoutePeerVisible(false));
dispatch(routeActions.setSavedRoute({ ...savedRoute, success: false }));
dispatch(routeActions.resetSavedRoute(null));
} else if (savedRoute.error) {
let errorMsg = "Failed to update network route";
switch (savedRoute.error.statusCode) {
case 403:
errorMsg =
"Failed to update network route. You might not have enough permissions.";
break;
default:
errorMsg = savedRoute.error.data.message
? savedRoute.error.data.message
: errorMsg;
break;
}
message.error({
content: errorMsg,
key: saveKey,
duration: 5,
style: styleNotification,
});
dispatch(routeActions.setSavedRoute({ ...savedRoute, error: null }));
dispatch(routeActions.resetSavedRoute(null));
}
}, [savedRoute]);
return (
<>
{route && (
@@ -406,7 +426,7 @@ const RouteAddNew = (selectedPeer: any) => {
disabled={savedRoute.loading}
onClick={handleFormSubmit}
>
Add Route
Add route
</Button>
</Space>
}
@@ -416,6 +436,7 @@ const RouteAddNew = (selectedPeer: any) => {
form={form}
requiredMark={false}
onValuesChange={onChange}
className="route-form"
>
<Row gutter={16}>
<Col span={24}>
@@ -431,10 +452,10 @@ const RouteAddNew = (selectedPeer: any) => {
fontSize: "18px",
margin: "0px",
fontWeight: 500,
marginBottom: "15px",
marginBottom: "25px",
}}
>
Add Route
Add route
</Paragraph>
{!!selectedPeer.selectedPeer && (
@@ -573,7 +594,7 @@ const RouteAddNew = (selectedPeer: any) => {
<div
onClick={() => toggleEditDescription(true)}
style={{
margin: "0 0 30px",
margin: "0 0 15px",
lineHeight: "22px",
cursor: "pointer",
}}
@@ -611,45 +632,6 @@ const RouteAddNew = (selectedPeer: any) => {
</Row>
</Header>
</Col>
{/* {!!!selectedPeer.selectedPeer && (
<Col span={24}>
<Form.Item name="enabled" label="">
<div
style={{
display: "flex",
gap: "15px",
}}
>
<Switch
size={"small"}
checked={formRoute.enabled}
onChange={handleEnableChange}
/>
<div>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
}}
>
Enabled
</label>
<Paragraph
type={"secondary"}
style={{
marginTop: "-2",
fontWeight: "500",
marginBottom: "0",
}}
>
You can enable or disable the route
</Paragraph>
</div>
</div>
</Form.Item>
</Col>
)} */}
<Col span={24}>
<label
style={{
@@ -804,6 +786,7 @@ const RouteAddNew = (selectedPeer: any) => {
bordered={false}
ghost={true}
style={{ padding: "0" }}
className="remove-bg"
>
<Panel
key="0"
@@ -904,7 +887,7 @@ const RouteAddNew = (selectedPeer: any) => {
</Col>
<Col
span={24}
style={{ marginTop: "20px", marginBottom: "25px" }}
style={{ marginTop: "24px", marginBottom: "12px" }}
>
<Text type={"secondary"}>
Learn more about
@@ -914,7 +897,7 @@ const RouteAddNew = (selectedPeer: any) => {
href="https://docs.netbird.io/how-to/routing-traffic-to-private-networks"
>
{" "}
Network Routes
network routes
</a>
</Text>
</Col>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+10 -21
View File
@@ -27,7 +27,6 @@ import { RuleObject } from "antd/lib/form";
import { CustomTagProps } from "rc-select/lib/BaseSelect";
import { Group } from "../store/group/types";
import { useGetTokenSilently } from "../utils/token";
import { expiresInToSeconds, ExpiresInValue } from "../views/ExpiresInInput";
import moment from "moment";
import { Container } from "./Container";
import Paragraph from "antd/es/typography/Paragraph";
@@ -37,7 +36,6 @@ import { useGetGroupTagHelpers } from "../utils/groups";
const { Option } = Select;
const { Text } = Typography;
const ExpiresInDefault: ExpiresInValue = { number: 30, interval: "day" };
const customExpiresFormat = (value: Date): string | null => {
return formatDate(value);
@@ -95,7 +93,6 @@ const SetupKeyNew = () => {
const fSetupKey = {
...setupKey,
autoGroupNames: setupKey.auto_groups ? formKeyGroups : [],
expiresInFormatted: ExpiresInDefault,
exp: moment(setupKey.expires),
last: moment(setupKey.last_used),
} as FormSetupKey;
@@ -115,7 +112,7 @@ const SetupKeyNew = () => {
(s) => !allGroupsNames.includes(s)
);
const expiresIn = expiresInToSeconds(formSetupKey.expiresInFormatted);
const expiresIn = formSetupKey.expires_in * 24 * 3600 // the api expects seconds while the form returns days
return {
id: formSetupKey.id,
name: formSetupKey.name,
@@ -278,7 +275,13 @@ const SetupKeyNew = () => {
/>
<Card bordered={true} style={{ marginBottom: "7px", border: "none" }}>
<div style={{ maxWidth: "800px" }}>
<h3 style={{ fontSize: "22px", fontWeight: "500",marginBottom:"30px" }}>
<h3
style={{
fontSize: "22px",
fontWeight: "500",
marginBottom: "30px",
}}
>
{setupKey.name}
</h3>
<Form
@@ -287,7 +290,6 @@ const SetupKeyNew = () => {
form={form}
onValuesChange={onChange}
initialValues={{
expiresIn: ExpiresInDefault,
usage_limit: 1,
}}
>
@@ -365,7 +367,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "30px" }}>
<Row style={{ marginTop: "39px" }}>
<Col
xs={24}
sm={24}
@@ -423,20 +425,6 @@ const SetupKeyNew = () => {
</Row>
</Col>
</Row>
<Row style={{ marginTop: "40px", marginBottom: "28px" }}>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/register-machines-using-setup-keys"
>
{" "}
Setup Keys
</a>
</Text>
</Row>
</Form>
</div>
<Container
@@ -446,6 +434,7 @@ const SetupKeyNew = () => {
justifyContent: "start",
padding: 0,
gap: "10px",
marginTop: "24px",
}}
key={0}
>
+16 -39
View File
@@ -26,22 +26,18 @@ import { RuleObject } from "antd/lib/form";
import { CustomTagProps } from "rc-select/lib/BaseSelect";
import { Group } from "../store/group/types";
import { useGetTokenSilently } from "../utils/token";
import { expiresInToSeconds, ExpiresInValue } from "../views/ExpiresInInput";
import moment from "moment";
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";
import { useGetGroupTagHelpers } from "../utils/groups";
const { Option } = Select;
const { Text } = Typography;
const ExpiresInDefault: ExpiresInValue = { number: 30, interval: "day" };
const SetupKeyNew = () => {
const {
optionRender,
} = useGetGroupTagHelpers()
const { optionRender, blueTagRender } = useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
const setupNewKeyVisible = useSelector(
@@ -90,7 +86,6 @@ const SetupKeyNew = () => {
const fSetupKey = {
...setupKey,
autoGroupNames: setupKey.auto_groups ? formKeyGroups : [],
expiresInFormatted: ExpiresInDefault,
exp: moment(setupKey.expires),
last: moment(setupKey.last_used),
} as FormSetupKey;
@@ -110,7 +105,7 @@ const SetupKeyNew = () => {
(s) => !allGroupsNames.includes(s)
);
const expiresIn = expiresInToSeconds(formSetupKey.expiresInFormatted);
const expiresIn = formSetupKey.expires_in * 24 * 3600; // the api expects seconds we have days
return {
id: formSetupKey.id,
name: formSetupKey.name,
@@ -227,26 +222,6 @@ const SetupKeyNew = () => {
return Promise.resolve();
};
const tagRender = (props: CustomTagProps) => {
const { value, closable, onClose } = props;
const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
event.preventDefault();
event.stopPropagation();
};
return (
<Tag
color="blue"
onMouseDown={onPreventMouseDown}
closable={closable}
onClose={onClose}
style={{ marginRight: 3 }}
>
<strong>{value}</strong>
</Tag>
);
};
const dropDownRender = (menu: React.ReactElement) => (
<>
{menu}
@@ -370,8 +345,7 @@ const SetupKeyNew = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
margin: "0px",
fontWeight:"500"
fontWeight: "500",
}}
>
{showPlainToken
@@ -383,6 +357,10 @@ const SetupKeyNew = () => {
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-20px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
}}
>
{showPlainToken
@@ -396,7 +374,6 @@ const SetupKeyNew = () => {
form={form}
onValuesChange={onChange}
initialValues={{
expiresIn: ExpiresInDefault,
usage_limit: 1,
}}
>
@@ -424,7 +401,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "20px" }} justify={"space-between"}>
<Row style={{ marginTop: "24px" }} justify={"space-between"}>
<Col span={18}>
<Paragraph
style={{
@@ -446,6 +423,7 @@ const SetupKeyNew = () => {
<Row justify={"end"}>
<Form.Item name="reusable" valuePropName="checked">
<Switch
size="small"
onChange={(checked) => {
setFormSetupKey({
...formSetupKey,
@@ -458,7 +436,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "10px" }}>
<Row style={{ marginTop: "16px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -496,7 +474,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "20px" }}>
<Row style={{ marginTop: "24px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -510,13 +488,12 @@ const SetupKeyNew = () => {
</Col>
<Col>
<Form.Item
name="expiresIn"
name="expires_in"
rules={[
{ required: true, message: "Please enter expiration date" },
]}
>
<InputNumber
defaultValue={7}
placeholder={`2`}
type="number"
addonAfter=" Days"
@@ -532,7 +509,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "20px" }}>
<Row style={{ marginTop: "24px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -558,7 +535,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)}
@@ -570,7 +547,7 @@ const SetupKeyNew = () => {
</Form.Item>
</Col>
</Row>
<Row style={{ marginTop: "40px", marginBottom: "28px" }}>
<Row style={{ marginTop: "24px", marginBottom: "24px" }}>
<Text type={"secondary"}>
Learn more about
<a
+12 -3
View File
@@ -177,9 +177,18 @@ const AddPATPopup = () => {
</Form.Item>
<Paragraph type={"secondary"} style={{fontSize: "14px", marginTop: "-18px"}}>Should be between 1 and 365 days</Paragraph>
</Col>
<Col span={24}>
<Button icon={<QuestionCircleFilled/>} type="link" target="_blank" disabled={true} style={{marginTop: "20px", marginBottom: "20px"}}
href="https://docs.netbird.io/how-to/access-netbird-public-api">Learn more about personal access tokens</Button>
<Col span={24} style={{marginTop: "15px"}}>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/access-netbird-public-api"
>
{" "}
access tokens
</a>
</Text>
</Col>
</Row>
</Form>}
+11 -10
View File
@@ -343,16 +343,17 @@ const InviteUserPopup = () => {
</Form.Item>
</Col>
<Col span={24}>
<Button
icon={<QuestionCircleFilled />}
type="link"
target="_blank"
disabled={true}
style={{ marginTop: "20px", marginBottom: "20px" }}
href="https://docs.netbird.io/how-to/access-netbird-public-api"
>
Learn more about user
</Button>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/add-users-to-your-network"
>
{" "}
user management
</a>
</Text>
</Col>
</Row>
</Form>
@@ -11,32 +11,45 @@ const {Title, Paragraph, Text} = Typography;
export const DockerTab = () => {
const [steps, setSteps] = useState([
{
key: 1,
title: 'Install Docker',
commands: (
<Button style={{marginTop: "5px"}} type="primary" href="https://docs.docker.com/engine/install/" target="_blank">Official Docker website</Button>
),
copied: false,
showCopyButton: false
} as StepCommand,
{
key: 2,
title: 'Run NetBird container',
commands: formatDockerCommand(),
copied: false,
showCopyButton: false
} as StepCommand,
{
key: 3,
title: "Read docs",
commands: (
<Link href="https://docs.netbird.io/how-to/getting-started#running-net-bird-in-docker" target="_blank">Running NetBird in Docker</Link>
),
copied: false,
showCopyButton: false
} as StepCommand
])
{
key: 1,
title: "Install Docker",
commands: (
<Button
style={{ marginTop: "5px" }}
type="primary"
href="https://docs.docker.com/engine/install/"
target="_blank"
>
Official Docker website
</Button>
),
copied: false,
showCopyButton: false,
} as StepCommand,
{
key: 2,
title: "Run NetBird container",
commands: formatDockerCommand(),
commandsForCopy: formatDockerCommand(),
copied: false,
showCopyButton: false,
} as StepCommand,
{
key: 3,
title: "Read docs",
commands: (
<Link
href="https://docs.netbird.io/how-to/getting-started#running-net-bird-in-docker"
target="_blank"
>
Running NetBird in Docker
</Link>
),
copied: false,
showCopyButton: false,
} as StepCommand,
]);
return (
<div style={{marginTop: 10}}>
@@ -1,28 +1,28 @@
import { useState } from 'react';
import { useState } from "react";
import { Button } from "antd";
import TabSteps from "./TabSteps";
import { StepCommand } from "./types"
import { StepCommand } from "./types";
export const OtherTab = () => {
const [steps, _] = useState([
{
key: 1,
title: "For other installation options check our documentation.",
commands: (
<Button
type="primary"
href={`https://docs.netbird.io/how-to/getting-started#binary-install`}
target="_blank"
>
Documentation
</Button>
),
copied: false,
} as StepCommand,
]);
const [steps, _] = useState([
{
key: 1,
title: 'For other installation options check our documentation.',
commands: (
<Button type="primary" href={`https://docs.netbird.io/how-to/getting-started#binary-install`} target="_blank">
Documentation
</Button>
),
copied: false,
} as StepCommand,
])
return <TabSteps stepsItems={steps} />;
};
return (
<TabSteps stepsItems={steps} />
)
}
export default OtherTab
export default OtherTab;
+200 -125
View File
@@ -1,136 +1,211 @@
import React, {useState} from 'react';
import React, { useState } from "react";
import {Button, Divider, Row, Tooltip, Typography} from "antd";
import { Button, Divider, Row, Tooltip, Typography } from "antd";
import TabSteps from "./TabSteps";
import {StepCommand} from "./types"
import {formatNetBirdUP} from "./common"
import {Collapse} from "antd";
import { StepCommand } from "./types";
import { formatNetBirdUP } from "./common";
import { Collapse } from "antd";
import SyntaxHighlighter from "react-syntax-highlighter";
import {QuestionCircleOutlined} from "@ant-design/icons";
import { QuestionCircleOutlined } from "@ant-design/icons";
import { CheckOutlined, CopyOutlined } from "@ant-design/icons";
import { copyToClipboard } from "../../../../utils/common";
const {Panel} = Collapse;
const { Panel } = Collapse;
const {Text} = Typography;
const { Text } = Typography;
export const LinuxTab = () => {
const [copied, setCopied] = useState(false);
const [quickSteps, setQuickSteps] = useState([
{
key: 1,
title: (
<Row>
<Text>Download and run MacOS installer: </Text>
<Tooltip
title={
<text>
If you don't know what chip your Mac has, you can find out by
clicking on the Apple logo in the top left corner of your screen
and selecting 'About This Mac'. For more information click{" "}
<a
href="https://support.apple.com/en-us/HT211814"
target="_blank"
>
here
</a>
</text>
}
className={"ant-form-item-tooltip"}
>
<QuestionCircleOutlined
style={{
color: "rgba(0, 0, 0, 0.45)",
cursor: "help",
marginLeft: "3px",
}}
/>
</Tooltip>
</Row>
),
commands: (
<Row style={{ paddingTop: "5px" }}>
<Button
style={{ marginRight: "10px" }}
type="primary"
href="https://pkgs.netbird.io/macos/amd64"
>
Download for Intel
</Button>
<Button
style={{ marginRight: "10px" }}
type="default"
href="https://pkgs.netbird.io/macos/arm64"
>
Download for M1 & M2
</Button>
</Row>
),
copied: false,
} as StepCommand,
{
key: 2,
title: 'Click on "Connect" from the NetBird icon in your system tray',
commands: "",
copied: false,
showCopyButton: false,
},
{
key: 3,
title: "Sign up using your email address",
commands: "",
copied: false,
showCopyButton: false,
},
]);
const [quickSteps, setQuickSteps] = useState([
{
key: 1,
title: (
<Row>
<Text>Download and run MacOS installer: </Text>
<Tooltip title={
<text>If you don't know what chip your Mac has, you can find out by clicking on the Apple logo
in the top left corner of your screen and selecting 'About This Mac'. For more information
click <a href="https://support.apple.com/en-us/HT211814" target="_blank">here</a></text>
}
className={"ant-form-item-tooltip"}>
<QuestionCircleOutlined
style={{color: "rgba(0, 0, 0, 0.45)", cursor: "help", marginLeft: "3px"}}/>
</Tooltip>
</Row>
const [steps, setSteps] = useState([
{
key: 1,
title: "Download and install Homebrew",
commands: (
<Button
style={{ marginTop: "5px" }}
type="primary"
href="https://brew.sh/"
target="_blank"
>
Download Brew
</Button>
),
copied: false,
} as StepCommand,
{
key: 2,
title: "Install NetBird:",
commands: [
`# for CLI only`,
`brew install netbirdio/tap/netbird`,
`# for GUI package`,
`brew install --cask netbirdio/tap/netbird-ui`,
].join("\n"),
commandsForCopy: [
`brew install netbirdio/tap/netbird`,
`brew install --cask netbirdio/tap/netbird-ui`,
].join("\n"),
copied: false,
showCopyButton: true,
} as StepCommand,
{
key: 3,
title: "Start NetBird daemon:",
commands: [
`sudo netbird service install`,
`sudo netbird service start`,
].join("\n"),
commandsForCopy: [
`sudo netbird service install`,
`sudo netbird service start`,
].join("\n"),
copied: false,
showCopyButton: true,
} as StepCommand,
{
key: 4,
title: "Run NetBird and log in the browser:",
commands: formatNetBirdUP(),
commandsForCopy: formatNetBirdUP(),
copied: false,
showCopyButton: true,
} as StepCommand,
]);
),
commands: (
<Row style={{paddingTop: "5px"}}>
<Button style={{marginRight: "10px"}} type="primary" href="https://pkgs.netbird.io/macos/amd64">Download
for Intel</Button>
<Button style={{marginRight: "10px"}} type="default" href="https://pkgs.netbird.io/macos/arm64">Download
for M1 & M2</Button>
</Row>
),
copied: false
} as StepCommand,
{
key: 2,
title: 'Click on "Connect" from the NetBird icon in your system tray',
commands: '',
copied: false,
showCopyButton: false
},
{
key: 3,
title: 'Sign up using your email address',
commands: '',
copied: false,
showCopyButton: false
}
])
const [steps, setSteps] = useState([
{
key: 1,
title: 'Download and install Homebrew',
commands: (
<Button style={{marginTop: "5px"}} type="primary" href="https://brew.sh/" target="_blank">Download
Brew</Button>
),
copied: false
} as StepCommand,
{
key: 2,
title: 'Install NetBird:',
commands: [
`# for CLI only`,
`brew install netbirdio/tap/netbird`,
`# for GUI package`,
`brew install --cask netbirdio/tap/netbird-ui`
].join('\n'),
copied: false,
showCopyButton: true
} as StepCommand,
{
key: 3,
title: 'Start NetBird daemon:',
commands: [
`sudo netbird service install`,
`sudo netbird service start`
].join('\n'),
copied: false,
showCopyButton: true
} as StepCommand,
{
key: 4,
title: 'Run NetBird and log in the browser:',
commands: formatNetBirdUP(),
copied: false,
showCopyButton: true
} as StepCommand
])
return (
<div style={{marginTop: 10}}>
<Text style={{fontWeight: "bold"}}>
Install on MacOS
</Text>
<div style={{marginTop: 5, marginBottom: 5}}>
<TabSteps stepsItems={quickSteps}/>
const onCopyClick = () => {
const stringToCopy = "curl -fsSL https://pkgs.netbird.io/install.sh | sh";
copyToClipboard(stringToCopy);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 2000);
};
return (
<div style={{ marginTop: 10 }}>
<Text style={{ fontWeight: "bold" }}>Install on MacOS</Text>
<div style={{ marginTop: 5, marginBottom: 5 }}>
<TabSteps stepsItems={quickSteps} />
</div>
<div style={{ marginTop: 0 }} />
{/*<Divider style={{marginTop: "5px"}} />*/}
<Collapse bordered={false} style={{ backgroundColor: "unset" }}>
<Panel
className="CustomPopupCollapse"
header={<Text strong={true}>Or install via command line</Text>}
key="1"
>
<div style={{ marginLeft: "25px" }}>
<Text style={{ fontWeight: "bold" }}>Install with one command</Text>
<div
style={{
fontSize: ".85em",
marginTop: 5,
marginBottom: 25,
position: "relative",
}}
>
{!copied ? (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CopyOutlined />}
style={{ color: "rgb(107, 114, 128)", top: "0", zIndex: "3" }}
onClick={onCopyClick}
/>
) : (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CheckOutlined />}
style={{ color: "green", top: "0", zIndex: "3" }}
/>
)}
<SyntaxHighlighter language="bash">
curl -fsSL https://pkgs.netbird.io/install.sh | sh
</SyntaxHighlighter>
</div>
<div style={{marginTop: 0}}/>
{/*<Divider style={{marginTop: "5px"}} />*/}
<Collapse bordered={false} style={{backgroundColor: "unset"}}>
<Panel className="CustomPopupCollapse" header={<Text strong={true}>Or install via command line</Text>}
key="1">
<div style={{marginLeft: "25px"}}>
<Text style={{fontWeight: "bold"}}>
Install with one command
</Text>
<div style={{fontSize: ".85em", marginTop: 5, marginBottom: 25}}>
<SyntaxHighlighter language="bash">
curl -fsSL https://pkgs.netbird.io/install.sh | sh
</SyntaxHighlighter>
</div>
<Text style={{fontWeight: "bold"}}>
Or install manually with HomeBrew
</Text>
<div style={{marginTop: 5}}>
<TabSteps stepsItems={steps}/>
</div>
</div>
</Panel>
</Collapse>
</div>
)
}
<Text style={{ fontWeight: "bold" }}>
Or install manually with HomeBrew
</Text>
<div style={{ marginTop: 5 }}>
<TabSteps stepsItems={steps} />
</div>
</div>
</Panel>
</Collapse>
</div>
);
};
export default LinuxTab
export default LinuxTab;
@@ -1,63 +1,89 @@
import "highlight.js/styles/mono-blue.css";
import "highlight.js/lib/languages/bash";
import { StepCommand } from './types'
import SyntaxHighlighter from 'react-syntax-highlighter';
import {
Typography,
Space,
Steps, Button, Popover, StepsProps
} from "antd";
import {copyToClipboard} from "../../../../utils/common";
import {CheckOutlined, CopyOutlined} from "@ant-design/icons";
import React, {useEffect, useState} from "react";
import { StepCommand } from "./types";
import SyntaxHighlighter from "react-syntax-highlighter";
import { Typography, Space, Steps, Button, Popover, StepsProps } from "antd";
import { copyToClipboard } from "../../../../utils/common";
import { CheckOutlined, CopyOutlined } from "@ant-design/icons";
import React, { useEffect, useState } from "react";
const { Step } = Steps;
const {Text} = Typography;
const { Text } = Typography;
type Props = {
stepsItems: Array<StepCommand>
stepsItems: Array<StepCommand>;
};
const TabSteps:React.FC<Props> = ({stepsItems}) => {
const TabSteps: React.FC<Props> = ({ stepsItems }) => {
const [steps, setSteps] = useState(stepsItems);
const [steps, setSteps] = useState(stepsItems)
useEffect(() => setSteps(stepsItems), [stepsItems]);
useEffect(() => setSteps(stepsItems), [stepsItems])
const onCopyClick = (
key: string | number,
commands: React.ReactNode | string,
copied: boolean
) => {
if (!(typeof commands === "string")) return;
copyToClipboard(commands);
const step = steps.find((s) => s.key === key);
if (step) step.copied = copied;
setSteps([...steps]);
const onCopyClick = (key: string | number, commands:React.ReactNode | string, copied: boolean) => {
if (!(typeof commands === 'string')) return
copyToClipboard(commands)
const step = steps.find(s => s.key === key)
if (step) step.copied = copied
setSteps([...steps])
if (copied) {
setTimeout(() => {
onCopyClick(key, commands, false)
}, 2000)
}
if (copied) {
setTimeout(() => {
onCopyClick(key, commands, false);
}, 2000);
}
return (
<Steps direction="vertical" size={"small"}>
{steps.map(c =>
<Step
status={"process"}
key={c.key}
title={<Text>{c.title}</Text>}
description={
<Space className="nb-code" direction="vertical" size="small" style={{display: "flex", fontSize: ".85em"}}>
{ (c.commands && (typeof c.commands === 'string')) ? (
<SyntaxHighlighter language="bash">
{c.commands}
</SyntaxHighlighter>
) : (
c.commands
)}
</Space>
}
/>
)}
</Steps>
)
}
};
return (
<Steps direction="vertical" size={"small"}>
{steps.map((c) => (
<Step
status={"process"}
key={c.key}
title={<Text>{c.title}</Text>}
description={
<Space
className="nb-code"
direction="vertical"
size="small"
style={{ display: "flex", fontSize: ".85em" }}
>
{c.commands && typeof c.commands === "string" ? (
<>
{!c.copied ? (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CopyOutlined />}
style={{ color: "rgb(107, 114, 128)"}}
onClick={() => {
onCopyClick(c.key, c.commandsForCopy, true);
}}
/>
) : (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CheckOutlined />}
style={{ color: "green"}}
/>
)}
<SyntaxHighlighter language="bash">
{c.commands}
</SyntaxHighlighter>
</>
) : (
c.commands
)}
</Space>
}
/>
))}
</Steps>
);
};
export default TabSteps;
export default TabSteps;
@@ -1,68 +1,110 @@
import React, {useState} from 'react';
import {StepCommand} from "./types"
import {formatNetBirdUP} from "./common"
import React, { useState } from "react";
import { StepCommand } from "./types";
import { formatNetBirdUP } from "./common";
import SyntaxHighlighter from "react-syntax-highlighter";
import TabSteps from "./TabSteps";
import {Typography} from "antd";
import { Typography, Button } from "antd";
import { CheckOutlined, CopyOutlined } from "@ant-design/icons";
import { copyToClipboard } from "../../../../utils/common";
const {Title, Paragraph, Text} = Typography;
const { Title, Paragraph, Text } = Typography;
export const UbuntuTab = () => {
const [copied, setCopied] = useState(false);
const [steps, setSteps] = useState([
{
key: 1,
title: 'Add repository',
commands: [
`sudo apt install ca-certificates curl gnupg -y`,
`curl -L https://pkgs.wiretrustee.com/debian/public.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/wiretrustee.gpg`,
`echo 'deb https://pkgs.wiretrustee.com/debian stable main' | sudo tee /etc/apt/sources.list.d/wiretrustee.list`
].join('\n'),
copied: false,
showCopyButton: false
} as StepCommand,
{
key: 2,
title: 'Install NetBird',
commands: [
`sudo apt-get update`,
`# for CLI only`,
`sudo apt-get install netbird`,
`# for GUI package`,
`sudo apt-get install netbird-ui`
].join('\n'),
copied: false,
showCopyButton: false
} as StepCommand,
{
key: 3,
title: 'Run NetBird and log in the browser',
commands: formatNetBirdUP(),
copied: false,
showCopyButton: false
} as StepCommand
])
const [steps, setSteps] = useState([
{
key: 1,
title: "Add repository",
commands: [
`sudo apt install ca-certificates curl gnupg -y`,
`curl -L https://pkgs.wiretrustee.com/debian/public.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/wiretrustee.gpg`,
`echo 'deb https://pkgs.wiretrustee.com/debian stable main' | sudo tee /etc/apt/sources.list.d/wiretrustee.list`,
].join("\n"),
commandsForCopy: [
`sudo apt install ca-certificates curl gnupg -y`,
`curl -L https://pkgs.wiretrustee.com/debian/public.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/wiretrustee.gpg`,
`echo 'deb https://pkgs.wiretrustee.com/debian stable main' | sudo tee /etc/apt/sources.list.d/wiretrustee.list`,
].join("\n"),
copied: false,
showCopyButton: false,
} as StepCommand,
{
key: 2,
title: "Install NetBird",
commands: [
`sudo apt-get update`,
`# for CLI only`,
`sudo apt-get install netbird`,
`# for GUI package`,
`sudo apt-get install netbird-ui`,
].join("\n"),
commandsForCopy: [
`sudo apt-get update`,
`sudo apt-get install netbird`,
`sudo apt-get install netbird-ui`,
].join("\n"),
copied: false,
showCopyButton: false,
} as StepCommand,
{
key: 3,
title: "Run NetBird and log in the browser",
commands: formatNetBirdUP(),
commandsForCopy: formatNetBirdUP(),
copied: false,
showCopyButton: false,
} as StepCommand,
]);
return (
<div style={{marginTop: 10}}>
<Text style={{fontWeight: "bold"}}>
Install with one command
</Text>
<div style={{fontSize: ".85em", marginTop: 5, marginBottom: 25}}>
<SyntaxHighlighter language="bash">
curl -fsSL https://pkgs.netbird.io/install.sh | sh
</SyntaxHighlighter>
</div>
<Text style={{fontWeight: "bold"}}>
Or install manually on Ubuntu
</Text>
<div style={{marginTop: 5}}>
<TabSteps stepsItems={steps}/>
</div>
const onCopyClick = () => {
const stringToCopy = "curl -fsSL https://pkgs.netbird.io/install.sh | sh";
copyToClipboard(stringToCopy);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 2000);
};
</div>
return (
<div style={{ marginTop: 10 }}>
<Text style={{ fontWeight: "bold" }}>Install with one command</Text>
<div
style={{
fontSize: ".85em",
marginTop: 5,
marginBottom: 25,
position: "relative",
}}
>
{!copied ? (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CopyOutlined />}
style={{ color: "rgb(107, 114, 128)", top: "0", zIndex: "3" }}
onClick={onCopyClick}
/>
) : (
<Button
type="text"
size="middle"
className="btn-copy-code peer"
icon={<CheckOutlined />}
style={{ color: "green", top: "0", zIndex: "3" }}
/>
)}
<SyntaxHighlighter language="bash">
curl -fsSL https://pkgs.netbird.io/install.sh | sh
</SyntaxHighlighter>
</div>
<Text style={{ fontWeight: "bold" }}>Or install manually on Ubuntu</Text>
<div style={{ marginTop: 5 }}>
<TabSteps stepsItems={steps} />
</div>
</div>
);
};
)
}
export default UbuntuTab
export default UbuntuTab;
Loaded 20 of 39 files, more files were not shown because too many files have changed in this diff. Show more