diff --git a/server/routers/accessToken/listAccessTokens.ts b/server/routers/accessToken/listAccessTokens.ts index 6ac2c936..c3874c0c 100644 --- a/server/routers/accessToken/listAccessTokens.ts +++ b/server/routers/accessToken/listAccessTokens.ts @@ -5,7 +5,8 @@ import { resources, userResources, roleResources, - resourceAccessToken + resourceAccessToken, + sites } from "@server/db/schema"; import response from "@server/lib/response"; import HttpCode from "@server/types/HttpCode"; @@ -59,7 +60,8 @@ function queryAccessTokens( title: resourceAccessToken.title, description: resourceAccessToken.description, createdAt: resourceAccessToken.createdAt, - resourceName: resources.name + resourceName: resources.name, + siteName: sites.name }; if (orgId) { @@ -70,6 +72,10 @@ function queryAccessTokens( resources, eq(resourceAccessToken.resourceId, resources.resourceId) ) + .leftJoin( + sites, + eq(resources.resourceId, sites.siteId) + ) .where( and( inArray( @@ -91,6 +97,10 @@ function queryAccessTokens( resources, eq(resourceAccessToken.resourceId, resources.resourceId) ) + .leftJoin( + sites, + eq(resources.resourceId, sites.siteId) + ) .where( and( inArray( diff --git a/server/routers/resource/getResource.ts b/server/routers/resource/getResource.ts index d832e852..3c40f47b 100644 --- a/server/routers/resource/getResource.ts +++ b/server/routers/resource/getResource.ts @@ -1,7 +1,7 @@ import { Request, Response, NextFunction } from "express"; import { z } from "zod"; import { db } from "@server/db"; -import { Resource, resources } from "@server/db/schema"; +import { Resource, resources, sites } from "@server/db/schema"; import { eq } from "drizzle-orm"; import response from "@server/lib/response"; import HttpCode from "@server/types/HttpCode"; @@ -18,7 +18,9 @@ const getResourceSchema = z }) .strict(); -export type GetResourceResponse = Resource; +export type GetResourceResponse = Resource & { + siteName: string; +}; export async function getResource( req: Request, @@ -38,13 +40,17 @@ export async function getResource( const { resourceId } = parsedParams.data; - const resource = await db + const [resp] = await db .select() .from(resources) .where(eq(resources.resourceId, resourceId)) + .leftJoin(sites, eq(sites.siteId, resources.siteId)) .limit(1); - if (resource.length === 0) { + const resource = resp.resources; + const site = resp.sites; + + if (!resource) { return next( createHttpError( HttpCode.NOT_FOUND, @@ -54,7 +60,10 @@ export async function getResource( } return response(res, { - data: resource[0], + data: { + ...resource, + siteName: site?.name + }, success: true, error: false, message: "Resource retrieved successfully", diff --git a/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx b/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx index 89b6d050..0ab634d6 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx @@ -1,7 +1,7 @@ "use client"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { InfoIcon, ShieldCheck, ShieldOff } from "lucide-react"; +import { ArrowRight, InfoIcon, ShieldCheck, ShieldOff } from "lucide-react"; import { useResourceContext } from "@app/hooks/useResourceContext"; import { Separator } from "@app/components/ui/separator"; import CopyToClipboard from "@app/components/CopyToClipboard"; @@ -11,6 +11,7 @@ import { InfoSections, InfoSectionTitle } from "@app/components/InfoSection"; +import Link from "next/link"; type ResourceInfoBoxType = {}; @@ -26,7 +27,7 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) { Resource Information - + {resource.http ? ( <> @@ -40,22 +41,16 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) { authInfo.whitelist ? (
- - This resource is protected with - at least one authentication method. - + Protected
) : (
- - Anyone can access this resource. - + Not Protected
)}
- URL @@ -65,6 +60,12 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) { /> + + Site + + {resource.siteName} + + ) : ( <> @@ -76,7 +77,6 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) { - Port diff --git a/src/app/[orgId]/settings/resources/[resourceId]/general/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/general/page.tsx index c3a313e4..b60c68dc 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/general/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/general/page.tsx @@ -265,6 +265,12 @@ export default function GeneralForm() { description: "The resource has been transferred successfully" }); router.refresh(); + + updateResource({ + siteName: + sites.find((site) => site.siteId === data.siteId)?.name || + "" + }); } setTransferLoading(false); } @@ -606,9 +612,7 @@ export default function GeneralForm() { - + No sites found. diff --git a/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx b/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx index e91be2f2..fcae3741 100644 --- a/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx +++ b/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx @@ -107,7 +107,12 @@ export default function CreateShareLinkForm({ const [isOpen, setIsOpen] = useState(false); const [resources, setResources] = useState< - { resourceId: number; name: string; resourceUrl: string }[] + { + resourceId: number; + name: string; + resourceUrl: string; + siteName: string | null; + }[] >([]); const timeUnits = [ @@ -159,7 +164,8 @@ export default function CreateShareLinkForm({ .map((r) => ({ resourceId: r.resourceId, name: r.name, - resourceUrl: `${r.ssl ? "https://" : "http://"}${r.fullDomain}/` + resourceUrl: `${r.ssl ? "https://" : "http://"}${r.fullDomain}/`, + siteName: r.siteName })) ); } @@ -231,19 +237,28 @@ export default function CreateShareLinkForm({ token.accessToken ); setDirectLink(directLink); + + const resource = resources.find((r) => r.resourceId === values.resourceId); + onCreated?.({ accessTokenId: token.accessTokenId, resourceId: token.resourceId, resourceName: values.resourceName, title: token.title, createdAt: token.createdAt, - expiresAt: token.expiresAt + expiresAt: token.expiresAt, + siteName: resource?.siteName || null, }); } setLoading(false); } + function getSelectedResourceName(id: number) { + const resource = resources.find((r) => r.resourceId === id); + return `${resource?.name} ${resource?.siteName ? `(${resource.siteName})` : ""}`; + } + return ( <> {field.value - ? resources.find( - ( - r - ) => - r.resourceId === - field.value + ? getSelectedResourceName( + field.value ) - ?.name : "Select resource"} @@ -348,9 +358,7 @@ export default function CreateShareLinkForm({ : "opacity-0" )} /> - { - r.name - } + {`${r.name} ${r.siteName ? `(${r.siteName})` : ""}`} ) )} diff --git a/src/app/[orgId]/settings/share-links/ShareLinksTable.tsx b/src/app/[orgId]/settings/share-links/ShareLinksTable.tsx index 2acc1399..7d19b2b6 100644 --- a/src/app/[orgId]/settings/share-links/ShareLinksTable.tsx +++ b/src/app/[orgId]/settings/share-links/ShareLinksTable.tsx @@ -41,6 +41,7 @@ export type ShareLinkRow = { title: string | null; createdAt: number; expiresAt: number | null; + siteName: string | null; }; type ShareLinksTableProps = { @@ -145,7 +146,8 @@ export default function ShareLinksTable({ return ( @@ -274,20 +276,21 @@ export default function ShareLinksTable({ return "Never"; } }, - { + { id: "delete", cell: ({ row }) => (
) } - ]; return ( diff --git a/src/app/[orgId]/settings/sites/[niceId]/SiteInfoCard.tsx b/src/app/[orgId]/settings/sites/[niceId]/SiteInfoCard.tsx index 2a05606c..ee4758be 100644 --- a/src/app/[orgId]/settings/sites/[niceId]/SiteInfoCard.tsx +++ b/src/app/[orgId]/settings/sites/[niceId]/SiteInfoCard.tsx @@ -3,7 +3,6 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { InfoIcon } from "lucide-react"; import { useSiteContext } from "@app/hooks/useSiteContext"; -import { Separator } from "@app/components/ui/separator"; import { InfoSection, InfoSectionContent, @@ -33,7 +32,7 @@ export default function SiteInfoCard({}: SiteInfoCardProps) { Site Information - + {(site.type == "newt" || site.type == "wireguard") && ( <> @@ -52,8 +51,6 @@ export default function SiteInfoCard({}: SiteInfoCardProps) { )}
- - )} diff --git a/src/components/InfoSection.tsx b/src/components/InfoSection.tsx index 51f096b2..bc87f0df 100644 --- a/src/components/InfoSection.tsx +++ b/src/components/InfoSection.tsx @@ -1,8 +1,16 @@ "use client"; -export function InfoSections({ children }: { children: React.ReactNode }) { +export function InfoSections({ + children, + cols +}: { + children: React.ReactNode; + cols?: number; +}) { return ( -
+
{children}
); @@ -23,9 +31,3 @@ export function InfoSectionContent({ }) { return
{children}
; } - -export function Divider() { - return ( -
- ); -}