mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-09-23 00:30:43 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30b858c1bc | ||
|
|
e82b269ff5 | ||
|
|
23a4b79f01 | ||
|
|
cc5a9b1033 | ||
|
|
09ae157be3 | ||
|
|
cb89eeb921 | ||
|
|
79446c0e77 | ||
|
|
1f258e4e2c | ||
|
|
bae95d2e11 | ||
|
|
3d95a826e7 | ||
|
|
d8d13aff01 | ||
|
|
695b571a50 | ||
|
|
ddfb6a6179 | ||
|
|
8c94119c6a |
No files matched your search
+1
-1
@@ -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
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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}
|
||||
|
||||
@@ -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
+153
-220
File diff suppressed because it is too large.
Load diff
@@ -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}
|
||||
>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>}
|
||||
|
||||
@@ -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;
|
||||
@@ -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
Reference in new issue
Block a user