Skip to content

Commit 3f6e4c4

Browse files
authored
Add lazy connection setting (#465)
1 parent 0e2661c commit 3f6e4c4

File tree

19 files changed

+232
-35
lines changed

19 files changed

+232
-35
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"ip-cidr": "^3.1.0",
5959
"js-cookie": "^3.0.5",
6060
"lodash": "^4.17.21",
61-
"lucide-react": "^0.479.0",
61+
"lucide-react": "^0.481.0",
6262
"next": "^14.2.28",
6363
"next-themes": "^0.2.1",
6464
"punycode": "^2.3.1",

src/app/(dashboard)/peer/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,19 @@ const PeerGeneralInformation = () => {
157157
* Detect if there are changes in the peer information, if there are changes, then enable the save button.
158158
*/
159159
const { hasChanges, updateRef: updateHasChangedRef } = useHasChanges([
160-
name,
161160
ssh,
162161
selectedGroups,
163162
loginExpiration,
164163
inactivityExpiration,
165164
]);
166165

167-
const updatePeer = async () => {
166+
const updatePeer = async (newName?: string) => {
168167
let batchCall: Promise<any>[] = [];
169168
const groupCalls = getAllGroupCalls();
170169

171170
if (permission.peers.update) {
172171
const updateRequest = update({
173-
name,
172+
name: newName ?? name,
174173
ssh,
175174
loginExpiration,
176175
inactivityExpiration,
@@ -187,7 +186,6 @@ const PeerGeneralInformation = () => {
187186
mutate("/peers/" + peer.id);
188187
mutate("/groups");
189188
updateHasChangedRef([
190-
name,
191189
ssh,
192190
selectedGroups,
193191
loginExpiration,
@@ -229,8 +227,10 @@ const PeerGeneralInformation = () => {
229227
</ModalTrigger>
230228
<EditNameModal
231229
onSuccess={(newName) => {
232-
setName(newName);
233-
setShowEditNameModal(false);
230+
updatePeer(newName).then(() => {
231+
setName(newName);
232+
setShowEditNameModal(false);
233+
});
234234
}}
235235
peer={peer}
236236
initialName={name}

src/app/(dashboard)/settings/page.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
AlertOctagonIcon,
77
FolderGit2Icon,
88
LockIcon,
9+
MonitorSmartphoneIcon,
910
NetworkIcon,
1011
ShieldIcon,
1112
} from "lucide-react";
@@ -16,6 +17,7 @@ import { useLoggedInUser } from "@/contexts/UsersProvider";
1617
import PageContainer from "@/layouts/PageContainer";
1718
import { useAccount } from "@/modules/account/useAccount";
1819
import AuthenticationTab from "@/modules/settings/AuthenticationTab";
20+
import ClientSettingsTab from "@/modules/settings/ClientSettingsTab";
1921
import DangerZoneTab from "@/modules/settings/DangerZoneTab";
2022
import GroupsTab from "@/modules/settings/GroupsTab";
2123
import NetworkSettingsTab from "@/modules/settings/NetworkSettingsTab";
@@ -63,6 +65,10 @@ export default function NetBirdSettings() {
6365
<NetworkIcon size={14} />
6466
Networks
6567
</VerticalTabs.Trigger>
68+
<VerticalTabs.Trigger value="clients">
69+
<MonitorSmartphoneIcon size={14} />
70+
Clients
71+
</VerticalTabs.Trigger>
6672
</>
6773
)}
6874

@@ -77,6 +83,7 @@ export default function NetBirdSettings() {
7783
{account && <PermissionsTab account={account} />}
7884
{account && <GroupsTab account={account} />}
7985
{account && <NetworkSettingsTab account={account} />}
86+
{account && <ClientSettingsTab account={account} />}
8087
{account && <DangerZoneTab account={account} />}
8188
</div>
8289
</RestrictedAccess>

src/components/Badge.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ interface Props extends React.HTMLAttributes<HTMLDivElement>, BadgeVariants {
88
children: React.ReactNode;
99
className?: string;
1010
useHover?: boolean;
11+
disabled?: boolean;
1112
}
1213

1314
const variants = cva("", {
@@ -53,6 +54,7 @@ export default function Badge({
5354
className,
5455
variant = "blue",
5556
useHover = false,
57+
disabled = false,
5658
...props
5759
}: Readonly<Props>) {
5860
return (
@@ -61,6 +63,7 @@ export default function Badge({
6163
"relative z-10 cursor-inherit whitespace-nowrap rounded-md text-[12px] py-1.5 px-3 font-normal flex gap-1.5 items-center justify-center transition-all",
6264
className,
6365
variants({ variant, hover: useHover ? variant : "none" }),
66+
disabled && "cursor-not-allowed opacity-50 select-none",
6467
)}
6568
{...props}
6669
>

src/components/ui/InputDomain.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ type Props = {
1414
onError?: (error: boolean) => void;
1515
error?: string;
1616
disabled?: boolean;
17+
preventLeadingAndTrailingDots?: boolean;
18+
allowWildcard?: boolean;
1719
};
1820
enum ActionType {
1921
ADD = "ADD",
@@ -40,6 +42,8 @@ export default function InputDomain({
4042
onRemove,
4143
onError,
4244
disabled,
45+
preventLeadingAndTrailingDots,
46+
allowWildcard = true,
4347
}: Readonly<Props>) {
4448
const [name, setName] = useState(value?.name || "");
4549

@@ -52,7 +56,11 @@ export default function InputDomain({
5256
if (name == "") {
5357
return "";
5458
}
55-
const valid = validator.isValidDomain(name);
59+
const valid = validator.isValidDomain(name, {
60+
allowOnlyTld: true,
61+
allowWildcard,
62+
preventLeadingAndTrailingDots,
63+
});
5664
if (!valid) {
5765
return "Please enter a valid domain, e.g. example.com or intra.example.com";
5866
}

src/hooks/useRedirect.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ export const useRedirect = (
1616
const intervalRef = useRef<NodeJS.Timeout | null>(null);
1717

1818
useEffect(() => {
19-
// If redirect is disabled or the url is already in the callback urls or the url is the current path then do not redirect
20-
if (!enable || callBackUrls.current.includes(url) || url === currentPath)
21-
return;
19+
// If redirect is disabled or the url is already in the callback urls then do not redirect
20+
if (!enable || callBackUrls.current.includes(url)) return;
2221

2322
const performRedirect = () => {
2423
if (!isRedirecting.current) {

src/interfaces/Account.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ export interface Account {
1919
regular_users_view_blocked: boolean;
2020
routing_peer_dns_resolution_enabled: boolean;
2121
dns_domain: string;
22+
lazy_connection_enabled: boolean;
2223
};
2324
}

src/modules/access-control/table/AccessControlPostureCheckCell.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ import Badge from "@components/Badge";
22
import { IconCirclePlus } from "@tabler/icons-react";
33
import { ShieldCheck } from "lucide-react";
44
import React from "react";
5+
import { usePermissions } from "@/contexts/PermissionsProvider";
56
import { Policy } from "@/interfaces/Policy";
67

78
type Props = {
89
policy: Policy;
910
};
1011
export default function AccessControlPostureCheckCell({ policy }: Props) {
12+
const { permission } = usePermissions();
13+
14+
const isDisabled = !permission.policies.create || !permission.policies.update;
15+
1116
return policy.source_posture_checks &&
1217
policy.source_posture_checks.length > 0 ? (
1318
<div className={"flex"}>
@@ -18,7 +23,14 @@ export default function AccessControlPostureCheckCell({ policy }: Props) {
1823
</div>
1924
) : (
2025
<div className={"flex"}>
21-
<Badge variant={"gray"} useHover={true}>
26+
<Badge
27+
variant={"gray"}
28+
useHover={!isDisabled}
29+
onClick={(e) => {
30+
if (isDisabled) e.stopPropagation();
31+
}}
32+
disabled={isDisabled}
33+
>
2234
<IconCirclePlus size={14} />
2335
Add Posture Check
2436
</Badge>

src/modules/access-control/table/AccessControlTable.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import DataTableRefreshButton from "@components/table/DataTableRefreshButton";
88
import { DataTableRowsPerPage } from "@components/table/DataTableRowsPerPage";
99
import GetStartedTest from "@components/ui/GetStartedTest";
1010
import type { ColumnDef, SortingState } from "@tanstack/react-table";
11+
import { removeAllSpaces } from "@utils/helpers";
1112
import { ExternalLinkIcon, PlusCircle } from "lucide-react";
1213
import { usePathname } from "next/navigation";
1314
import React, { useState } from "react";
@@ -37,16 +38,20 @@ type Props = {
3738

3839
export const AccessControlTableColumns: ColumnDef<Policy>[] = [
3940
{
40-
accessorKey: "name",
41+
id: "name",
42+
accessorFn: (row) => removeAllSpaces(row?.name),
4143
header: ({ column }) => {
4244
return <DataTableHeader column={column}>Name</DataTableHeader>;
4345
},
4446
sortingFn: "text",
47+
filterFn: "fuzzy",
4548
cell: ({ cell }) => <AccessControlNameCell policy={cell.row.original} />,
4649
},
4750
{
48-
accessorKey: "description",
51+
id: "description",
52+
accessorFn: (row) => removeAllSpaces(row?.description),
4953
sortingFn: "text",
54+
filterFn: "fuzzy",
5055
},
5156
{
5257
id: "enabled",

0 commit comments

Comments
 (0)