mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 09:28:06 +00:00
Merge pull request #4566 from Infisical/misc/move-gateway-and-relay-to-networking-page
misc: move gateway and relay to networking page
This commit is contained in:
@@ -1,11 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
faBook,
|
faBook,
|
||||||
faCog,
|
faCog,
|
||||||
faDoorClosed,
|
|
||||||
faInfinity,
|
faInfinity,
|
||||||
faMoneyBill,
|
faMoneyBill,
|
||||||
|
faNetworkWired,
|
||||||
faPlug,
|
faPlug,
|
||||||
faRoute,
|
|
||||||
faShare,
|
faShare,
|
||||||
faTable,
|
faTable,
|
||||||
faUsers,
|
faUsers,
|
||||||
@@ -125,26 +124,14 @@ export const OrgSidebar = ({ isHidden }: Props) => {
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to="/organization/gateways">
|
<Link to="/organization/networking">
|
||||||
{({ isActive }) => (
|
{({ isActive }) => (
|
||||||
<MenuItem isSelected={isActive}>
|
<MenuItem isSelected={isActive}>
|
||||||
<div className="mx-1 flex gap-2">
|
<div className="mx-1 flex gap-2">
|
||||||
<div className="w-6">
|
<div className="w-6">
|
||||||
<FontAwesomeIcon icon={faDoorClosed} className="mr-4" />
|
<FontAwesomeIcon icon={faNetworkWired} className="mr-4" />
|
||||||
</div>
|
</div>
|
||||||
Gateways
|
Networking
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
</Link>
|
|
||||||
<Link to="/organization/relays">
|
|
||||||
{({ isActive }) => (
|
|
||||||
<MenuItem isSelected={isActive}>
|
|
||||||
<div className="mx-1 flex gap-2">
|
|
||||||
<div className="w-6">
|
|
||||||
<FontAwesomeIcon icon={faRoute} className="mr-4" />
|
|
||||||
</div>
|
|
||||||
Relays
|
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,267 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { Helmet } from "react-helmet";
|
|
||||||
import {
|
|
||||||
faArrowUpRightFromSquare,
|
|
||||||
faBookOpen,
|
|
||||||
faCopy,
|
|
||||||
faDoorClosed,
|
|
||||||
faEdit,
|
|
||||||
faEllipsisV,
|
|
||||||
faInfoCircle,
|
|
||||||
faMagnifyingGlass,
|
|
||||||
faSearch,
|
|
||||||
faTrash
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import { formatRelative } from "date-fns";
|
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
|
||||||
import {
|
|
||||||
DeleteActionModal,
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
EmptyState,
|
|
||||||
IconButton,
|
|
||||||
Input,
|
|
||||||
Modal,
|
|
||||||
ModalContent,
|
|
||||||
PageHeader,
|
|
||||||
Table,
|
|
||||||
TableContainer,
|
|
||||||
TableSkeleton,
|
|
||||||
TBody,
|
|
||||||
Td,
|
|
||||||
Th,
|
|
||||||
THead,
|
|
||||||
Tooltip,
|
|
||||||
Tr
|
|
||||||
} from "@app/components/v2";
|
|
||||||
import {
|
|
||||||
OrgGatewayPermissionActions,
|
|
||||||
OrgPermissionAppConnectionActions,
|
|
||||||
OrgPermissionSubjects
|
|
||||||
} from "@app/context/OrgPermissionContext/types";
|
|
||||||
import { withPermission } from "@app/hoc";
|
|
||||||
import { usePopUp } from "@app/hooks";
|
|
||||||
import { gatewaysQueryKeys, useDeleteGatewayById } from "@app/hooks/api/gateways";
|
|
||||||
import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2";
|
|
||||||
|
|
||||||
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
|
|
||||||
|
|
||||||
export const GatewayListPage = withPermission(
|
|
||||||
() => {
|
|
||||||
const [search, setSearch] = useState("");
|
|
||||||
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
|
||||||
"deleteGateway",
|
|
||||||
"editDetails"
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
const deleteGatewayById = useDeleteGatewayById();
|
|
||||||
const deleteGatewayV2ById = useDeleteGatewayV2ById();
|
|
||||||
|
|
||||||
const handleDeleteGateway = async () => {
|
|
||||||
const data = popUp.deleteGateway.data as { id: string; isV1: boolean };
|
|
||||||
if (data.isV1) {
|
|
||||||
await deleteGatewayById.mutateAsync(data.id);
|
|
||||||
} else {
|
|
||||||
await deleteGatewayV2ById.mutateAsync(data.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpToggle("deleteGateway");
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully deleted gateway"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredGateway = gateways?.filter((el) =>
|
|
||||||
el.name.toLowerCase().includes(search.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bg-bunker-800">
|
|
||||||
<Helmet>
|
|
||||||
<title>Infisical | Gateways</title>
|
|
||||||
<meta property="og:image" content="/images/message.png" />
|
|
||||||
</Helmet>
|
|
||||||
<div className="flex w-full justify-center bg-bunker-800 text-white">
|
|
||||||
<div className="w-full max-w-7xl">
|
|
||||||
<PageHeader
|
|
||||||
className="w-full"
|
|
||||||
title={
|
|
||||||
<div className="flex w-full items-center">
|
|
||||||
<span>Gateways</span>
|
|
||||||
<a
|
|
||||||
className="-mt-1.5"
|
|
||||||
href="https://infisical.com/docs/documentation/platform/gateways/overview"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<div className="ml-2 inline-block rounded-md bg-yellow/20 px-1.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
|
||||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
|
||||||
<span>Docs</span>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={faArrowUpRightFromSquare}
|
|
||||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
description="Create and configure gateway to access private network resources from Infisical"
|
|
||||||
/>
|
|
||||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
|
||||||
<div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
value={search}
|
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
|
||||||
placeholder="Search gateway..."
|
|
||||||
className="flex-1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<TableContainer className="mt-4">
|
|
||||||
<Table>
|
|
||||||
<THead>
|
|
||||||
<Tr>
|
|
||||||
<Th className="w-1/3">Name</Th>
|
|
||||||
<Th>Identity</Th>
|
|
||||||
<Th>
|
|
||||||
Health Check
|
|
||||||
<Tooltip
|
|
||||||
asChild={false}
|
|
||||||
className="normal-case"
|
|
||||||
content="The last known healthcheck. Triggers every 1 hour."
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faInfoCircle} className="ml-2" />
|
|
||||||
</Tooltip>
|
|
||||||
</Th>
|
|
||||||
<Th className="w-5" />
|
|
||||||
</Tr>
|
|
||||||
</THead>
|
|
||||||
<TBody>
|
|
||||||
{isGatewaysLoading && (
|
|
||||||
<TableSkeleton innerKey="gateway-table" columns={4} key="gateway-table" />
|
|
||||||
)}
|
|
||||||
{filteredGateway?.map((el) => (
|
|
||||||
<Tr key={el.id}>
|
|
||||||
<Td>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span>{el.name}</span>
|
|
||||||
<span className="rounded bg-mineshaft-700 px-1.5 py-0.5 text-xs text-mineshaft-400">
|
|
||||||
Gateway v{el.isV1 ? "1" : "2"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</Td>
|
|
||||||
<Td>{el.identity.name}</Td>
|
|
||||||
<Td>
|
|
||||||
{el.heartbeat
|
|
||||||
? formatRelative(new Date(el.heartbeat), new Date())
|
|
||||||
: "-"}
|
|
||||||
</Td>
|
|
||||||
<Td className="w-5">
|
|
||||||
<Tooltip className="max-w-sm text-center" content="Options">
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<IconButton
|
|
||||||
ariaLabel="Options"
|
|
||||||
colorSchema="secondary"
|
|
||||||
className="w-6"
|
|
||||||
variant="plain"
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faEllipsisV} />
|
|
||||||
</IconButton>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuItem
|
|
||||||
icon={<FontAwesomeIcon icon={faCopy} />}
|
|
||||||
onClick={() => navigator.clipboard.writeText(el.id)}
|
|
||||||
>
|
|
||||||
Copy ID
|
|
||||||
</DropdownMenuItem>
|
|
||||||
{el.isV1 && (
|
|
||||||
<OrgPermissionCan
|
|
||||||
I={OrgGatewayPermissionActions.EditGateways}
|
|
||||||
a={OrgPermissionSubjects.Gateway}
|
|
||||||
>
|
|
||||||
{(isAllowed: boolean) => (
|
|
||||||
<DropdownMenuItem
|
|
||||||
isDisabled={!isAllowed}
|
|
||||||
icon={<FontAwesomeIcon icon={faEdit} />}
|
|
||||||
onClick={() => handlePopUpOpen("editDetails", el)}
|
|
||||||
>
|
|
||||||
Edit Details
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
|
||||||
)}
|
|
||||||
<OrgPermissionCan
|
|
||||||
I={OrgPermissionAppConnectionActions.Delete}
|
|
||||||
a={OrgPermissionSubjects.AppConnections}
|
|
||||||
>
|
|
||||||
{(isAllowed: boolean) => (
|
|
||||||
<DropdownMenuItem
|
|
||||||
isDisabled={!isAllowed}
|
|
||||||
icon={<FontAwesomeIcon icon={faTrash} />}
|
|
||||||
className="text-red"
|
|
||||||
onClick={() => handlePopUpOpen("deleteGateway", el)}
|
|
||||||
>
|
|
||||||
Delete Gateway
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</Tooltip>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</TBody>
|
|
||||||
</Table>
|
|
||||||
<Modal
|
|
||||||
isOpen={popUp.editDetails.isOpen}
|
|
||||||
onOpenChange={(isOpen) => handlePopUpToggle("editDetails", isOpen)}
|
|
||||||
>
|
|
||||||
<ModalContent title="Edit Gateway">
|
|
||||||
<EditGatewayDetailsModal
|
|
||||||
gatewayDetails={popUp.editDetails.data}
|
|
||||||
onClose={() => handlePopUpToggle("editDetails")}
|
|
||||||
/>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
{!isGatewaysLoading && !filteredGateway?.length && (
|
|
||||||
<EmptyState
|
|
||||||
title={
|
|
||||||
gateways?.length
|
|
||||||
? "No Gateways match search..."
|
|
||||||
: "No Gateways have been configured"
|
|
||||||
}
|
|
||||||
icon={gateways?.length ? faSearch : faDoorClosed}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<DeleteActionModal
|
|
||||||
isOpen={popUp.deleteGateway.isOpen}
|
|
||||||
title={`Are you sure you want to delete gateway ${
|
|
||||||
(popUp?.deleteGateway?.data as { name: string })?.name || ""
|
|
||||||
}?`}
|
|
||||||
onChange={(isOpen) => handlePopUpToggle("deleteGateway", isOpen)}
|
|
||||||
deleteKey="confirm"
|
|
||||||
onDeleteApproved={() => handleDeleteGateway()}
|
|
||||||
/>
|
|
||||||
</TableContainer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{ action: OrgGatewayPermissionActions.ListGateways, subject: OrgPermissionSubjects.Gateway }
|
|
||||||
);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router";
|
|
||||||
|
|
||||||
import { GatewayListPage } from "./GatewayListPage";
|
|
||||||
|
|
||||||
export const Route = createFileRoute(
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways/"
|
|
||||||
)({
|
|
||||||
component: GatewayListPage,
|
|
||||||
context: () => ({
|
|
||||||
breadcrumbs: [
|
|
||||||
{
|
|
||||||
label: "Gateways"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { Helmet } from "react-helmet";
|
|
||||||
import {
|
|
||||||
faArrowUpRightFromSquare,
|
|
||||||
faBookOpen,
|
|
||||||
faCopy,
|
|
||||||
faDoorClosed,
|
|
||||||
faEllipsisV,
|
|
||||||
faMagnifyingGlass,
|
|
||||||
faSearch,
|
|
||||||
faTrash
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import { formatRelative } from "date-fns";
|
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
|
||||||
import {
|
|
||||||
DeleteActionModal,
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
EmptyState,
|
|
||||||
IconButton,
|
|
||||||
Input,
|
|
||||||
PageHeader,
|
|
||||||
Table,
|
|
||||||
TableContainer,
|
|
||||||
TableSkeleton,
|
|
||||||
TBody,
|
|
||||||
Td,
|
|
||||||
Th,
|
|
||||||
THead,
|
|
||||||
Tooltip,
|
|
||||||
Tr
|
|
||||||
} from "@app/components/v2";
|
|
||||||
import {
|
|
||||||
OrgPermissionSubjects,
|
|
||||||
OrgRelayPermissionActions
|
|
||||||
} from "@app/context/OrgPermissionContext/types";
|
|
||||||
import { withPermission } from "@app/hoc";
|
|
||||||
import { usePopUp } from "@app/hooks";
|
|
||||||
import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays";
|
|
||||||
|
|
||||||
export const RelayListPage = withPermission(
|
|
||||||
() => {
|
|
||||||
const [search, setSearch] = useState("");
|
|
||||||
const { data: relays, isPending: isRelaysLoading } = useGetRelays();
|
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteRelay"] as const);
|
|
||||||
|
|
||||||
const deleteRelayById = useDeleteRelayById();
|
|
||||||
|
|
||||||
const handleDeleteRelay = async () => {
|
|
||||||
const data = popUp.deleteRelay.data as { id: string };
|
|
||||||
await deleteRelayById.mutateAsync(data.id);
|
|
||||||
|
|
||||||
handlePopUpToggle("deleteRelay");
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully deleted relay"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredRelays = relays?.filter((el) =>
|
|
||||||
el.name.toLowerCase().includes(search.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bg-bunker-800">
|
|
||||||
<Helmet>
|
|
||||||
<title>Infisical | Relays</title>
|
|
||||||
<meta property="og:image" content="/images/message.png" />
|
|
||||||
</Helmet>
|
|
||||||
<div className="flex w-full justify-center bg-bunker-800 text-white">
|
|
||||||
<div className="w-full max-w-7xl">
|
|
||||||
<PageHeader
|
|
||||||
className="w-full"
|
|
||||||
title={
|
|
||||||
<div className="flex w-full items-center">
|
|
||||||
<span>Relays</span>
|
|
||||||
<a
|
|
||||||
className="-mt-1.5"
|
|
||||||
href="https://infisical.com/docs/documentation/platform/gateways/relay-deployment"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<div className="ml-2 inline-block rounded-md bg-yellow/20 px-1.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
|
||||||
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
|
||||||
<span>Docs</span>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={faArrowUpRightFromSquare}
|
|
||||||
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
description="Create and configure relays to securely access private network resources from Infisical"
|
|
||||||
/>
|
|
||||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
|
||||||
<div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
value={search}
|
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
|
||||||
placeholder="Search relay..."
|
|
||||||
className="flex-1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<TableContainer className="mt-4">
|
|
||||||
<Table>
|
|
||||||
<THead>
|
|
||||||
<Tr>
|
|
||||||
<Th className="w-1/3">Name</Th>
|
|
||||||
<Th>Host</Th>
|
|
||||||
<Th>Created</Th>
|
|
||||||
<Th className="w-5" />
|
|
||||||
</Tr>
|
|
||||||
</THead>
|
|
||||||
<TBody>
|
|
||||||
{isRelaysLoading && (
|
|
||||||
<TableSkeleton innerKey="relay-table" columns={4} key="relay-table" />
|
|
||||||
)}
|
|
||||||
{filteredRelays?.map((el) => (
|
|
||||||
<Tr key={el.id}>
|
|
||||||
<Td>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span>{el.name}</span>
|
|
||||||
{!el.orgId && (
|
|
||||||
<Tooltip content="This is a managed relay provided by Infisical">
|
|
||||||
<span className="rounded bg-mineshaft-700 px-1.5 py-0.5 text-xs text-mineshaft-400">
|
|
||||||
Managed
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Td>
|
|
||||||
<Td>{el.host}</Td>
|
|
||||||
<Td>{formatRelative(new Date(el.createdAt), new Date())}</Td>
|
|
||||||
<Td className="w-5">
|
|
||||||
<Tooltip className="max-w-sm text-center" content="Options">
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<IconButton
|
|
||||||
ariaLabel="Options"
|
|
||||||
colorSchema="secondary"
|
|
||||||
className="w-6"
|
|
||||||
variant="plain"
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faEllipsisV} />
|
|
||||||
</IconButton>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuItem
|
|
||||||
icon={<FontAwesomeIcon icon={faCopy} />}
|
|
||||||
onClick={() => navigator.clipboard.writeText(el.id)}
|
|
||||||
>
|
|
||||||
Copy ID
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<OrgPermissionCan
|
|
||||||
I={OrgRelayPermissionActions.DeleteRelays}
|
|
||||||
a={OrgPermissionSubjects.Relay}
|
|
||||||
>
|
|
||||||
{(isAllowed: boolean) => (
|
|
||||||
<DropdownMenuItem
|
|
||||||
isDisabled={!isAllowed || !el.orgId}
|
|
||||||
icon={<FontAwesomeIcon icon={faTrash} />}
|
|
||||||
className="text-red"
|
|
||||||
onClick={() => handlePopUpOpen("deleteRelay", el)}
|
|
||||||
>
|
|
||||||
Delete Relay
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</Tooltip>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</TBody>
|
|
||||||
</Table>
|
|
||||||
{!isRelaysLoading && !filteredRelays?.length && (
|
|
||||||
<EmptyState
|
|
||||||
title={
|
|
||||||
relays?.length
|
|
||||||
? "No Relays match search..."
|
|
||||||
: "No Relays have been configured"
|
|
||||||
}
|
|
||||||
icon={relays?.length ? faSearch : faDoorClosed}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<DeleteActionModal
|
|
||||||
isOpen={popUp.deleteRelay.isOpen}
|
|
||||||
title={`Are you sure you want to delete relay ${
|
|
||||||
(popUp?.deleteRelay?.data as { name: string })?.name || ""
|
|
||||||
}?`}
|
|
||||||
onChange={(isOpen) => handlePopUpToggle("deleteRelay", isOpen)}
|
|
||||||
deleteKey="confirm"
|
|
||||||
onDeleteApproved={() => handleDeleteRelay()}
|
|
||||||
/>
|
|
||||||
</TableContainer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{ action: OrgRelayPermissionActions.ListRelays, subject: OrgPermissionSubjects.Relay }
|
|
||||||
);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router";
|
|
||||||
|
|
||||||
import { RelayListPage } from "./RelayListPage";
|
|
||||||
|
|
||||||
export const Route = createFileRoute(
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/relays/"
|
|
||||||
)({
|
|
||||||
component: RelayListPage,
|
|
||||||
context: () => ({
|
|
||||||
breadcrumbs: [
|
|
||||||
{
|
|
||||||
label: "Relays"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Helmet } from "react-helmet";
|
||||||
|
|
||||||
|
import { PageHeader } from "@app/components/v2";
|
||||||
|
|
||||||
|
import { NetworkingTabGroup } from "./components/NetworkingTabGroup/NetworkingTabGroup";
|
||||||
|
|
||||||
|
export const NetworkingPage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Helmet>
|
||||||
|
<title>Infisical | Networking</title>
|
||||||
|
<meta property="og:image" content="/images/message.png" />
|
||||||
|
</Helmet>
|
||||||
|
<div className="flex w-full justify-center bg-bunker-800 text-white">
|
||||||
|
<div className="w-full max-w-7xl">
|
||||||
|
<PageHeader
|
||||||
|
title="Networking"
|
||||||
|
description="Manage gateways and relays to securely access private network resources from Infisical"
|
||||||
|
/>
|
||||||
|
<NetworkingTabGroup />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
faArrowUpRightFromSquare,
|
||||||
|
faBookOpen,
|
||||||
|
faCopy,
|
||||||
|
faDoorClosed,
|
||||||
|
faEdit,
|
||||||
|
faEllipsisV,
|
||||||
|
faInfoCircle,
|
||||||
|
faMagnifyingGlass,
|
||||||
|
faSearch,
|
||||||
|
faTrash
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { createNotification } from "@app/components/notifications";
|
||||||
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
|
import {
|
||||||
|
DeleteActionModal,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
EmptyState,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Modal,
|
||||||
|
ModalContent,
|
||||||
|
Table,
|
||||||
|
TableContainer,
|
||||||
|
TableSkeleton,
|
||||||
|
TBody,
|
||||||
|
Td,
|
||||||
|
Th,
|
||||||
|
THead,
|
||||||
|
Tooltip,
|
||||||
|
Tr
|
||||||
|
} from "@app/components/v2";
|
||||||
|
import {
|
||||||
|
OrgGatewayPermissionActions,
|
||||||
|
OrgPermissionSubjects
|
||||||
|
} from "@app/context/OrgPermissionContext/types";
|
||||||
|
import { withPermission } from "@app/hoc";
|
||||||
|
import { usePopUp } from "@app/hooks";
|
||||||
|
import { gatewaysQueryKeys, useDeleteGatewayById } from "@app/hooks/api/gateways";
|
||||||
|
import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2";
|
||||||
|
|
||||||
|
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
|
||||||
|
|
||||||
|
const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
|
||||||
|
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
|
||||||
|
const now = new Date();
|
||||||
|
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
|
||||||
|
|
||||||
|
const isHealthy = heartbeatDate && heartbeatDate >= oneHourAgo;
|
||||||
|
const tooltipContent = heartbeatDate
|
||||||
|
? `Last heartbeat: ${heartbeatDate.toLocaleString()}`
|
||||||
|
: "No heartbeat data available";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip content={tooltipContent}>
|
||||||
|
<span className={`cursor-default ${isHealthy ? "text-green-400" : "text-red-400"}`}>
|
||||||
|
{isHealthy ? "Healthy" : "Unreachable"}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GatewayTab = withPermission(
|
||||||
|
() => {
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
||||||
|
|
||||||
|
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
||||||
|
"deleteGateway",
|
||||||
|
"editDetails"
|
||||||
|
] as const);
|
||||||
|
|
||||||
|
const deleteGatewayById = useDeleteGatewayById();
|
||||||
|
const deleteGatewayV2ById = useDeleteGatewayV2ById();
|
||||||
|
|
||||||
|
const handleDeleteGateway = async () => {
|
||||||
|
const data = popUp.deleteGateway.data as { id: string; isV1: boolean };
|
||||||
|
if (data.isV1) {
|
||||||
|
await deleteGatewayById.mutateAsync(data.id);
|
||||||
|
} else {
|
||||||
|
await deleteGatewayV2ById.mutateAsync(data.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpToggle("deleteGateway");
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully deleted gateway"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredGateway = gateways?.filter((el) =>
|
||||||
|
el.name.toLowerCase().includes(search.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<h3 className="text-lg font-semibold text-mineshaft-100">Gateways</h3>
|
||||||
|
<a
|
||||||
|
href="https://infisical.com/docs/documentation/platform/gateways/overview"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<div className="inline-block rounded-md bg-yellow/20 px-1.5 py-0.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
||||||
|
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||||
|
<span>Docs</span>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faArrowUpRightFromSquare}
|
||||||
|
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mb-4 text-sm text-mineshaft-400">
|
||||||
|
Create and configure gateway to access private network resources from Infisical
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Input
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
||||||
|
placeholder="Search gateway..."
|
||||||
|
className="flex-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TableContainer className="mt-4">
|
||||||
|
<Table>
|
||||||
|
<THead>
|
||||||
|
<Tr>
|
||||||
|
<Th className="w-1/2">Name</Th>
|
||||||
|
<Th>
|
||||||
|
Health Check
|
||||||
|
<Tooltip
|
||||||
|
asChild={false}
|
||||||
|
className="normal-case"
|
||||||
|
content="The last known healthcheck. Triggers every 1 hour."
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faInfoCircle} className="ml-2" />
|
||||||
|
</Tooltip>
|
||||||
|
</Th>
|
||||||
|
<Th className="w-5" />
|
||||||
|
</Tr>
|
||||||
|
</THead>
|
||||||
|
<TBody>
|
||||||
|
{isGatewaysLoading && (
|
||||||
|
<TableSkeleton innerKey="gateway-table" columns={4} key="gateway-table" />
|
||||||
|
)}
|
||||||
|
{filteredGateway?.map((el) => (
|
||||||
|
<Tr key={el.id}>
|
||||||
|
<Td>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span>{el.name}</span>
|
||||||
|
<span className="rounded bg-mineshaft-700 px-1.5 py-0.5 text-xs text-mineshaft-400">
|
||||||
|
Gateway v{el.isV1 ? "1" : "2"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<GatewayHealthStatus heartbeat={el.heartbeat} />
|
||||||
|
</Td>
|
||||||
|
<Td className="w-5">
|
||||||
|
<Tooltip className="max-w-sm text-center" content="Options">
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="Options"
|
||||||
|
colorSchema="secondary"
|
||||||
|
className="w-6"
|
||||||
|
variant="plain"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faEllipsisV} />
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem
|
||||||
|
icon={<FontAwesomeIcon icon={faCopy} />}
|
||||||
|
onClick={() => navigator.clipboard.writeText(el.id)}
|
||||||
|
>
|
||||||
|
Copy ID
|
||||||
|
</DropdownMenuItem>
|
||||||
|
{el.isV1 && (
|
||||||
|
<OrgPermissionCan
|
||||||
|
I={OrgGatewayPermissionActions.EditGateways}
|
||||||
|
a={OrgPermissionSubjects.Gateway}
|
||||||
|
>
|
||||||
|
{(isAllowed: boolean) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
icon={<FontAwesomeIcon icon={faEdit} />}
|
||||||
|
onClick={() => handlePopUpOpen("editDetails", el)}
|
||||||
|
>
|
||||||
|
Edit Details
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
)}
|
||||||
|
<OrgPermissionCan
|
||||||
|
I={OrgGatewayPermissionActions.DeleteGateways}
|
||||||
|
a={OrgPermissionSubjects.Gateway}
|
||||||
|
>
|
||||||
|
{(isAllowed: boolean) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
icon={<FontAwesomeIcon icon={faTrash} />}
|
||||||
|
className="text-red"
|
||||||
|
onClick={() => handlePopUpOpen("deleteGateway", el)}
|
||||||
|
>
|
||||||
|
Delete Gateway
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Tooltip>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</TBody>
|
||||||
|
</Table>
|
||||||
|
<Modal
|
||||||
|
isOpen={popUp.editDetails.isOpen}
|
||||||
|
onOpenChange={(isOpen) => handlePopUpToggle("editDetails", isOpen)}
|
||||||
|
>
|
||||||
|
<ModalContent title="Edit Gateway">
|
||||||
|
<EditGatewayDetailsModal
|
||||||
|
gatewayDetails={popUp.editDetails.data}
|
||||||
|
onClose={() => handlePopUpToggle("editDetails")}
|
||||||
|
/>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
{!isGatewaysLoading && !filteredGateway?.length && (
|
||||||
|
<EmptyState
|
||||||
|
title={
|
||||||
|
gateways?.length
|
||||||
|
? "No Gateways match search..."
|
||||||
|
: "No Gateways have been configured"
|
||||||
|
}
|
||||||
|
icon={gateways?.length ? faSearch : faDoorClosed}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DeleteActionModal
|
||||||
|
isOpen={popUp.deleteGateway.isOpen}
|
||||||
|
title={`Are you sure you want to delete gateway ${
|
||||||
|
(popUp?.deleteGateway?.data as { name: string })?.name || ""
|
||||||
|
}?`}
|
||||||
|
onChange={(isOpen) => handlePopUpToggle("deleteGateway", isOpen)}
|
||||||
|
deleteKey="confirm"
|
||||||
|
onDeleteApproved={() => handleDeleteGateway()}
|
||||||
|
/>
|
||||||
|
</TableContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ action: OrgGatewayPermissionActions.ListGateways, subject: OrgPermissionSubjects.Gateway }
|
||||||
|
);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { GatewayTab } from "./GatewayTab";
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useSearch } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||||
|
|
||||||
|
import { GatewayTab } from "../GatewayTab/GatewayTab";
|
||||||
|
import { RelayTab } from "../RelayTab/RelayTab";
|
||||||
|
|
||||||
|
export const NetworkingTabGroup = () => {
|
||||||
|
const search = useSearch({
|
||||||
|
from: "/_authenticate/_inject-org-details/_org-layout/organization/networking/"
|
||||||
|
});
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
{ name: "Gateways", key: "gateways", component: GatewayTab },
|
||||||
|
{ name: "Relays", key: "relays", component: RelayTab }
|
||||||
|
];
|
||||||
|
|
||||||
|
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
||||||
|
<TabList>
|
||||||
|
{tabs.map((tab) => (
|
||||||
|
<Tab value={tab.key} key={tab.key}>
|
||||||
|
{tab.name}
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
|
</TabList>
|
||||||
|
{tabs.map(({ key, component: Component }) => (
|
||||||
|
<TabPanel value={key} key={`tab-panel-${key}`}>
|
||||||
|
<Component />
|
||||||
|
</TabPanel>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { NetworkingTabGroup } from "./NetworkingTabGroup";
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
faArrowUpRightFromSquare,
|
||||||
|
faBookOpen,
|
||||||
|
faCopy,
|
||||||
|
faDoorClosed,
|
||||||
|
faEllipsisV,
|
||||||
|
faMagnifyingGlass,
|
||||||
|
faSearch,
|
||||||
|
faTrash
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { formatRelative } from "date-fns";
|
||||||
|
|
||||||
|
import { createNotification } from "@app/components/notifications";
|
||||||
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
|
import {
|
||||||
|
DeleteActionModal,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
EmptyState,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Table,
|
||||||
|
TableContainer,
|
||||||
|
TableSkeleton,
|
||||||
|
TBody,
|
||||||
|
Td,
|
||||||
|
Th,
|
||||||
|
THead,
|
||||||
|
Tooltip,
|
||||||
|
Tr
|
||||||
|
} from "@app/components/v2";
|
||||||
|
import {
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
OrgRelayPermissionActions
|
||||||
|
} from "@app/context/OrgPermissionContext/types";
|
||||||
|
import { withPermission } from "@app/hoc";
|
||||||
|
import { usePopUp } from "@app/hooks";
|
||||||
|
import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays";
|
||||||
|
|
||||||
|
export const RelayTab = withPermission(
|
||||||
|
() => {
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
const { data: relays, isPending: isRelaysLoading } = useGetRelays();
|
||||||
|
|
||||||
|
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteRelay"] as const);
|
||||||
|
|
||||||
|
const deleteRelayById = useDeleteRelayById();
|
||||||
|
|
||||||
|
const handleDeleteRelay = async () => {
|
||||||
|
const data = popUp.deleteRelay.data as { id: string };
|
||||||
|
await deleteRelayById.mutateAsync(data.id);
|
||||||
|
|
||||||
|
handlePopUpToggle("deleteRelay");
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully deleted relay"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredRelays = relays?.filter((el) =>
|
||||||
|
el.name.toLowerCase().includes(search.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<h3 className="text-lg font-semibold text-mineshaft-100">Relays</h3>
|
||||||
|
<a
|
||||||
|
href="https://infisical.com/docs/documentation/platform/gateways/relay-deployment"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<div className="inline-block rounded-md bg-yellow/20 px-1.5 py-0.5 text-sm font-normal text-yellow opacity-80 hover:opacity-100">
|
||||||
|
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
|
||||||
|
<span>Docs</span>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faArrowUpRightFromSquare}
|
||||||
|
className="mb-[0.07rem] ml-1.5 text-[10px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mb-4 text-sm text-mineshaft-400">
|
||||||
|
Create and configure relays to securely access private network resources from Infisical
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Input
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
||||||
|
placeholder="Search relay..."
|
||||||
|
className="flex-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TableContainer className="mt-4">
|
||||||
|
<Table>
|
||||||
|
<THead>
|
||||||
|
<Tr>
|
||||||
|
<Th className="w-1/3">Name</Th>
|
||||||
|
<Th>Host</Th>
|
||||||
|
<Th>Created</Th>
|
||||||
|
<Th className="w-5" />
|
||||||
|
</Tr>
|
||||||
|
</THead>
|
||||||
|
<TBody>
|
||||||
|
{isRelaysLoading && (
|
||||||
|
<TableSkeleton innerKey="relay-table" columns={4} key="relay-table" />
|
||||||
|
)}
|
||||||
|
{filteredRelays?.map((el) => (
|
||||||
|
<Tr key={el.id}>
|
||||||
|
<Td>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span>{el.name}</span>
|
||||||
|
{!el.orgId && (
|
||||||
|
<Tooltip content="This is a managed relay provided by Infisical">
|
||||||
|
<span className="rounded bg-mineshaft-700 px-1.5 py-0.5 text-xs text-mineshaft-400">
|
||||||
|
Managed
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td>{el.host}</Td>
|
||||||
|
<Td>{formatRelative(new Date(el.createdAt), new Date())}</Td>
|
||||||
|
<Td className="w-5">
|
||||||
|
<Tooltip className="max-w-sm text-center" content="Options">
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="Options"
|
||||||
|
colorSchema="secondary"
|
||||||
|
className="w-6"
|
||||||
|
variant="plain"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faEllipsisV} />
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem
|
||||||
|
icon={<FontAwesomeIcon icon={faCopy} />}
|
||||||
|
onClick={() => navigator.clipboard.writeText(el.id)}
|
||||||
|
>
|
||||||
|
Copy ID
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<OrgPermissionCan
|
||||||
|
I={OrgRelayPermissionActions.DeleteRelays}
|
||||||
|
a={OrgPermissionSubjects.Relay}
|
||||||
|
>
|
||||||
|
{(isAllowed: boolean) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
isDisabled={!isAllowed || !el.orgId}
|
||||||
|
icon={<FontAwesomeIcon icon={faTrash} />}
|
||||||
|
className="text-red"
|
||||||
|
onClick={() => handlePopUpOpen("deleteRelay", el)}
|
||||||
|
>
|
||||||
|
Delete Relay
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Tooltip>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</TBody>
|
||||||
|
</Table>
|
||||||
|
{!isRelaysLoading && !filteredRelays?.length && (
|
||||||
|
<EmptyState
|
||||||
|
title={
|
||||||
|
relays?.length ? "No Relays match search..." : "No Relays have been configured"
|
||||||
|
}
|
||||||
|
icon={relays?.length ? faSearch : faDoorClosed}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DeleteActionModal
|
||||||
|
isOpen={popUp.deleteRelay.isOpen}
|
||||||
|
title={`Are you sure you want to delete relay ${
|
||||||
|
(popUp?.deleteRelay?.data as { name: string })?.name || ""
|
||||||
|
}?`}
|
||||||
|
onChange={(isOpen) => handlePopUpToggle("deleteRelay", isOpen)}
|
||||||
|
deleteKey="confirm"
|
||||||
|
onDeleteApproved={() => handleDeleteRelay()}
|
||||||
|
/>
|
||||||
|
</TableContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ action: OrgRelayPermissionActions.ListRelays, subject: OrgPermissionSubjects.Relay }
|
||||||
|
);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { RelayTab } from "./RelayTab";
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export { GatewayTab } from "./GatewayTab/GatewayTab";
|
||||||
|
export { NetworkingTabGroup } from "./NetworkingTabGroup/NetworkingTabGroup";
|
||||||
|
export { RelayTab } from "./RelayTab/RelayTab";
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
|
||||||
|
import { zodValidator } from "@tanstack/zod-adapter";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { NetworkingPage } from "./NetworkingPage";
|
||||||
|
|
||||||
|
const NetworkingPageQueryParams = z.object({
|
||||||
|
selectedTab: z.string().catch("")
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Route = createFileRoute(
|
||||||
|
"/_authenticate/_inject-org-details/_org-layout/organization/networking/"
|
||||||
|
)({
|
||||||
|
component: NetworkingPage,
|
||||||
|
validateSearch: zodValidator(NetworkingPageQueryParams),
|
||||||
|
search: {
|
||||||
|
middlewares: [stripSearchParams({ selectedTab: "" })]
|
||||||
|
},
|
||||||
|
context: () => ({
|
||||||
|
breadcrumbs: [
|
||||||
|
{
|
||||||
|
label: "Networking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
||||||
+46
-122
@@ -62,8 +62,7 @@ import { Route as organizationIdentityDetailsByIDPageRouteImport } from './pages
|
|||||||
import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route'
|
import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route'
|
||||||
import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route'
|
import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route'
|
||||||
import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route'
|
import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route'
|
||||||
import { Route as organizationGatewaysRelayRelayListPageRouteImport } from './pages/organization/Gateways/Relay/RelayListPage/route'
|
import { Route as organizationNetworkingPageRouteImport } from './pages/organization/NetworkingPage/route'
|
||||||
import { Route as organizationGatewaysGatewayListPageRouteImport } from './pages/organization/Gateways/GatewayListPage/route'
|
|
||||||
import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route'
|
import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route'
|
||||||
import { Route as sshLayoutImport } from './pages/ssh/layout'
|
import { Route as sshLayoutImport } from './pages/ssh/layout'
|
||||||
import { Route as secretScanningLayoutImport } from './pages/secret-scanning/layout'
|
import { Route as secretScanningLayoutImport } from './pages/secret-scanning/layout'
|
||||||
@@ -256,13 +255,9 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport =
|
|||||||
createFileRoute(
|
createFileRoute(
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing',
|
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing',
|
||||||
)()
|
)()
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysImport =
|
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport =
|
||||||
createFileRoute(
|
createFileRoute(
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/relays',
|
'/_authenticate/_inject-org-details/_org-layout/organization/networking',
|
||||||
)()
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport =
|
|
||||||
createFileRoute(
|
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways',
|
|
||||||
)()
|
)()
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport =
|
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport =
|
||||||
createFileRoute(
|
createFileRoute(
|
||||||
@@ -564,18 +559,10 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute =
|
|||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRoute =
|
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute =
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysImport.update({
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport.update({
|
||||||
id: '/relays',
|
id: '/networking',
|
||||||
path: '/relays',
|
path: '/networking',
|
||||||
getParentRoute: () =>
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
|
||||||
} as any)
|
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute =
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport.update({
|
|
||||||
id: '/gateways',
|
|
||||||
path: '/gateways',
|
|
||||||
getParentRoute: () =>
|
getParentRoute: () =>
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
||||||
} as any)
|
} as any)
|
||||||
@@ -778,20 +765,12 @@ const organizationSecretSharingPageRouteRoute =
|
|||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
const organizationGatewaysRelayRelayListPageRouteRoute =
|
const organizationNetworkingPageRouteRoute =
|
||||||
organizationGatewaysRelayRelayListPageRouteImport.update({
|
organizationNetworkingPageRouteImport.update({
|
||||||
id: '/',
|
id: '/',
|
||||||
path: '/',
|
path: '/',
|
||||||
getParentRoute: () =>
|
getParentRoute: () =>
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRoute,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute,
|
||||||
} as any)
|
|
||||||
|
|
||||||
const organizationGatewaysGatewayListPageRouteRoute =
|
|
||||||
organizationGatewaysGatewayListPageRouteImport.update({
|
|
||||||
id: '/',
|
|
||||||
path: '/',
|
|
||||||
getParentRoute: () =>
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute,
|
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
const organizationAppConnectionsAppConnectionsPageRouteRoute =
|
const organizationAppConnectionsAppConnectionsPageRouteRoute =
|
||||||
@@ -2390,18 +2369,11 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport
|
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||||
}
|
}
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways': {
|
'/_authenticate/_inject-org-details/_org-layout/organization/networking': {
|
||||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/gateways'
|
id: '/_authenticate/_inject-org-details/_org-layout/organization/networking'
|
||||||
path: '/gateways'
|
path: '/networking'
|
||||||
fullPath: '/organization/gateways'
|
fullPath: '/organization/networking'
|
||||||
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport
|
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
|
||||||
}
|
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/relays': {
|
|
||||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/relays'
|
|
||||||
path: '/relays'
|
|
||||||
fullPath: '/organization/relays'
|
|
||||||
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysImport
|
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||||
}
|
}
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': {
|
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': {
|
||||||
@@ -2432,19 +2404,12 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof organizationAppConnectionsAppConnectionsPageRouteImport
|
preLoaderRoute: typeof organizationAppConnectionsAppConnectionsPageRouteImport
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport
|
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport
|
||||||
}
|
}
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways/': {
|
'/_authenticate/_inject-org-details/_org-layout/organization/networking/': {
|
||||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/gateways/'
|
id: '/_authenticate/_inject-org-details/_org-layout/organization/networking/'
|
||||||
path: '/'
|
path: '/'
|
||||||
fullPath: '/organization/gateways/'
|
fullPath: '/organization/networking/'
|
||||||
preLoaderRoute: typeof organizationGatewaysGatewayListPageRouteImport
|
preLoaderRoute: typeof organizationNetworkingPageRouteImport
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport
|
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport
|
||||||
}
|
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/relays/': {
|
|
||||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/relays/'
|
|
||||||
path: '/'
|
|
||||||
fullPath: '/organization/relays/'
|
|
||||||
preLoaderRoute: typeof organizationGatewaysRelayRelayListPageRouteImport
|
|
||||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysImport
|
|
||||||
}
|
}
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': {
|
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': {
|
||||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/'
|
id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/'
|
||||||
@@ -3754,34 +3719,18 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithCh
|
|||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteChildren,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteChildren,
|
||||||
)
|
)
|
||||||
|
|
||||||
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteChildren {
|
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren {
|
||||||
organizationGatewaysGatewayListPageRouteRoute: typeof organizationGatewaysGatewayListPageRouteRoute
|
organizationNetworkingPageRouteRoute: typeof organizationNetworkingPageRouteRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteChildren =
|
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren =
|
||||||
{
|
{
|
||||||
organizationGatewaysGatewayListPageRouteRoute:
|
organizationNetworkingPageRouteRoute: organizationNetworkingPageRouteRoute,
|
||||||
organizationGatewaysGatewayListPageRouteRoute,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren =
|
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren =
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute._addFileChildren(
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute._addFileChildren(
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteChildren,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren,
|
||||||
)
|
|
||||||
|
|
||||||
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteChildren {
|
|
||||||
organizationGatewaysRelayRelayListPageRouteRoute: typeof organizationGatewaysRelayRelayListPageRouteRoute
|
|
||||||
}
|
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteChildren =
|
|
||||||
{
|
|
||||||
organizationGatewaysRelayRelayListPageRouteRoute:
|
|
||||||
organizationGatewaysRelayRelayListPageRouteRoute,
|
|
||||||
}
|
|
||||||
|
|
||||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteWithChildren =
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRoute._addFileChildren(
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteChildren,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren {
|
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren {
|
||||||
@@ -3825,8 +3774,7 @@ interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren {
|
|||||||
organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute
|
organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute
|
||||||
organizationProjectsPageRouteRoute: typeof organizationProjectsPageRouteRoute
|
organizationProjectsPageRouteRoute: typeof organizationProjectsPageRouteRoute
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteWithChildren
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||||
organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute
|
organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute
|
||||||
@@ -3844,10 +3792,8 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren: Authentica
|
|||||||
organizationProjectsPageRouteRoute: organizationProjectsPageRouteRoute,
|
organizationProjectsPageRouteRoute: organizationProjectsPageRouteRoute,
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute:
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute:
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren,
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute:
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute:
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren,
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRoute:
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteWithChildren,
|
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute:
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute:
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren,
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren,
|
||||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute:
|
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute:
|
||||||
@@ -4746,14 +4692,12 @@ export interface FileRoutesByFullPath {
|
|||||||
'/admin/environment': typeof adminEnvironmentPageRouteRoute
|
'/admin/environment': typeof adminEnvironmentPageRouteRoute
|
||||||
'/admin/integrations': typeof adminIntegrationsPageRouteRoute
|
'/admin/integrations': typeof adminIntegrationsPageRouteRoute
|
||||||
'/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
'/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||||
'/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
'/organization/networking': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren
|
||||||
'/organization/relays': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteWithChildren
|
|
||||||
'/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
'/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||||
'/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
'/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||||
'/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
'/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
||||||
'/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
'/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||||
'/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute
|
'/organization/networking/': typeof organizationNetworkingPageRouteRoute
|
||||||
'/organization/relays/': typeof organizationGatewaysRelayRelayListPageRouteRoute
|
|
||||||
'/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
'/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
||||||
'/organization/settings/': typeof organizationSettingsPageRouteRoute
|
'/organization/settings/': typeof organizationSettingsPageRouteRoute
|
||||||
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||||
@@ -4969,8 +4913,7 @@ export interface FileRoutesByTo {
|
|||||||
'/admin/integrations': typeof adminIntegrationsPageRouteRoute
|
'/admin/integrations': typeof adminIntegrationsPageRouteRoute
|
||||||
'/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
'/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
||||||
'/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
'/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||||
'/organization/gateways': typeof organizationGatewaysGatewayListPageRouteRoute
|
'/organization/networking': typeof organizationNetworkingPageRouteRoute
|
||||||
'/organization/relays': typeof organizationGatewaysRelayRelayListPageRouteRoute
|
|
||||||
'/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute
|
'/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute
|
||||||
'/organization/settings': typeof organizationSettingsPageRouteRoute
|
'/organization/settings': typeof organizationSettingsPageRouteRoute
|
||||||
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||||
@@ -5189,14 +5132,12 @@ export interface FileRoutesById {
|
|||||||
'/_authenticate/_inject-org-details/admin/_admin-layout/environment': typeof adminEnvironmentPageRouteRoute
|
'/_authenticate/_inject-org-details/admin/_admin-layout/environment': typeof adminEnvironmentPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/admin/_admin-layout/integrations': typeof adminIntegrationsPageRouteRoute
|
'/_authenticate/_inject-org-details/admin/_admin-layout/integrations': typeof adminIntegrationsPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
'/_authenticate/_inject-org-details/_org-layout/organization/networking': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/relays': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRelaysRouteWithChildren
|
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
'/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute
|
'/_authenticate/_inject-org-details/_org-layout/organization/networking/': typeof organizationNetworkingPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/relays/': typeof organizationGatewaysRelayRelayListPageRouteRoute
|
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/': typeof organizationSettingsPageRouteRoute
|
'/_authenticate/_inject-org-details/_org-layout/organization/settings/': typeof organizationSettingsPageRouteRoute
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
'/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||||
@@ -5422,14 +5363,12 @@ export interface FileRouteTypes {
|
|||||||
| '/admin/environment'
|
| '/admin/environment'
|
||||||
| '/admin/integrations'
|
| '/admin/integrations'
|
||||||
| '/organization/app-connections'
|
| '/organization/app-connections'
|
||||||
| '/organization/gateways'
|
| '/organization/networking'
|
||||||
| '/organization/relays'
|
|
||||||
| '/organization/secret-sharing'
|
| '/organization/secret-sharing'
|
||||||
| '/organization/settings'
|
| '/organization/settings'
|
||||||
| '/secret-manager/$projectId'
|
| '/secret-manager/$projectId'
|
||||||
| '/organization/app-connections/'
|
| '/organization/app-connections/'
|
||||||
| '/organization/gateways/'
|
| '/organization/networking/'
|
||||||
| '/organization/relays/'
|
|
||||||
| '/organization/secret-sharing/'
|
| '/organization/secret-sharing/'
|
||||||
| '/organization/settings/'
|
| '/organization/settings/'
|
||||||
| '/organization/groups/$groupId'
|
| '/organization/groups/$groupId'
|
||||||
@@ -5644,8 +5583,7 @@ export interface FileRouteTypes {
|
|||||||
| '/admin/integrations'
|
| '/admin/integrations'
|
||||||
| '/secret-manager/$projectId'
|
| '/secret-manager/$projectId'
|
||||||
| '/organization/app-connections'
|
| '/organization/app-connections'
|
||||||
| '/organization/gateways'
|
| '/organization/networking'
|
||||||
| '/organization/relays'
|
|
||||||
| '/organization/secret-sharing'
|
| '/organization/secret-sharing'
|
||||||
| '/organization/settings'
|
| '/organization/settings'
|
||||||
| '/organization/groups/$groupId'
|
| '/organization/groups/$groupId'
|
||||||
@@ -5862,14 +5800,12 @@ export interface FileRouteTypes {
|
|||||||
| '/_authenticate/_inject-org-details/admin/_admin-layout/environment'
|
| '/_authenticate/_inject-org-details/admin/_admin-layout/environment'
|
||||||
| '/_authenticate/_inject-org-details/admin/_admin-layout/integrations'
|
| '/_authenticate/_inject-org-details/admin/_admin-layout/integrations'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/gateways'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/networking'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/relays'
|
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId'
|
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/gateways/'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/networking/'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/relays/'
|
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings/'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/settings/'
|
||||||
| '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId'
|
| '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId'
|
||||||
@@ -6290,8 +6226,7 @@ export const routeTree = rootRoute
|
|||||||
"/_authenticate/_inject-org-details/_org-layout/organization/billing",
|
"/_authenticate/_inject-org-details/_org-layout/organization/billing",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/projects",
|
"/_authenticate/_inject-org-details/_org-layout/organization/projects",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/app-connections",
|
"/_authenticate/_inject-org-details/_org-layout/organization/app-connections",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways",
|
"/_authenticate/_inject-org-details/_org-layout/organization/networking",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/relays",
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing",
|
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings",
|
"/_authenticate/_inject-org-details/_org-layout/organization/settings",
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId",
|
"/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId",
|
||||||
@@ -6366,18 +6301,11 @@ export const routeTree = rootRoute
|
|||||||
"/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback"
|
"/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways": {
|
"/_authenticate/_inject-org-details/_org-layout/organization/networking": {
|
||||||
"filePath": "",
|
"filePath": "",
|
||||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization",
|
"parent": "/_authenticate/_inject-org-details/_org-layout/organization",
|
||||||
"children": [
|
"children": [
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways/"
|
"/_authenticate/_inject-org-details/_org-layout/organization/networking/"
|
||||||
]
|
|
||||||
},
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/relays": {
|
|
||||||
"filePath": "",
|
|
||||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization",
|
|
||||||
"children": [
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/relays/"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing": {
|
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing": {
|
||||||
@@ -6407,13 +6335,9 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "organization/AppConnections/AppConnectionsPage/route.tsx",
|
"filePath": "organization/AppConnections/AppConnectionsPage/route.tsx",
|
||||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/app-connections"
|
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/app-connections"
|
||||||
},
|
},
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways/": {
|
"/_authenticate/_inject-org-details/_org-layout/organization/networking/": {
|
||||||
"filePath": "organization/Gateways/GatewayListPage/route.tsx",
|
"filePath": "organization/NetworkingPage/route.tsx",
|
||||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/gateways"
|
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/networking"
|
||||||
},
|
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/relays/": {
|
|
||||||
"filePath": "organization/Gateways/Relay/RelayListPage/route.tsx",
|
|
||||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/relays"
|
|
||||||
},
|
},
|
||||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/": {
|
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/": {
|
||||||
"filePath": "organization/SecretSharingPage/route.tsx",
|
"filePath": "organization/SecretSharingPage/route.tsx",
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ const organizationRoutes = route("/organization", [
|
|||||||
"organization/AppConnections/OauthCallbackPage/route.tsx"
|
"organization/AppConnections/OauthCallbackPage/route.tsx"
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
route("/gateways", [index("organization/Gateways/GatewayListPage/route.tsx")]),
|
route("/networking", [index("organization/NetworkingPage/route.tsx")])
|
||||||
route("/relays", [index("organization/Gateways/Relay/RelayListPage/route.tsx")])
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const secretManagerRoutes = route("/projects/secret-management/$projectId", [
|
const secretManagerRoutes = route("/projects/secret-management/$projectId", [
|
||||||
|
|||||||
Reference in New Issue
Block a user