mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-09-23 00:30:43 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3d4dcb567 | ||
|
|
57e71a330e | ||
|
|
2b7b5875d2 |
No files matched your search
Generated
-347
@@ -14,7 +14,6 @@
|
||||
"@radix-ui/react-collapsible": "^1.0.3",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
"@radix-ui/react-hover-card": "^1.1.4",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-radio-group": "^1.1.3",
|
||||
@@ -922,352 +921,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.4.tgz",
|
||||
"integrity": "sha512-QSUUnRA3PQ2UhvoCv3eYvMnCAgGQW+sTu86QPuNb+ZMi+ZENd6UWpiXbcWDQ4AEaKF9KKpCHBeaJz9Rw6lRlaQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.3",
|
||||
"@radix-ui/react-popper": "1.2.1",
|
||||
"@radix-ui/react-portal": "1.1.3",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/primitive": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
|
||||
"integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-arrow": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz",
|
||||
"integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-primitive": "2.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-compose-refs": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
|
||||
"integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-context": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
|
||||
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-dismissable-layer": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz",
|
||||
"integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-escape-keydown": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz",
|
||||
"integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.0.0",
|
||||
"@radix-ui/react-arrow": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0",
|
||||
"@radix-ui/react-use-rect": "1.1.0",
|
||||
"@radix-ui/react-use-size": "1.1.0",
|
||||
"@radix-ui/rect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-portal": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz",
|
||||
"integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
|
||||
"integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-primitive": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz",
|
||||
"integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-slot": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
|
||||
"integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-callback-ref": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
|
||||
"integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-controllable-state": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
|
||||
"integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-escape-keydown": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
|
||||
"integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-layout-effect": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
|
||||
"integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-rect": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
|
||||
"integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/rect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-size": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
|
||||
"integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/rect": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
|
||||
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-id": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
"@radix-ui/react-collapsible": "^1.0.3",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
"@radix-ui/react-hover-card": "^1.1.4",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-radio-group": "^1.1.3",
|
||||
|
||||
@@ -14,6 +14,7 @@ import PeersProvider from "@/contexts/PeersProvider";
|
||||
import RoutesProvider from "@/contexts/RoutesProvider";
|
||||
import { Route } from "@/interfaces/Route";
|
||||
import PageContainer from "@/layouts/PageContainer";
|
||||
import { NetworkRoutesDeprecationInfo } from "@/modules/networks/misc/NetworkRoutesDeprecationInfo";
|
||||
import useGroupedRoutes from "@/modules/route-group/useGroupedRoutes";
|
||||
|
||||
const NetworkRoutesTable = lazy(
|
||||
@@ -39,7 +40,9 @@ export default function NetworkRoutes() {
|
||||
icon={<NetworkRoutesIcon size={13} />}
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
<h1 ref={headingRef}>Network Routes</h1>
|
||||
<h1 ref={headingRef}>
|
||||
Network Routes <NetworkRoutesDeprecationInfo size={18} />
|
||||
</h1>
|
||||
<Paragraph>
|
||||
Network routes allow you to access other networks like LANs and
|
||||
VPCs without installing NetBird on every resource.
|
||||
|
||||
@@ -31,15 +31,12 @@ export default function Networks() {
|
||||
</Breadcrumbs>
|
||||
<h1 ref={headingRef}>Networks</h1>
|
||||
<Paragraph>
|
||||
Networks allow you to access internal resources in LANs and VPCs without
|
||||
installing NetBird on every machine.
|
||||
Networks allow you to access other resources like LANs and VPCs
|
||||
without installing NetBird on every device.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
Learn more about
|
||||
<InlineLink
|
||||
href={"https://docs.netbird.io/how-to/networks"}
|
||||
target={"_blank"}
|
||||
>
|
||||
<InlineLink href={"https://docs.netbird.io/how-to/networks"} target={"_blank"}>
|
||||
Networks
|
||||
<ExternalLinkIcon size={12} />
|
||||
</InlineLink>
|
||||
|
||||
@@ -316,7 +316,6 @@ function UserInformationCard({ user }: { user: User }) {
|
||||
<>
|
||||
{!user.is_current && user.role != Role.Owner && (
|
||||
<Card.ListItem
|
||||
tooltip={false}
|
||||
label={
|
||||
<>
|
||||
<Ban size={16} />
|
||||
|
||||
@@ -30,7 +30,7 @@ import * as React from "react";
|
||||
import { Fragment, useEffect, useMemo, useState } from "react";
|
||||
import { useGroups } from "@/contexts/GroupsProvider";
|
||||
import { useElementSize } from "@/hooks/useElementSize";
|
||||
import type { Group, GroupPeer, GroupResource } from "@/interfaces/Group";
|
||||
import type {Group, GroupPeer, GroupResource} from "@/interfaces/Group";
|
||||
import { NetworkResource } from "@/interfaces/Network";
|
||||
import type { Peer } from "@/interfaces/Peer";
|
||||
|
||||
@@ -48,7 +48,6 @@ interface MultiSelectProps {
|
||||
showRoutes?: boolean;
|
||||
disabledGroups?: Group[];
|
||||
dataCy?: string;
|
||||
showResourceCounter?: boolean;
|
||||
}
|
||||
export function PeerGroupSelector({
|
||||
onChange,
|
||||
@@ -64,7 +63,6 @@ export function PeerGroupSelector({
|
||||
showRoutes = false,
|
||||
disabledGroups,
|
||||
dataCy = "group-selector-dropdown",
|
||||
showResourceCounter = true,
|
||||
}: Readonly<MultiSelectProps>) {
|
||||
const { groups, dropdownOptions, setDropdownOptions, addDropdownOptions } =
|
||||
useGroups();
|
||||
@@ -107,34 +105,20 @@ export function PeerGroupSelector({
|
||||
const groupPeers: GroupPeer[] | undefined =
|
||||
(group?.peers as GroupPeer[]) || [];
|
||||
const groupResources: GroupResource[] | undefined =
|
||||
(group?.resources as GroupResource[]) || [];
|
||||
(group?.resources as GroupResource[]) || [];
|
||||
|
||||
if (peer) groupPeers?.push({ id: peer?.id as string, name: peer?.name });
|
||||
|
||||
if (!group && !option) {
|
||||
addDropdownOptions([
|
||||
{ name: name, peers: groupPeers, resources: groupResources },
|
||||
]);
|
||||
addDropdownOptions([{ name: name, peers: groupPeers, resources: groupResources }]);
|
||||
}
|
||||
|
||||
if (max == 1 && values.length == 1) {
|
||||
onChange([
|
||||
{
|
||||
name: name,
|
||||
id: group?.id,
|
||||
peers: groupPeers,
|
||||
resources: groupResources,
|
||||
},
|
||||
]);
|
||||
onChange([{ name: name, id: group?.id, peers: groupPeers, resources: groupResources }]);
|
||||
} else {
|
||||
onChange((previous) => [
|
||||
...previous,
|
||||
{
|
||||
name: name,
|
||||
id: group?.id,
|
||||
peers: groupPeers,
|
||||
resources: groupResources,
|
||||
},
|
||||
{ name: name, id: group?.id, peers: groupPeers, resources: groupResources },
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -412,9 +396,7 @@ export function PeerGroupSelector({
|
||||
<AccessControlGroupCount group_id={option.id} />
|
||||
)}
|
||||
|
||||
{showResourceCounter && (
|
||||
<ResourcesCounter group={option} />
|
||||
)}
|
||||
<ResourcesCounter group={option} />
|
||||
|
||||
<div
|
||||
className={
|
||||
|
||||
@@ -166,17 +166,15 @@ export function PeerSelector({
|
||||
placeholder={"Search for peers by name or ip..."}
|
||||
/>
|
||||
|
||||
{unfilteredItems.length == 0 && !search && (
|
||||
<div className={"max-w-xs mx-auto"}>
|
||||
<DropdownInfoText>
|
||||
{
|
||||
"Seems like you don't have any Linux peers to assign as a routing peer."
|
||||
}
|
||||
</DropdownInfoText>
|
||||
</div>
|
||||
{unfilteredItems.length == 0 && (
|
||||
<DropdownInfoText>
|
||||
{
|
||||
"Seems like you don't have any linux peers to assign as a routing peer."
|
||||
}
|
||||
</DropdownInfoText>
|
||||
)}
|
||||
|
||||
{filteredItems.length == 0 && search != "" && (
|
||||
{filteredItems.length == 0 && (
|
||||
<DropdownInfoText>
|
||||
There are no peers matching your search.
|
||||
</DropdownInfoText>
|
||||
|
||||
@@ -60,12 +60,10 @@ export default function SidebarItem({
|
||||
<li className={"px-4 cursor-pointer"}>
|
||||
<button
|
||||
className={classNames(
|
||||
"rounded-lg text-[.87rem] w-full ",
|
||||
"rounded-lg text-[.95rem] w-full ",
|
||||
"font-normal ",
|
||||
className,
|
||||
isChild
|
||||
? "pl-7 pr-2 py-[.45rem] mt-1 mb-0.5"
|
||||
: "py-[.45rem] px-3",
|
||||
isChild ? "pl-7 pr-2 py-2 mt-1 mb-0.5" : "py-2 px-3",
|
||||
isActive
|
||||
? "text-gray-900 bg-gray-200 dark:text-white dark:bg-nb-gray-900"
|
||||
: "text-gray-600 hover:bg-gray-200 dark:text-nb-gray-400 dark:hover:bg-nb-gray-900/50",
|
||||
|
||||
@@ -4,18 +4,9 @@ import React from "react";
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
horizontal?: boolean;
|
||||
};
|
||||
export default function Steps({
|
||||
children,
|
||||
className,
|
||||
horizontal = false,
|
||||
}: Readonly<Props>) {
|
||||
return (
|
||||
<div className={cn("pt-4", horizontal && "flex", className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
export default function Steps({ children, className }: Props) {
|
||||
return <div className={cn("pt-4", className)}>{children}</div>;
|
||||
}
|
||||
|
||||
type StepProps = {
|
||||
@@ -23,32 +14,21 @@ type StepProps = {
|
||||
step: number;
|
||||
line?: boolean;
|
||||
center?: boolean;
|
||||
horizontal?: boolean;
|
||||
};
|
||||
|
||||
const Step = ({
|
||||
children,
|
||||
step,
|
||||
line = true,
|
||||
center = false,
|
||||
horizontal,
|
||||
}: StepProps) => {
|
||||
const Step = ({ children, step, line = true, center = false }: StepProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex gap-4 items-start justify-start relative pb-6 -mx-1.5 group px-[2px]",
|
||||
"flex gap-4 items-start min-w-full justify-start relative pb-6 -mx-1.5 group px-[2px]",
|
||||
center && "items-center",
|
||||
horizontal ? "flex-col items-center" : "min-w-full",
|
||||
)}
|
||||
>
|
||||
{line && (
|
||||
<span
|
||||
className={cn(
|
||||
"bg-nb-gray-100 dark:bg-nb-gray-800 z-0 transition-all",
|
||||
horizontal
|
||||
? "w-full h-[2px] absolute mt-[16px] transform translate-x-1/2"
|
||||
: "h-full w-[2px] absolute left-0 ml-[18px]",
|
||||
)}
|
||||
className={
|
||||
"h-full w-[2px] bg-nb-gray-100 dark:bg-nb-gray-800 absolute left-0 ml-[18px] z-0 transition-all"
|
||||
}
|
||||
></span>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Badge from "@components/Badge";
|
||||
import { NewBadge } from "@components/ui/NewBadge";
|
||||
import TruncatedText from "@components/ui/TruncatedText";
|
||||
import TextWithTooltip from "@components/ui/TextWithTooltip";
|
||||
import { cn } from "@utils/helpers";
|
||||
import { FolderGit2, XIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
@@ -38,9 +37,18 @@ export default function GroupBadge({
|
||||
>
|
||||
<FolderGit2 size={12} className={"shrink-0"} />
|
||||
|
||||
<TruncatedText text={group?.name || ""} maxChars={20} />
|
||||
<TextWithTooltip text={group?.name || ""} maxChars={20} />
|
||||
{children}
|
||||
{isNew && showNewBadge && <NewBadge />}
|
||||
{isNew && showNewBadge && (
|
||||
<span
|
||||
className={
|
||||
"text-[7px] relative top-[.25px] leading-[0] bg-green-900 border border-green-500/20 py-1.5 px-1 rounded-[3px] text-green-400"
|
||||
}
|
||||
>
|
||||
NEW
|
||||
</span>
|
||||
)}
|
||||
|
||||
{showX && (
|
||||
<XIcon
|
||||
size={12}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
type Props = {
|
||||
text?: string;
|
||||
};
|
||||
export const NewBadge = ({ text = "NEW" }: Props) => {
|
||||
return (
|
||||
<span
|
||||
className={
|
||||
"text-[7px] relative top-[.25px] leading-[0] bg-green-900 border border-green-500/20 py-1.5 px-1 rounded-[3px] text-green-400"
|
||||
}
|
||||
>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
@@ -1,78 +0,0 @@
|
||||
import * as HoverCard from "@radix-ui/react-hover-card";
|
||||
import { cn } from "@utils/helpers";
|
||||
import React, { useMemo, useState } from "react";
|
||||
|
||||
type Props = {
|
||||
text?: string;
|
||||
className?: string;
|
||||
maxChars?: number;
|
||||
hideTooltip?: boolean;
|
||||
};
|
||||
|
||||
export default function TruncatedText({
|
||||
text,
|
||||
className,
|
||||
maxChars = 40,
|
||||
hideTooltip = false,
|
||||
}: Props) {
|
||||
const charCount = useMemo(() => {
|
||||
if (!text) return 0;
|
||||
return text.length;
|
||||
}, [text]);
|
||||
|
||||
const isDisabled = charCount <= maxChars || hideTooltip;
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
if (isDisabled) {
|
||||
return (
|
||||
<div
|
||||
className={"w-full min-w-0 inline-block"}
|
||||
style={{
|
||||
maxWidth: `${maxChars - 2}ch`,
|
||||
}}
|
||||
>
|
||||
<div className={cn(className, "truncate")}>{text}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<HoverCard.Root
|
||||
openDelay={650}
|
||||
closeDelay={100}
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
>
|
||||
<HoverCard.Trigger asChild={true}>
|
||||
<div
|
||||
className={"w-full min-w-0 inline-block"}
|
||||
style={{
|
||||
maxWidth: `${maxChars - 2}ch`,
|
||||
}}
|
||||
>
|
||||
<div className={cn(className, "truncate")}>{text}</div>
|
||||
</div>
|
||||
</HoverCard.Trigger>
|
||||
<HoverCard.Portal>
|
||||
<HoverCard.Content
|
||||
onMouseLeave={() => setOpen(false)}
|
||||
onMouseEnter={() => setOpen(false)}
|
||||
alignOffset={20}
|
||||
sideOffset={4}
|
||||
className={cn(
|
||||
"z-[9999] overflow-hidden rounded-md border border-neutral-200 bg-white text-sm text-neutral-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-nb-gray-930 dark:bg-nb-gray-940 dark:text-neutral-50",
|
||||
className,
|
||||
"px-3 py-1.5",
|
||||
)}
|
||||
>
|
||||
<div className={"text-neutral-300 flex flex-col gap-1"}>
|
||||
<div className={"max-w-xs break-all whitespace-normal text-xs"}>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
</HoverCard.Content>
|
||||
</HoverCard.Portal>
|
||||
</HoverCard.Root>
|
||||
);
|
||||
}
|
||||
@@ -16,7 +16,6 @@ export interface NetworkRouter {
|
||||
peer_groups?: string[];
|
||||
metric: number;
|
||||
masquerade: boolean;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface NetworkResource {
|
||||
@@ -26,5 +25,4 @@ export interface NetworkResource {
|
||||
address: string;
|
||||
groups?: string[] | Group[];
|
||||
type?: "domain" | "host" | "subnet";
|
||||
enabled: boolean;
|
||||
}
|
||||
@@ -281,7 +281,6 @@ export function AccessControlModalContent({
|
||||
onChange={setSourceGroups}
|
||||
values={sourceGroups}
|
||||
saveGroupAssignments={useSave}
|
||||
showResourceCounter={false}
|
||||
/>
|
||||
</div>
|
||||
<PolicyDirection
|
||||
@@ -392,7 +391,9 @@ export function AccessControlModalContent({
|
||||
<Paragraph className={"text-sm mt-auto"}>
|
||||
Learn more about
|
||||
<InlineLink
|
||||
href={"https://docs.netbird.io/how-to/manage-network-access"}
|
||||
href={
|
||||
"https://docs.netbird.io/how-to/manage-network-access"
|
||||
}
|
||||
target={"_blank"}
|
||||
>
|
||||
Access Controls
|
||||
|
||||
@@ -37,22 +37,6 @@ const ActivityFeedColumnsTable: ColumnDef<ActivityEvent>[] = [
|
||||
filterFn: "arrIncludesSomeExact",
|
||||
cell: ({ row }) => <ActivityEntryRow event={row.original} />,
|
||||
},
|
||||
{
|
||||
id: "activity_text",
|
||||
accessorFn: (event) => {
|
||||
try {
|
||||
if (event.meta) {
|
||||
return Object.keys(event.meta)
|
||||
.map((key) => {
|
||||
return `${event?.meta[key]}`;
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
} catch (error) {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "timestamp",
|
||||
id: "timestamp",
|
||||
@@ -119,7 +103,6 @@ export default function ActivityTable({
|
||||
columnVisibility={{
|
||||
timestamp: false,
|
||||
name: false,
|
||||
activity_text: false,
|
||||
initiator_email: false,
|
||||
}}
|
||||
getStartedCard={
|
||||
|
||||
@@ -10,7 +10,6 @@ import { Network, NetworkResource, NetworkRouter } from "@/interfaces/Network";
|
||||
import { AccessControlModalContent } from "@/modules/access-control/AccessControlModal";
|
||||
import NetworkModal from "@/modules/networks/NetworkModal";
|
||||
import NetworkResourceModal from "@/modules/networks/resources/NetworkResourceModal";
|
||||
import { ResourceGroupModal } from "@/modules/networks/resources/ResourceGroupModal";
|
||||
import NetworkRoutingPeerModal from "@/modules/networks/routing-peers/NetworkRoutingPeerModal";
|
||||
|
||||
type Props = {
|
||||
@@ -24,10 +23,6 @@ const NetworksContext = React.createContext(
|
||||
openEditNetworkModal: (network: Network) => void;
|
||||
openCreateNetworkModal: () => void;
|
||||
openResourceModal: (network: Network, resource?: NetworkResource) => void;
|
||||
openResourceGroupModal: (
|
||||
network: Network,
|
||||
resource?: NetworkResource,
|
||||
) => void;
|
||||
openPolicyModal: (network?: Network, resource?: NetworkResource) => void;
|
||||
deleteNetwork: (network: Network) => void;
|
||||
deleteResource: (network: Network, resource: NetworkResource) => void;
|
||||
@@ -54,7 +49,6 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
const [routingPeerModal, setRoutingPeerModal] = useState(false);
|
||||
const [networkModal, setNetworkModal] = useState(false);
|
||||
const [resourceModal, setResourceModal] = useState(false);
|
||||
const [resourceGroupModal, setResourceGroupModal] = useState(false);
|
||||
const [policyModal, setPolicyModal] = useState(false);
|
||||
|
||||
const openAddRoutingPeerModal = (
|
||||
@@ -82,15 +76,6 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
setResourceModal(true);
|
||||
};
|
||||
|
||||
const openResourceGroupModal = (
|
||||
network: Network,
|
||||
resource?: NetworkResource,
|
||||
) => {
|
||||
setCurrentNetwork(network);
|
||||
resource && setCurrentResource(resource);
|
||||
setResourceGroupModal(true);
|
||||
};
|
||||
|
||||
const openPolicyModal = (network?: Network, resource?: NetworkResource) => {
|
||||
setPolicyDefaultSettings({
|
||||
destinationGroups: resource?.groups,
|
||||
@@ -232,7 +217,6 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
openEditNetworkModal,
|
||||
openCreateNetworkModal,
|
||||
openResourceModal,
|
||||
openResourceGroupModal,
|
||||
openPolicyModal,
|
||||
deleteNetwork,
|
||||
deleteResource,
|
||||
@@ -248,7 +232,7 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
network={currentNetwork}
|
||||
onCreated={async (network) => {
|
||||
mutate("/networks");
|
||||
await askForResource(network);
|
||||
await askForRoutingPeer(network);
|
||||
}}
|
||||
onUpdated={() => {
|
||||
mutate("/networks");
|
||||
@@ -266,15 +250,13 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
initialDestinationGroups={policyDefaultSettings?.destinationGroups}
|
||||
initialName={policyDefaultSettings?.name}
|
||||
initialDescription={policyDefaultSettings?.description}
|
||||
onSuccess={async (p) => {
|
||||
onSuccess={(p) => {
|
||||
setPolicyModal(false);
|
||||
setPolicyDefaultSettings(undefined);
|
||||
mutate("/networks");
|
||||
if (network) {
|
||||
mutate(`/networks/${network.id}/resources`);
|
||||
mutate(`/networks/${network.id}`);
|
||||
} else {
|
||||
currentNetwork && (await askForRoutingPeer(currentNetwork));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -293,6 +275,8 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
if (network) {
|
||||
mutate(`/networks/${currentNetwork.id}/routers`);
|
||||
mutate(`/networks/${network.id}`);
|
||||
} else {
|
||||
await askForResource(currentNetwork);
|
||||
}
|
||||
}}
|
||||
onUpdated={async () => {
|
||||
@@ -310,26 +294,6 @@ export const NetworkProvider = ({ children, network }: Props) => {
|
||||
setRoutingPeerModal(state);
|
||||
}}
|
||||
/>
|
||||
|
||||
<ResourceGroupModal
|
||||
network={currentNetwork}
|
||||
resource={currentResource}
|
||||
open={resourceGroupModal}
|
||||
onOpenChange={(state) => {
|
||||
setCurrentResource(undefined);
|
||||
setResourceGroupModal(state);
|
||||
}}
|
||||
onUpdated={() => {
|
||||
setResourceGroupModal(false);
|
||||
setCurrentResource(undefined);
|
||||
mutate("/groups");
|
||||
if (network) {
|
||||
mutate(`/networks/${network.id}/resources`);
|
||||
mutate(`/networks/${network.id}`);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<NetworkResourceModal
|
||||
network={currentNetwork}
|
||||
resource={currentResource}
|
||||
|
||||
@@ -60,7 +60,10 @@ export const NetworkInformationSquare = ({
|
||||
{name}
|
||||
</p>
|
||||
<DescriptionWithTooltip
|
||||
className={cn("text-left", size == "lg" && "text-md mt-0.5")}
|
||||
className={cn(
|
||||
"text-left",
|
||||
size == "lg" && "text-md leading-none mt-0.5",
|
||||
)}
|
||||
maxChars={24}
|
||||
text={description}
|
||||
/>
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
import SidebarItem from "@components/SidebarItem";
|
||||
import { NewBadge } from "@components/ui/NewBadge";
|
||||
import * as React from "react";
|
||||
import NetworkRoutesIcon from "@/assets/icons/NetworkRoutesIcon";
|
||||
import { NetworkRoutesDeprecationInfo } from "@/modules/networks/misc/NetworkRoutesDeprecationInfo";
|
||||
|
||||
export const NetworkNavigation = () => {
|
||||
return (
|
||||
<>
|
||||
<SidebarItem
|
||||
icon={<NetworkRoutesIcon />}
|
||||
label="Networks"
|
||||
collapsible
|
||||
exactPathMatch={false}
|
||||
>
|
||||
<SidebarItem label="Networks" isChild href={"/networks"} />
|
||||
<SidebarItem
|
||||
icon={<NetworkRoutesIcon />}
|
||||
label={
|
||||
<div className={"flex items-center gap-2"}>
|
||||
Networks
|
||||
<NewBadge />
|
||||
<div className={"flex items-center"}>
|
||||
Network Routes
|
||||
<NetworkRoutesDeprecationInfo />
|
||||
</div>
|
||||
}
|
||||
href={"/networks"}
|
||||
/>
|
||||
<SidebarItem
|
||||
icon={<NetworkRoutesIcon />}
|
||||
isChild
|
||||
href={"/network-routes"}
|
||||
label={"Network Routes"}
|
||||
/>
|
||||
</>
|
||||
</SidebarItem>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import Button from "@components/Button";
|
||||
import FancyToggleSwitch from "@components/FancyToggleSwitch";
|
||||
import HelpText from "@components/HelpText";
|
||||
import InlineLink from "@components/InlineLink";
|
||||
import { Input } from "@components/Input";
|
||||
@@ -18,12 +17,7 @@ import Paragraph from "@components/Paragraph";
|
||||
import { PeerGroupSelector } from "@components/PeerGroupSelector";
|
||||
import Separator from "@components/Separator";
|
||||
import { useApiCall } from "@utils/api";
|
||||
import {
|
||||
ExternalLinkIcon,
|
||||
PlusCircle,
|
||||
Power,
|
||||
WorkflowIcon,
|
||||
} from "lucide-react";
|
||||
import { ExternalLinkIcon, PlusCircle, WorkflowIcon } from "lucide-react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { Network, NetworkResource } from "@/interfaces/Network";
|
||||
import useGroupHelper from "@/modules/groups/useGroupHelper";
|
||||
@@ -85,9 +79,6 @@ export function ResourceModalContent({
|
||||
const [groups, setGroups, { save: saveGroups }] = useGroupHelper({
|
||||
initial: resource?.groups || [],
|
||||
});
|
||||
const [enabled, setEnabled] = useState<boolean>(
|
||||
resource ? resource.enabled : true,
|
||||
);
|
||||
|
||||
const createResource = async () => {
|
||||
const savedGroups = await saveGroups();
|
||||
@@ -100,7 +91,6 @@ export function ResourceModalContent({
|
||||
description,
|
||||
address,
|
||||
groups: savedGroups.map((g) => g.id),
|
||||
enabled,
|
||||
}).then((r) => {
|
||||
onCreated?.(r);
|
||||
}),
|
||||
@@ -118,7 +108,6 @@ export function ResourceModalContent({
|
||||
description,
|
||||
address,
|
||||
groups: savedGroups.map((g) => g.id),
|
||||
enabled,
|
||||
}).then((r) => {
|
||||
onUpdated?.(r);
|
||||
}),
|
||||
@@ -162,34 +151,17 @@ export function ResourceModalContent({
|
||||
<div>
|
||||
<Label>Assigned Groups</Label>
|
||||
<HelpText>
|
||||
Add this resource to groups and use them as destinations when
|
||||
creating policies
|
||||
Control access to this resource by assigning it to groups
|
||||
</HelpText>
|
||||
<PeerGroupSelector onChange={setGroups} values={groups} />
|
||||
</div>
|
||||
<div className={"mt-3"}>
|
||||
<FancyToggleSwitch
|
||||
value={enabled}
|
||||
onChange={setEnabled}
|
||||
label={
|
||||
<>
|
||||
<Power size={15} />
|
||||
Enable Resource
|
||||
</>
|
||||
}
|
||||
helpText={"Use this switch to enable or disable the resource."}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ModalFooter className={"items-center"}>
|
||||
<div className={"w-full"}>
|
||||
<Paragraph className={"text-sm mt-auto"}>
|
||||
Learn more about
|
||||
<InlineLink
|
||||
href={"https://docs.netbird.io/how-to/networks#resources"}
|
||||
target={"_blank"}
|
||||
>
|
||||
<InlineLink href={"https://docs.netbird.io/how-to/networks#resources"} target={"_blank"}>
|
||||
Resources
|
||||
<ExternalLinkIcon size={12} />
|
||||
</InlineLink>
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import Button from "@components/Button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@components/DropdownMenu";
|
||||
import { MoreVertical, SquarePenIcon, Trash2 } from "lucide-react";
|
||||
import { SquarePenIcon, Trash2 } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { NetworkResource } from "@/interfaces/Network";
|
||||
import { useNetworksContext } from "@/modules/networks/NetworkProvider";
|
||||
@@ -17,45 +11,29 @@ export const ResourceActionCell = ({ resource }: Props) => {
|
||||
const { deleteResource, network, openResourceModal } = useNetworksContext();
|
||||
|
||||
return (
|
||||
<div className={"flex justify-end"}>
|
||||
<DropdownMenu modal={false}>
|
||||
<DropdownMenuTrigger
|
||||
asChild={true}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<Button variant={"secondary"} className={"!px-3"}>
|
||||
<MoreVertical size={16} className={"shrink-0"} />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-auto" align="end">
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!network) return;
|
||||
openResourceModal(network, resource);
|
||||
}}
|
||||
>
|
||||
<div className={"flex gap-3 items-center"}>
|
||||
<SquarePenIcon size={14} className={"shrink-0"} />
|
||||
Edit
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!network) return;
|
||||
deleteResource(network, resource);
|
||||
}}
|
||||
variant={"danger"}
|
||||
>
|
||||
<div className={"flex gap-3 items-center"}>
|
||||
<Trash2 size={14} className={"shrink-0"} />
|
||||
Remove
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<div className={"flex justify-end pr-4"}>
|
||||
<Button
|
||||
variant={"default-outline"}
|
||||
size={"sm"}
|
||||
onClick={() => {
|
||||
if (!network) return;
|
||||
openResourceModal(network, resource);
|
||||
}}
|
||||
>
|
||||
<SquarePenIcon size={16} />
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
variant={"danger-outline"}
|
||||
size={"sm"}
|
||||
onClick={() => {
|
||||
if (!network) return;
|
||||
deleteResource(network, resource);
|
||||
}}
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
Remove
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loaded 20 of 42 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user