diff --git a/frontend/src/const/routes.ts b/frontend/src/const/routes.ts index 2e835a1db..a31306818 100644 --- a/frontend/src/const/routes.ts +++ b/frontend/src/const/routes.ts @@ -66,7 +66,11 @@ export const ROUTE_PATHS = Object.freeze({ "/organization/app-connections/$appConnection/oauth/callback", "/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback" ) - } + }, + NetworkingPage: setRoute( + "/organization/networking", + "/_authenticate/_inject-org-details/_org-layout/organization/networking" + ) }, SecretManager: { ApprovalPage: setRoute( diff --git a/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/GatewayTab.tsx b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/GatewayTab.tsx index 27ebb6820..d5e79d326 100644 --- a/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/GatewayTab.tsx +++ b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/GatewayTab.tsx @@ -8,6 +8,7 @@ import { faEllipsisV, faInfoCircle, faMagnifyingGlass, + faPlus, faSearch, faTrash } from "@fortawesome/free-solid-svg-icons"; @@ -17,6 +18,7 @@ import { useQuery } from "@tanstack/react-query"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { + Button, DeleteActionModal, DropdownMenu, DropdownMenuContent, @@ -47,6 +49,7 @@ import { gatewaysQueryKeys, useDeleteGatewayById } from "@app/hooks/api/gateways import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2"; import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal"; +import { DeployGatewayModal } from "./components/DeployGatewayModal"; const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => { const heartbeatDate = heartbeat ? new Date(heartbeat) : null; @@ -73,6 +76,7 @@ export const GatewayTab = withPermission( const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list()); const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ + "deployGateway", "deleteGateway", "editDetails" ] as const); @@ -101,8 +105,8 @@ export const GatewayTab = withPermission( return (
-
-
+
+

Gateways

+
+

@@ -257,6 +269,10 @@ export const GatewayTab = withPermission( deleteKey="confirm" onDeleteApproved={() => handleDeleteGateway()} /> + handlePopUpToggle("deployGateway", isOpen)} + />

diff --git a/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployGatewayModal.tsx b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployGatewayModal.tsx new file mode 100644 index 000000000..2b8f17fe7 --- /dev/null +++ b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployGatewayModal.tsx @@ -0,0 +1,243 @@ +import { createNotification } from "@app/components/notifications"; +import { + FilterableSelect, + FormLabel, + IconButton, + Input, + Modal, + ModalContent +} from "@app/components/v2"; +import { useOrganization } from "@app/context"; +import { + useAddIdentityTokenAuth, + useCreateTokenIdentityTokenAuth, + useGetIdentityMembershipOrgs, + useGetIdentityTokenAuth +} from "@app/hooks/api"; +import { useGetRelays } from "@app/hooks/api/relays"; +import { slugSchema } from "@app/lib/schemas"; +import { faCopy, faUpRightFromSquare } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useEffect, useMemo, useState } from "react"; +import { SingleValue } from "react-select"; +import { RelayOption } from "./RelayOption"; +import { useNavigate } from "@tanstack/react-router"; +import { ROUTE_PATHS } from "@app/const/routes"; +import { twMerge } from "tailwind-merge"; + +type Props = { + isOpen: boolean; + onOpenChange: (isOpen: boolean) => void; +}; + +export const DeployGatewayModal = ({ isOpen, onOpenChange }: Props) => { + const { protocol, hostname, port } = window.location; + const portSuffix = port && port !== "80" ? `:${port}` : ""; + const siteURL = `${protocol}//${hostname}${portSuffix}`; + + const navigate = useNavigate({ + from: ROUTE_PATHS.Organization.NetworkingPage.path + }); + + const [name, setName] = useState(""); + const [relay, setRelay] = useState(null); + const [identity, setIdentity] = useState(null); + const [identityToken, setIdentityToken] = useState(""); + + useEffect(() => { + if (!isOpen) { + setName(""); + setRelay(null); + setIdentity(null); + setIdentityToken(""); + } + }, [isOpen]); + + const { data: relays, isPending: isRelaysLoading } = useGetRelays(); + + const { currentOrg } = useOrganization(); + const organizationId = currentOrg?.id || ""; + + const { data: identityMembershipOrgsData, isPending: isIdentitiesLoading } = + useGetIdentityMembershipOrgs({ + organizationId, + limit: 20000 + }); + const identityMembershipOrgs = identityMembershipOrgsData?.identityMemberships || []; + + const { mutateAsync: createToken } = useCreateTokenIdentityTokenAuth(); + const { mutateAsync: addIdentityTokenAuth } = useAddIdentityTokenAuth(); + const { refetch } = useGetIdentityTokenAuth(identity?.id ?? ""); + + useEffect(() => { + const generateToken = async () => { + if (!identity) return; + + try { + const { data: identityTokenAuth } = await refetch(); + if (!identityTokenAuth) { + await addIdentityTokenAuth({ + identityId: identity.id, + organizationId, + accessTokenTTL: 2592000, + accessTokenMaxTTL: 2592000, + accessTokenNumUsesLimit: 0, + accessTokenTrustedIps: [{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }] + }); + createNotification({ + text: "Automatically enabled token authentication for this identity.", + type: "info" + }); + } + + const token = await createToken({ + identityId: identity.id, + name: "gateway token (autogenerated)" + }); + setIdentityToken(token.accessToken); + createNotification({ + text: "Automatically generated a token for this identity.", + type: "info" + }); + } catch (err) { + console.error(err); + createNotification({ + text: "Failed to generate token for identity", + type: "error" + }); + setIdentityToken(""); + } + }; + + generateToken(); + }, [identity, organizationId, refetch, addIdentityTokenAuth, createToken]); + + const handleIdentityChange = (selectedIdentity: SingleValue<{ id: string; name: string }>) => { + setIdentity(selectedIdentity); + setIdentityToken(""); + }; + + const isNameValid = useMemo(() => !name || slugSchema().safeParse(name).success, [name]); + + const isCommandReady = useMemo( + () => !!name && isNameValid && !!relay && !!identityToken, + [name, isNameValid, relay, identityToken] + ); + + const command = useMemo( + () => + `infisical gateway start --name=${name} --relay=${ + relay?.name || "" + } --domain=${siteURL} --token=${identityToken}`, + [name, relay, identityToken, siteURL] + ); + + return ( + + + + setName(e.target.value)} + placeholder="Enter gateway name..." + isError={!isNameValid} + /> + + + { + if ((newValue as SingleValue<{ id: string }>)?.id === "_create") { + navigate({ + search: { selectedTab: "relays" } + }); + return; + } + + setRelay(newValue as SingleValue<{ id: string; name: string }>); + }} + isLoading={isRelaysLoading} + options={[ + { + id: "_create", + name: "Deploy New Relay" + }, + ...(relays || []) + ]} + placeholder="Select relay..." + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + components={{ Option: RelayOption }} + /> + + + + handleIdentityChange( + e as SingleValue<{ + id: string; + name: string; + }> + ) + } + isLoading={isIdentitiesLoading} + placeholder="Select identity..." + options={identityMembershipOrgs.map((membership) => membership.identity)} + getOptionValue={(option) => option.id} + getOptionLabel={(option) => option.name} + /> + + +
+ + { + navigator.clipboard.writeText(command); + + createNotification({ + text: "Command copied to clipboard", + type: "info" + }); + }} + className={twMerge("w-10", !isCommandReady && "pointer-events-none opacity-50")} + isDisabled={!isCommandReady} + > + + +
+ + Install the Infisical CLI + + +
+
+ ); +}; diff --git a/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployRelayModal.tsx b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployRelayModal.tsx new file mode 100644 index 000000000..2347c0472 --- /dev/null +++ b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/DeployRelayModal.tsx @@ -0,0 +1,204 @@ +import { createNotification } from "@app/components/notifications"; +import { + FilterableSelect, + FormLabel, + IconButton, + Input, + Modal, + ModalContent +} from "@app/components/v2"; +import { useOrganization } from "@app/context"; +import { + useAddIdentityTokenAuth, + useCreateTokenIdentityTokenAuth, + useGetIdentityMembershipOrgs, + useGetIdentityTokenAuth +} from "@app/hooks/api"; +import { slugSchema } from "@app/lib/schemas"; +import { faCopy, faUpRightFromSquare } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useEffect, useMemo, useState } from "react"; +import { SingleValue } from "react-select"; +import { twMerge } from "tailwind-merge"; + +type Props = { + isOpen: boolean; + onOpenChange: (isOpen: boolean) => void; +}; + +export const DeployRelayModal = ({ isOpen, onOpenChange }: Props) => { + const { protocol, hostname, port } = window.location; + const portSuffix = port && port !== "80" ? `:${port}` : ""; + const siteURL = `${protocol}//${hostname}${portSuffix}`; + + const [name, setName] = useState(""); + const [host, setHost] = useState(""); + const [identity, setIdentity] = useState(null); + const [identityToken, setIdentityToken] = useState(""); + + useEffect(() => { + if (!isOpen) { + setName(""); + setHost(""); + setIdentity(null); + setIdentityToken(""); + } + }, [isOpen]); + + const { currentOrg } = useOrganization(); + const organizationId = currentOrg?.id || ""; + + const { data: identityMembershipOrgsData, isPending: isIdentitiesLoading } = + useGetIdentityMembershipOrgs({ + organizationId, + limit: 20000 + }); + const identityMembershipOrgs = identityMembershipOrgsData?.identityMemberships || []; + + const { mutateAsync: createToken } = useCreateTokenIdentityTokenAuth(); + const { mutateAsync: addIdentityTokenAuth } = useAddIdentityTokenAuth(); + const { refetch } = useGetIdentityTokenAuth(identity?.id ?? ""); + + useEffect(() => { + const generateToken = async () => { + if (!identity) return; + + try { + const { data: identityTokenAuth } = await refetch(); + if (!identityTokenAuth) { + await addIdentityTokenAuth({ + identityId: identity.id, + organizationId, + accessTokenTTL: 2592000, + accessTokenMaxTTL: 2592000, + accessTokenNumUsesLimit: 0, + accessTokenTrustedIps: [{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }] + }); + createNotification({ + text: "Automatically enabled token authentication for this identity.", + type: "info" + }); + } + + const token = await createToken({ + identityId: identity.id, + name: "relay token (autogenerated)" + }); + setIdentityToken(token.accessToken); + createNotification({ + text: "Automatically generated a token for this identity.", + type: "info" + }); + } catch (err) { + console.error(err); + createNotification({ + text: "Failed to generate token for identity", + type: "error" + }); + setIdentityToken(""); + } + }; + + generateToken(); + }, [identity, organizationId, refetch, addIdentityTokenAuth, createToken]); + + const handleIdentityChange = (selectedIdentity: SingleValue<{ id: string; name: string }>) => { + setIdentity(selectedIdentity); + setIdentityToken(""); + }; + + const isNameValid = useMemo(() => !name || slugSchema().safeParse(name).success, [name]); + + const isCommandReady = useMemo( + () => !!name && !!host && isNameValid && !!identityToken, + [name, isNameValid, host, identityToken] + ); + + const command = useMemo( + () => + `infisical relay start --name=${name} --domain=${siteURL} --host=${host} --token=${identityToken}`, + [name, siteURL, host, identityToken] + ); + + return ( + + + + setName(e.target.value)} + placeholder="Enter relay name..." + isError={!isNameValid} + /> + + + setHost(e.target.value)} placeholder="0.0.0.0" /> + + + + handleIdentityChange( + e as SingleValue<{ + id: string; + name: string; + }> + ) + } + isLoading={isIdentitiesLoading} + placeholder="Select identity..." + options={identityMembershipOrgs.map((membership) => membership.identity)} + getOptionValue={(option) => option.id} + getOptionLabel={(option) => option.name} + /> + + +
+ + { + navigator.clipboard.writeText(command); + + createNotification({ + text: "Command copied to clipboard", + type: "info" + }); + }} + className={twMerge("w-10", !isCommandReady && "pointer-events-none opacity-50")} + isDisabled={!isCommandReady} + > + + +
+ + Install the Infisical CLI + + +
+
+ ); +}; diff --git a/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/RelayOption.tsx b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/RelayOption.tsx new file mode 100644 index 000000000..90c9a7ebd --- /dev/null +++ b/frontend/src/pages/organization/NetworkingPage/components/GatewayTab/components/RelayOption.tsx @@ -0,0 +1,32 @@ +import { components, OptionProps } from "react-select"; +import { faCheckCircle } from "@fortawesome/free-regular-svg-icons"; +import { faPlus } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +export const RelayOption = ({ + isSelected, + children, + ...props +}: OptionProps<{ id: string; name: string }>) => { + const isCreateOption = props.data.id === "_create"; + + return ( + +
+ {isCreateOption ? ( +
+ + Deploy New Relay +
+ ) : ( + <> +

{children}

+ {isSelected && ( + + )} + + )} +
+
+ ); +}; diff --git a/frontend/src/pages/organization/NetworkingPage/components/NetworkingTabGroup/NetworkingTabGroup.tsx b/frontend/src/pages/organization/NetworkingPage/components/NetworkingTabGroup/NetworkingTabGroup.tsx index 956a4d1ed..dc90b7f21 100644 --- a/frontend/src/pages/organization/NetworkingPage/components/NetworkingTabGroup/NetworkingTabGroup.tsx +++ b/frontend/src/pages/organization/NetworkingPage/components/NetworkingTabGroup/NetworkingTabGroup.tsx @@ -1,14 +1,19 @@ -import { useState } from "react"; -import { useSearch } from "@tanstack/react-router"; +import { useNavigate, useSearch } from "@tanstack/react-router"; import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { GatewayTab } from "../GatewayTab/GatewayTab"; import { RelayTab } from "../RelayTab/RelayTab"; +import { ROUTE_PATHS } from "@app/const/routes"; export const NetworkingTabGroup = () => { - const search = useSearch({ - from: "/_authenticate/_inject-org-details/_org-layout/organization/networking/" + const navigate = useNavigate({ + from: ROUTE_PATHS.Organization.NetworkingPage.path + }); + const selectedTab = useSearch({ + from: ROUTE_PATHS.Organization.NetworkingPage.id, + select: (el) => el.selectedTab, + structuralSharing: true }); const tabs = [ @@ -16,10 +21,14 @@ export const NetworkingTabGroup = () => { { name: "Relays", key: "relays", component: RelayTab } ]; - const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key); + const handleTabChange = (tab: string) => { + navigate({ + search: { selectedTab: tab } + }); + }; return ( - + {tabs.map((tab) => ( diff --git a/frontend/src/pages/organization/NetworkingPage/components/RelayTab/RelayTab.tsx b/frontend/src/pages/organization/NetworkingPage/components/RelayTab/RelayTab.tsx index e525b765d..2bfa8b250 100644 --- a/frontend/src/pages/organization/NetworkingPage/components/RelayTab/RelayTab.tsx +++ b/frontend/src/pages/organization/NetworkingPage/components/RelayTab/RelayTab.tsx @@ -7,6 +7,7 @@ import { faEllipsisV, faInfoCircle, faMagnifyingGlass, + faPlus, faSearch, faTrash } from "@fortawesome/free-solid-svg-icons"; @@ -16,6 +17,7 @@ import { formatRelative } from "date-fns"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { + Button, DeleteActionModal, DropdownMenu, DropdownMenuContent, @@ -41,6 +43,7 @@ import { import { withPermission } from "@app/hoc"; import { usePopUp } from "@app/hooks"; import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays"; +import { DeployRelayModal } from "../GatewayTab/components/DeployRelayModal"; const RelayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => { const heartbeatDate = heartbeat ? new Date(heartbeat) : null; @@ -66,7 +69,10 @@ export const RelayTab = withPermission( const [search, setSearch] = useState(""); const { data: relays, isPending: isRelaysLoading } = useGetRelays(); - const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteRelay"] as const); + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ + "deleteRelay", + "deployRelay" + ] as const); const deleteRelayById = useDeleteRelayById(); @@ -87,8 +93,8 @@ export const RelayTab = withPermission( return (
-
-
+
+

Relays

+
+

@@ -222,6 +236,10 @@ export const RelayTab = withPermission( deleteKey="confirm" onDeleteApproved={() => handleDeleteRelay()} /> + handlePopUpToggle("deployRelay", isOpen)} + />

diff --git a/frontend/src/pages/organization/NetworkingPage/route.tsx b/frontend/src/pages/organization/NetworkingPage/route.tsx index 906b12806..433647476 100644 --- a/frontend/src/pages/organization/NetworkingPage/route.tsx +++ b/frontend/src/pages/organization/NetworkingPage/route.tsx @@ -5,16 +5,16 @@ import { z } from "zod"; import { NetworkingPage } from "./NetworkingPage"; const NetworkingPageQueryParams = z.object({ - selectedTab: z.string().catch("") + selectedTab: z.string().catch("gateways") }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organization/networking/" + "/_authenticate/_inject-org-details/_org-layout/organization/networking" )({ component: NetworkingPage, validateSearch: zodValidator(NetworkingPageQueryParams), search: { - middlewares: [stripSearchParams({ selectedTab: "" })] + middlewares: [stripSearchParams({ selectedTab: "gateways" })] }, context: () => ({ breadcrumbs: [ diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index 1562f302d..bc92b6ef0 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -50,6 +50,7 @@ import { Route as adminCachingPageRouteImport } from './pages/admin/CachingPage/ import { Route as adminAuthenticationPageRouteImport } from './pages/admin/AuthenticationPage/route' import { Route as adminAccessManagementPageRouteImport } from './pages/admin/AccessManagementPage/route' import { Route as organizationProjectsPageRouteImport } from './pages/organization/ProjectsPage/route' +import { Route as organizationNetworkingPageRouteImport } from './pages/organization/NetworkingPage/route' import { Route as organizationBillingPageRouteImport } from './pages/organization/BillingPage/route' import { Route as organizationAuditLogsPageRouteImport } from './pages/organization/AuditLogsPage/route' import { Route as organizationAccessManagementPageRouteImport } from './pages/organization/AccessManagementPage/route' @@ -63,7 +64,6 @@ import { Route as organizationIdentityDetailsByIDPageRouteImport } from './pages import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route' import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route' import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route' -import { Route as organizationNetworkingPageRouteImport } from './pages/organization/NetworkingPage/route' import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route' import { Route as sshLayoutImport } from './pages/ssh/layout' import { Route as secretScanningLayoutImport } from './pages/secret-scanning/layout' @@ -270,10 +270,6 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing', )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organization/networking', - )() const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization/app-connections', @@ -594,14 +590,6 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, } as any) -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport.update({ - id: '/networking', - path: '/networking', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, - } as any) - const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport.update({ id: '/app-connections', @@ -658,6 +646,14 @@ const organizationProjectsPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, } as any) +const organizationNetworkingPageRouteRoute = + organizationNetworkingPageRouteImport.update({ + id: '/networking', + path: '/networking', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, + } as any) + const organizationBillingPageRouteRoute = organizationBillingPageRouteImport.update({ id: '/billing', @@ -807,14 +803,6 @@ const organizationSecretSharingPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute, } as any) -const organizationNetworkingPageRouteRoute = - organizationNetworkingPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute, - } as any) - const organizationAppConnectionsAppConnectionsPageRouteRoute = organizationAppConnectionsAppConnectionsPageRouteImport.update({ id: '/', @@ -2477,6 +2465,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationBillingPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } + '/_authenticate/_inject-org-details/_org-layout/organization/networking': { + id: '/_authenticate/_inject-org-details/_org-layout/organization/networking' + path: '/networking' + fullPath: '/organization/networking' + preLoaderRoute: typeof organizationNetworkingPageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport + } '/_authenticate/_inject-org-details/_org-layout/organization/projects': { id: '/_authenticate/_inject-org-details/_org-layout/organization/projects' path: '/projects' @@ -2533,13 +2528,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } - '/_authenticate/_inject-org-details/_org-layout/organization/networking': { - id: '/_authenticate/_inject-org-details/_org-layout/organization/networking' - path: '/networking' - fullPath: '/organization/networking' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport - } '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': { id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' path: '/secret-sharing' @@ -2568,13 +2556,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationAppConnectionsAppConnectionsPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport } - '/_authenticate/_inject-org-details/_org-layout/organization/networking/': { - id: '/_authenticate/_inject-org-details/_org-layout/organization/networking/' - path: '/' - fullPath: '/organization/networking/' - preLoaderRoute: typeof organizationNetworkingPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingImport - } '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': { id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/' path: '/' @@ -4002,20 +3983,6 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithCh AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren { - organizationNetworkingPageRouteRoute: typeof organizationNetworkingPageRouteRoute -} - -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren = - { - organizationNetworkingPageRouteRoute: organizationNetworkingPageRouteRoute, - } - -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteChildren, - ) - interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren { organizationSecretSharingPageRouteRoute: typeof organizationSecretSharingPageRouteRoute organizationSecretSharingSettingsPageRouteRoute: typeof organizationSecretSharingSettingsPageRouteRoute @@ -4055,9 +4022,9 @@ interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren { organizationAccessManagementPageRouteRoute: typeof organizationAccessManagementPageRouteRoute organizationAuditLogsPageRouteRoute: typeof organizationAuditLogsPageRouteRoute organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute + organizationNetworkingPageRouteRoute: typeof organizationNetworkingPageRouteRoute organizationProjectsPageRouteRoute: typeof organizationProjectsPageRouteRoute AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute @@ -4072,11 +4039,10 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren: Authentica organizationAccessManagementPageRouteRoute, organizationAuditLogsPageRouteRoute: organizationAuditLogsPageRouteRoute, organizationBillingPageRouteRoute: organizationBillingPageRouteRoute, + organizationNetworkingPageRouteRoute: organizationNetworkingPageRouteRoute, organizationProjectsPageRouteRoute: organizationProjectsPageRouteRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute: @@ -5057,6 +5023,7 @@ export interface FileRoutesByFullPath { '/organization/access-management': typeof organizationAccessManagementPageRouteRoute '/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/organization/billing': typeof organizationBillingPageRouteRoute + '/organization/networking': typeof organizationNetworkingPageRouteRoute '/organization/projects': typeof organizationProjectsPageRouteRoute '/admin/access-management': typeof adminAccessManagementPageRouteRoute '/admin/authentication': typeof adminAuthenticationPageRouteRoute @@ -5065,12 +5032,10 @@ export interface FileRoutesByFullPath { '/admin/environment': typeof adminEnvironmentPageRouteRoute '/admin/integrations': typeof adminIntegrationsPageRouteRoute '/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren - '/organization/networking': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren '/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren '/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren '/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/organization/networking/': typeof organizationNetworkingPageRouteRoute '/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute '/organization/settings/': typeof organizationSettingsPageRouteRoute '/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute @@ -5294,6 +5259,7 @@ export interface FileRoutesByTo { '/organization/access-management': typeof organizationAccessManagementPageRouteRoute '/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/organization/billing': typeof organizationBillingPageRouteRoute + '/organization/networking': typeof organizationNetworkingPageRouteRoute '/organization/projects': typeof organizationProjectsPageRouteRoute '/admin/access-management': typeof adminAccessManagementPageRouteRoute '/admin/authentication': typeof adminAuthenticationPageRouteRoute @@ -5303,7 +5269,6 @@ export interface FileRoutesByTo { '/admin/integrations': typeof adminIntegrationsPageRouteRoute '/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/organization/networking': typeof organizationNetworkingPageRouteRoute '/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute '/organization/settings': typeof organizationSettingsPageRouteRoute '/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute @@ -5529,6 +5494,7 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/_org-layout/organization/access-management': typeof organizationAccessManagementPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/billing': typeof organizationBillingPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/organization/networking': typeof organizationNetworkingPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/projects': typeof organizationProjectsPageRouteRoute '/_authenticate/_inject-org-details/admin/_admin-layout/access-management': typeof adminAccessManagementPageRouteRoute '/_authenticate/_inject-org-details/admin/_admin-layout/authentication': typeof adminAuthenticationPageRouteRoute @@ -5537,12 +5503,10 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/admin/_admin-layout/environment': typeof adminEnvironmentPageRouteRoute '/_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/networking': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationNetworkingRouteWithChildren '/_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/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organization/networking/': typeof organizationNetworkingPageRouteRoute '/_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/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute @@ -5778,6 +5742,7 @@ export interface FileRouteTypes { | '/organization/access-management' | '/organization/audit-logs' | '/organization/billing' + | '/organization/networking' | '/organization/projects' | '/admin/access-management' | '/admin/authentication' @@ -5786,12 +5751,10 @@ export interface FileRouteTypes { | '/admin/environment' | '/admin/integrations' | '/organization/app-connections' - | '/organization/networking' | '/organization/secret-sharing' | '/organization/settings' | '/secret-manager/$projectId' | '/organization/app-connections/' - | '/organization/networking/' | '/organization/secret-sharing/' | '/organization/settings/' | '/organization/groups/$groupId' @@ -6014,6 +5977,7 @@ export interface FileRouteTypes { | '/organization/access-management' | '/organization/audit-logs' | '/organization/billing' + | '/organization/networking' | '/organization/projects' | '/admin/access-management' | '/admin/authentication' @@ -6023,7 +5987,6 @@ export interface FileRouteTypes { | '/admin/integrations' | '/secret-manager/$projectId' | '/organization/app-connections' - | '/organization/networking' | '/organization/secret-sharing' | '/organization/settings' | '/organization/groups/$groupId' @@ -6247,6 +6210,7 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/_org-layout/organization/access-management' | '/_authenticate/_inject-org-details/_org-layout/organization/audit-logs' | '/_authenticate/_inject-org-details/_org-layout/organization/billing' + | '/_authenticate/_inject-org-details/_org-layout/organization/networking' | '/_authenticate/_inject-org-details/_org-layout/organization/projects' | '/_authenticate/_inject-org-details/admin/_admin-layout/access-management' | '/_authenticate/_inject-org-details/admin/_admin-layout/authentication' @@ -6255,12 +6219,10 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/admin/_admin-layout/environment' | '/_authenticate/_inject-org-details/admin/_admin-layout/integrations' | '/_authenticate/_inject-org-details/_org-layout/organization/app-connections' - | '/_authenticate/_inject-org-details/_org-layout/organization/networking' | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' | '/_authenticate/_inject-org-details/_org-layout/organization/settings' | '/_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/networking/' | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/' | '/_authenticate/_inject-org-details/_org-layout/organization/settings/' | '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId' @@ -6703,9 +6665,9 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organization/access-management", "/_authenticate/_inject-org-details/_org-layout/organization/audit-logs", "/_authenticate/_inject-org-details/_org-layout/organization/billing", + "/_authenticate/_inject-org-details/_org-layout/organization/networking", "/_authenticate/_inject-org-details/_org-layout/organization/projects", "/_authenticate/_inject-org-details/_org-layout/organization/app-connections", - "/_authenticate/_inject-org-details/_org-layout/organization/networking", "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing", "/_authenticate/_inject-org-details/_org-layout/organization/settings", "/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId", @@ -6744,6 +6706,10 @@ export const routeTree = rootRoute "filePath": "organization/BillingPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" }, + "/_authenticate/_inject-org-details/_org-layout/organization/networking": { + "filePath": "organization/NetworkingPage/route.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/organization" + }, "/_authenticate/_inject-org-details/_org-layout/organization/projects": { "filePath": "organization/ProjectsPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" @@ -6780,13 +6746,6 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback" ] }, - "/_authenticate/_inject-org-details/_org-layout/organization/networking": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/organization", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/organization/networking/" - ] - }, "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing": { "filePath": "", "parent": "/_authenticate/_inject-org-details/_org-layout/organization", @@ -6814,10 +6773,6 @@ export const routeTree = rootRoute "filePath": "organization/AppConnections/AppConnectionsPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization/app-connections" }, - "/_authenticate/_inject-org-details/_org-layout/organization/networking/": { - "filePath": "organization/NetworkingPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organization/networking" - }, "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/": { "filePath": "organization/SecretSharingPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing" diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index bebc50339..e84e5873d 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -40,7 +40,7 @@ const organizationRoutes = route("/organization", [ "organization/AppConnections/OauthCallbackPage/route.tsx" ) ]), - route("/networking", [index("organization/NetworkingPage/route.tsx")]) + route("/networking", "organization/NetworkingPage/route.tsx") ]); const secretManagerRoutes = route("/projects/secret-management/$projectId", [