mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-07 03:06:40 +00:00
add agent to table
This commit is contained in:
@@ -2269,5 +2269,6 @@
|
|||||||
"remoteExitNodeRegenerateAndDisconnectConfirmation": "Are you sure you want to regenerate the credentials and disconnect this remote exit node?",
|
"remoteExitNodeRegenerateAndDisconnectConfirmation": "Are you sure you want to regenerate the credentials and disconnect this remote exit node?",
|
||||||
"remoteExitNodeRegenerateAndDisconnectWarning": "This will regenerate the credentials and immediately disconnect the remote exit node. The remote exit node will need to be restarted with the new credentials.",
|
"remoteExitNodeRegenerateAndDisconnectWarning": "This will regenerate the credentials and immediately disconnect the remote exit node. The remote exit node will need to be restarted with the new credentials.",
|
||||||
"remoteExitNodeRegenerateCredentialsConfirmation": "Are you sure you want to regenerate the credentials for this remote exit node?",
|
"remoteExitNodeRegenerateCredentialsConfirmation": "Are you sure you want to regenerate the credentials for this remote exit node?",
|
||||||
"remoteExitNodeRegenerateCredentialsWarning": "This will regenerate the credentials. The remote exit node will stay connected until you manually restart it and use the new credentials."
|
"remoteExitNodeRegenerateCredentialsWarning": "This will regenerate the credentials. The remote exit node will stay connected until you manually restart it and use the new credentials.",
|
||||||
|
"agent": "Agent"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { getNextAvailableClientSubnet } from "@server/lib/ip";
|
|||||||
import logger from "@server/logger";
|
import logger from "@server/logger";
|
||||||
import { rebuildClientAssociationsFromClient } from "./rebuildClientAssociations";
|
import { rebuildClientAssociationsFromClient } from "./rebuildClientAssociations";
|
||||||
import { sendTerminateClient } from "@server/routers/client/terminate";
|
import { sendTerminateClient } from "@server/routers/client/terminate";
|
||||||
|
import { getUniqueClientName } from "@server/db/names";
|
||||||
|
|
||||||
export async function calculateUserClientsForOrgs(
|
export async function calculateUserClientsForOrgs(
|
||||||
userId: string,
|
userId: string,
|
||||||
@@ -176,6 +177,8 @@ export async function calculateUserClientsForOrgs(
|
|||||||
const subnet = newSubnet.split("/")[0];
|
const subnet = newSubnet.split("/")[0];
|
||||||
const updatedSubnet = `${subnet}/${org.subnet.split("/")[1]}`;
|
const updatedSubnet = `${subnet}/${org.subnet.split("/")[1]}`;
|
||||||
|
|
||||||
|
const niceId = await getUniqueClientName(orgId);
|
||||||
|
|
||||||
// Create the client
|
// Create the client
|
||||||
const [newClient] = await transaction
|
const [newClient] = await transaction
|
||||||
.insert(clients)
|
.insert(clients)
|
||||||
@@ -186,7 +189,8 @@ export async function calculateUserClientsForOrgs(
|
|||||||
name: olm.name || "User Client",
|
name: olm.name || "User Client",
|
||||||
subnet: updatedSubnet,
|
subnet: updatedSubnet,
|
||||||
olmId: olm.olmId,
|
olmId: olm.olmId,
|
||||||
type: "olm"
|
type: "olm",
|
||||||
|
niceId
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ function queryClients(orgId: string, accessibleClientIds: number[], filter?: "us
|
|||||||
userId: clients.userId,
|
userId: clients.userId,
|
||||||
username: users.username,
|
username: users.username,
|
||||||
userEmail: users.email,
|
userEmail: users.email,
|
||||||
niceId: clients.niceId
|
niceId: clients.niceId,
|
||||||
|
agent: olms.agent
|
||||||
})
|
})
|
||||||
.from(clients)
|
.from(clients)
|
||||||
.leftJoin(orgs, eq(clients.orgId, orgs.orgId))
|
.leftJoin(orgs, eq(clients.orgId, orgs.orgId))
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ export default async function ClientsPage(props: ClientsPageProps) {
|
|||||||
userId: client.userId,
|
userId: client.userId,
|
||||||
username: client.username,
|
username: client.username,
|
||||||
userEmail: client.userEmail,
|
userEmail: client.userEmail,
|
||||||
niceId: client.niceId
|
niceId: client.niceId,
|
||||||
|
agent: client.agent
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ export default async function ClientsPage(props: ClientsPageProps) {
|
|||||||
olmUpdateAvailable: client.olmUpdateAvailable || false,
|
olmUpdateAvailable: client.olmUpdateAvailable || false,
|
||||||
userId: client.userId,
|
userId: client.userId,
|
||||||
username: client.username,
|
username: client.username,
|
||||||
userEmail: client.userEmail
|
userEmail: client.userEmail,
|
||||||
|
niceId: client.niceId,
|
||||||
|
agent: client.agent
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export type ClientRow = {
|
|||||||
username: string | null;
|
username: string | null;
|
||||||
userEmail: string | null;
|
userEmail: string | null;
|
||||||
niceId: string;
|
niceId: string;
|
||||||
|
agent: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ClientTableProps = {
|
type ClientTableProps = {
|
||||||
@@ -65,7 +66,6 @@ export default function MachineClientsTable({
|
|||||||
const [isRefreshing, startTransition] = useTransition();
|
const [isRefreshing, startTransition] = useTransition();
|
||||||
|
|
||||||
const defaultMachineColumnVisibility = {
|
const defaultMachineColumnVisibility = {
|
||||||
client: false,
|
|
||||||
subnet: false,
|
subnet: false,
|
||||||
userId: false,
|
userId: false,
|
||||||
niceId: false
|
niceId: false
|
||||||
@@ -226,7 +226,7 @@ export default function MachineClientsTable({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "client",
|
accessorKey: "client",
|
||||||
friendlyName: t("client"),
|
friendlyName: t("agent"),
|
||||||
header: ({ column }) => {
|
header: ({ column }) => {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
@@ -237,7 +237,7 @@ export default function MachineClientsTable({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t("client")}
|
{t("agent")}
|
||||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@@ -247,19 +247,18 @@ export default function MachineClientsTable({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center space-x-1">
|
<div className="flex items-center space-x-1">
|
||||||
<Badge variant="secondary">
|
{originalRow.agent && originalRow.olmVersion ? (
|
||||||
<div className="flex items-center space-x-2">
|
<Badge variant="secondary">
|
||||||
<span>Olm</span>
|
{originalRow.agent +
|
||||||
{originalRow.olmVersion && (
|
" v" +
|
||||||
<span className="text-xs text-gray-500">
|
originalRow.olmVersion}
|
||||||
v{originalRow.olmVersion}
|
</Badge>
|
||||||
</span>
|
) : (
|
||||||
)}
|
"-"
|
||||||
</div>
|
|
||||||
</Badge>
|
|
||||||
{originalRow.olmUpdateAvailable && (
|
|
||||||
<InfoPopup info={t("olmUpdateAvailableInfo")} />
|
|
||||||
)}
|
)}
|
||||||
|
{/*originalRow.olmUpdateAvailable && (
|
||||||
|
<InfoPopup info={t("olmUpdateAvailableInfo")} />
|
||||||
|
)*/}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ export type ClientRow = {
|
|||||||
userId: string | null;
|
userId: string | null;
|
||||||
username: string | null;
|
username: string | null;
|
||||||
userEmail: string | null;
|
userEmail: string | null;
|
||||||
|
niceId: string;
|
||||||
|
agent: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ClientTableProps = {
|
type ClientTableProps = {
|
||||||
@@ -60,8 +62,8 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
const [isRefreshing, startTransition] = useTransition();
|
const [isRefreshing, startTransition] = useTransition();
|
||||||
|
|
||||||
const defaultUserColumnVisibility = {
|
const defaultUserColumnVisibility = {
|
||||||
client: false,
|
subnet: false,
|
||||||
subnet: false
|
niceId: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshData = () => {
|
const refreshData = () => {
|
||||||
@@ -123,6 +125,25 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "niceId",
|
||||||
|
friendlyName: t("identifier"),
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() =>
|
||||||
|
column.toggleSorting(
|
||||||
|
column.getIsSorted() === "asc"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("identifier")}
|
||||||
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "userEmail",
|
accessorKey: "userEmail",
|
||||||
friendlyName: "User",
|
friendlyName: "User",
|
||||||
@@ -261,7 +282,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "client",
|
accessorKey: "client",
|
||||||
friendlyName: t("client"),
|
friendlyName: t("agent"),
|
||||||
header: ({ column }) => {
|
header: ({ column }) => {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
@@ -272,7 +293,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t("client")}
|
{t("agent")}
|
||||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@@ -282,19 +303,19 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center space-x-1">
|
<div className="flex items-center space-x-1">
|
||||||
<Badge variant="secondary">
|
{originalRow.agent && originalRow.olmVersion ? (
|
||||||
<div className="flex items-center space-x-2">
|
<Badge variant="secondary">
|
||||||
<span>Olm</span>
|
{originalRow.agent +
|
||||||
{originalRow.olmVersion && (
|
" v" +
|
||||||
<span className="text-xs text-gray-500">
|
originalRow.olmVersion}
|
||||||
v{originalRow.olmVersion}
|
</Badge>
|
||||||
</span>
|
) : (
|
||||||
)}
|
"-"
|
||||||
</div>
|
|
||||||
</Badge>
|
|
||||||
{originalRow.olmUpdateAvailable && (
|
|
||||||
<InfoPopup info={t("olmUpdateAvailableInfo")} />
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/*originalRow.olmUpdateAvailable && (
|
||||||
|
<InfoPopup info={t("olmUpdateAvailableInfo")} />
|
||||||
|
)*/}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -320,62 +341,52 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// Only include actions column if there are rows without userIds
|
baseColumns.push({
|
||||||
if (hasRowsWithoutUserId) {
|
id: "actions",
|
||||||
baseColumns.push({
|
enableHiding: false,
|
||||||
id: "actions",
|
header: () => <span className="p-3"></span>,
|
||||||
enableHiding: false,
|
cell: ({ row }) => {
|
||||||
header: () => <span className="p-3"></span>,
|
const clientRow = row.original;
|
||||||
cell: ({ row }) => {
|
return !clientRow.userId ? (
|
||||||
const clientRow = row.original;
|
<div className="flex items-center gap-2 justify-end">
|
||||||
return !clientRow.userId ? (
|
<DropdownMenu>
|
||||||
<div className="flex items-center gap-2 justify-end">
|
<DropdownMenuTrigger asChild>
|
||||||
<DropdownMenu>
|
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||||
<DropdownMenuTrigger asChild>
|
<span className="sr-only">Open menu</span>
|
||||||
<Button
|
<MoreHorizontal className="h-4 w-4" />
|
||||||
variant="ghost"
|
|
||||||
className="h-8 w-8 p-0"
|
|
||||||
>
|
|
||||||
<span className="sr-only">
|
|
||||||
Open menu
|
|
||||||
</span>
|
|
||||||
<MoreHorizontal className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{/* <Link */}
|
|
||||||
{/* className="block w-full" */}
|
|
||||||
{/* href={`/${clientRow.orgId}/settings/sites/${clientRow.nice}`} */}
|
|
||||||
{/* > */}
|
|
||||||
{/* <DropdownMenuItem> */}
|
|
||||||
{/* View settings */}
|
|
||||||
{/* </DropdownMenuItem> */}
|
|
||||||
{/* </Link> */}
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedClient(clientRow);
|
|
||||||
setIsDeleteModalOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="text-red-500">
|
|
||||||
Delete
|
|
||||||
</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
<Link
|
|
||||||
href={`/${clientRow.orgId}/settings/clients/${clientRow.id}`}
|
|
||||||
>
|
|
||||||
<Button variant={"outline"}>
|
|
||||||
Edit
|
|
||||||
<ArrowRight className="ml-2 w-4 h-4" />
|
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</DropdownMenuTrigger>
|
||||||
</div>
|
<DropdownMenuContent align="end">
|
||||||
) : null;
|
{/* <Link */}
|
||||||
}
|
{/* className="block w-full" */}
|
||||||
});
|
{/* href={`/${clientRow.orgId}/settings/sites/${clientRow.nice}`} */}
|
||||||
}
|
{/* > */}
|
||||||
|
{/* <DropdownMenuItem> */}
|
||||||
|
{/* View settings */}
|
||||||
|
{/* </DropdownMenuItem> */}
|
||||||
|
{/* </Link> */}
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedClient(clientRow);
|
||||||
|
setIsDeleteModalOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="text-red-500">Delete</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
<Link
|
||||||
|
href={`/${clientRow.orgId}/settings/clients/${clientRow.id}`}
|
||||||
|
>
|
||||||
|
<Button variant={"outline"}>
|
||||||
|
Edit
|
||||||
|
<ArrowRight className="ml-2 w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return baseColumns;
|
return baseColumns;
|
||||||
}, [hasRowsWithoutUserId, t]);
|
}, [hasRowsWithoutUserId, t]);
|
||||||
|
|||||||
Reference in New Issue
Block a user