From 18e6f16ce7448be0472619158e0354a2857c9c1a Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Mon, 28 Apr 2025 21:45:43 -0400 Subject: [PATCH] add snippets to create resource --- server/license/license.ts | 3 +- .../resources/[resourceId]/proxy/page.tsx | 78 +- .../settings/resources/create/page.tsx | 1030 +++++++++-------- .../share-links/CreateShareLinkForm.tsx | 12 +- src/app/components/LicenseViolation.tsx | 7 +- 5 files changed, 634 insertions(+), 496 deletions(-) diff --git a/server/license/license.ts b/server/license/license.ts index b1398d13..3f01effd 100644 --- a/server/license/license.ts +++ b/server/license/license.ts @@ -137,7 +137,8 @@ LQIDAQAB hostId: this.hostId, isHostLicensed: true, isLicenseValid: false, - maxSites: undefined + maxSites: undefined, + usedSites: siteCount.value }; try { diff --git a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx index 8c027d30..ea388176 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx @@ -67,6 +67,12 @@ import { SwitchInput } from "@app/components/SwitchInput"; import { useRouter } from "next/navigation"; import { isTargetValid } from "@server/lib/validators"; import { tlsNameSchema } from "@server/lib/schemas"; +import { ChevronsUpDown } from "lucide-react"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger +} from "@app/components/ui/collapsible"; const addTargetSchema = z.object({ ip: z.string().refine(isTargetValid), @@ -145,6 +151,7 @@ export default function ReverseProxyTargets(props: { const [proxySettingsLoading, setProxySettingsLoading] = useState(false); const [pageLoading, setPageLoading] = useState(true); + const [isAdvancedOpen, setIsAdvancedOpen] = useState(false); const router = useRouter(); const addTargetForm = useForm({ @@ -589,26 +596,57 @@ export default function ReverseProxyTargets(props: { )} /> - ( - - - TLS Server Name (SNI) - - - - - - The TLS Server Name to use - for SNI. Leave empty to use - the default. - - - - )} - /> + +
+ + + +
+ + ( + + + TLS Server Name + (SNI) + + + + + + The TLS Server Name + to use for SNI. + Leave empty to use + the default. + + + + )} + /> + +
diff --git a/src/app/[orgId]/settings/resources/create/page.tsx b/src/app/[orgId]/settings/resources/create/page.tsx index d500a809..704a1947 100644 --- a/src/app/[orgId]/settings/resources/create/page.tsx +++ b/src/app/[orgId]/settings/resources/create/page.tsx @@ -59,6 +59,9 @@ import { } from "@app/components/ui/popover"; import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons"; import { cn } from "@app/lib/cn"; +import { SquareArrowOutUpRight } from "lucide-react"; +import CopyTextBox from "@app/components/CopyTextBox"; +import Link from "next/link"; const baseResourceFormSchema = z.object({ name: z.string().min(1).max(255), @@ -108,6 +111,8 @@ export default function Page() { { domainId: string; baseDomain: string }[] >([]); const [createLoading, setCreateLoading] = useState(false); + const [showSnippets, setShowSnippets] = useState(false); + const [resourceId, setResourceId] = useState(null); const resourceTypes: ReadonlyArray = [ { @@ -202,7 +207,14 @@ export default function Page() { if (res && res.status === 201) { const id = res.data.data.resourceId; - router.push(`/${orgId}/settings/resources/${id}`); + setResourceId(id); + + if (isHttp) { + router.push(`/${orgId}/settings/resources/${id}`); + } else { + setShowSnippets(true); + router.refresh(); + } } } catch (e) { console.error("Error creating resource:", e); @@ -301,466 +313,132 @@ export default function Page() { {!loadingPage && (
- - - - - Resource Information - - - - -
- - ( - - - Name - - - - - - - This is the display - name for the - resource. - - - )} - /> - - ( - - - Site - - - - - - - - - - - - - No - site - found. - - - {sites.map( - ( - site - ) => ( - { - baseForm.setValue( - "siteId", - site.siteId - ); - }} - > - - { - site.name - } - - ) - )} - - - - - - - - This site will - provide connectivity - to the resource. - - - )} - /> - - -
-
-
- - - - - Resource Type - - - Determine how you want to access your - resource - - - - { - baseForm.setValue( - "http", - value === "http" - ); - }} - cols={2} - /> - - - - {baseForm.watch("http") ? ( + {!showSnippets ? ( + - HTTPS Settings + Resource Information - - Configure how your resource will be - accessed over HTTPS - -
+ - {env.flags - .allowBaseDomainResources && ( - ( - - - Domain Type - - - - - )} - /> - )} - - {!httpForm.watch( - "isBaseDomain" - ) && ( - - - Subdomain - -
-
- ( - - - - - - - )} - /> -
-
- ( - - - - - )} - /> -
-
- - The subdomain where - your resource will - be accessible. - -
- )} - - {httpForm.watch( - "isBaseDomain" - ) && ( - ( - - - Base Domain - - - - - )} - /> - )} - - -
-
-
- ) : ( - - - - TCP/UDP Settings - - - Configure how your resource will be - accessed over TCP/UDP - - - - -
- - ( - Protocol + Name - + + + + + This is the + display name for + the resource. + )} /> ( - + - Port Number + Site - - - field.onChange( - e - .target - .value - ? parseInt( - e - .target - .value + + + + + + + + + + + + No + site + found. + + + {sites.map( + ( + site + ) => ( + { + baseForm.setValue( + "siteId", + site.siteId + ); + }} + > + + { + site.name + } + + ) + )} + + + + + - The external - port number to - proxy requests. + This site will + provide + connectivity to + the resource. )} @@ -770,37 +448,461 @@ export default function Page() { - )} - -
- - -
+ {baseForm.watch("http") ? ( + + + + HTTPS Settings + + + Configure how your resource will be + accessed over HTTPS + + + + + + + {env.flags + .allowBaseDomainResources && ( + ( + + + Domain + Type + + + + + )} + /> + )} + + {!httpForm.watch( + "isBaseDomain" + ) && ( + + + Subdomain + +
+
+ ( + + + + + + + )} + /> +
+
+ ( + + + + + )} + /> +
+
+ + The subdomain + where your + resource will be + accessible. + +
+ )} + + {httpForm.watch( + "isBaseDomain" + ) && ( + ( + + + Base + Domain + + + + + )} + /> + )} + + +
+
+
+ ) : ( + + + + TCP/UDP Settings + + + Configure how your resource will be + accessed over TCP/UDP + + + + +
+ + ( + + + Protocol + + + + + )} + /> + + ( + + + Port Number + + + + field.onChange( + e + .target + .value + ? parseInt( + e + .target + .value + ) + : undefined + ) + } + /> + + + + The external + port number + to proxy + requests. + + + )} + /> + + +
+
+
+ )} + +
+ + +
+
+ ) : ( + + + + + Configuration Snippets + + + Copy and paste these configuration snippets to set up your TCP/UDP resource + + + +
+
+

+ Traefik: Add Entrypoints +

+ +
+ +
+

+ Gerbil: Expose Ports in Docker Compose +

+ +
+ + + + Learn how to configure TCP/UDP resources + + + +
+
+
+ +
+ + +
+
+ )}
)} diff --git a/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx b/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx index bc8701ad..871f0ca0 100644 --- a/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx +++ b/src/app/[orgId]/settings/share-links/CreateShareLinkForm.tsx @@ -57,9 +57,7 @@ import { import { CheckIcon, ChevronsUpDown } from "lucide-react"; import { Checkbox } from "@app/components/ui/checkbox"; import { GenerateAccessTokenResponse } from "@server/routers/accessToken"; -import { - constructShareLink -} from "@app/lib/shareLinks"; +import { constructShareLink } from "@app/lib/shareLinks"; import { ShareLinkRow } from "./ShareLinksTable"; import { QRCodeCanvas, QRCodeSVG } from "qrcode.react"; import { @@ -528,11 +526,9 @@ export default function CreateShareLinkForm({ accessTokenId } token={accessToken} - resourceUrl={ - form.getValues( - "resourceUrl" - ) - } + resourceUrl={form.getValues( + "resourceUrl" + )} /> diff --git a/src/app/components/LicenseViolation.tsx b/src/app/components/LicenseViolation.tsx index 6e1a58be..1771475c 100644 --- a/src/app/components/LicenseViolation.tsx +++ b/src/app/components/LicenseViolation.tsx @@ -33,9 +33,10 @@ export default function LicenseViolation() { return (

- License Violation: Using {licenseStatus.usedSites} sites - exceeds your licensed limit of {licenseStatus.maxSites}{" "} - sites. Follow license terms to continue using all features. + License Violation: This server is using{" "} + {licenseStatus.usedSites} sites which exceeds its licensed + limit of {licenseStatus.maxSites} sites. Follow license + terms to continue using all features.

);