diff --git a/messages/en-US.json b/messages/en-US.json index 5bd4249d9..be70e0781 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -220,8 +220,9 @@ "resourceRawDescriptionCloud": "Proxy requests over raw TCP/UDP using a port number. Requires sites to connect to a remote node.", "resourceCreate": "Create Resource", "resourceCreateDescription": "Follow the steps below to create a new resource", + "resourceCreateGeneralDescription": "Configure the basic resource settings including the name and the type", "resourceSeeAll": "See All Resources", - "resourceInfo": "Resource Information", + "resourceCreateGeneral": "General", "resourceNameDescription": "This is the display name for the resource.", "siteSelect": "Select site", "siteSearch": "Search site", @@ -231,9 +232,11 @@ "noCountryFound": "No country found.", "siteSelectionDescription": "This site will provide connectivity to the target.", "resourceType": "Resource Type", - "resourceTypeDescription": "Determine how to access the resource", + "resourceTypeDescription": "This controls the resource protocol and how it will be rendered in the browser. This can’t be changed later.", + "resourceDomainDescription": "The resource will be served at this fully qualified domain name.", "resourceHTTPSSettings": "HTTPS Settings", "resourceHTTPSSettingsDescription": "Configure how the resource will be accessed over HTTPS", + "resourcePortDescription": "The external port on the Pangolin instance or node where the resource will be accessible.", "domainType": "Domain Type", "subdomain": "Subdomain", "baseDomain": "Base Domain", @@ -1982,9 +1985,9 @@ "sshServerMode": "Mode", "sshServerModeStandard": "Standard SSH Server", "sshServerModePangolin": "Pangolin SSH", - "sshServerModeStandardDescription": "Uses a Pangolin auth daemon to manage SSH authentication on the site or remote host.", + "sshServerModeStandardDescription": "Routes commands over network to an SSH server such as OpenSSH.", "sshServerModeNative": "Native SSH Server", - "sshServerModeNativeDescription": "SSH authentication is handled natively by an existing SSH server without a separate auth daemon.", + "sshServerModeNativeDescription": "Executes commands directly on the host via the Site Connector. No network config required.", "sshAuthenticationMethod": "Authentication Method", "sshAuthMethodManual": "Manual Authentication", "sshAuthMethodManualDescription": "Requires existing host credentials. Bypasses automatic provisioning.", @@ -3354,5 +3357,6 @@ "memberPortalResourceDisabled": "Resource Disabled", "memberPortalShowingResources": "Showing {start}-{end} of {total} resources", "memberPortalPrevious": "Previous", - "memberPortalNext": "Next" + "memberPortalNext": "Next", + "httpSettings": "HTTP Settings" } diff --git a/src/app/[orgId]/settings/resources/proxy/create/page.tsx b/src/app/[orgId]/settings/resources/proxy/create/page.tsx index 7ba53c8bd..513adcc20 100644 --- a/src/app/[orgId]/settings/resources/proxy/create/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/create/page.tsx @@ -19,7 +19,14 @@ import { SettingsSectionTitle } from "@app/components/Settings"; import HeaderTitle from "@app/components/SettingsSectionTitle"; -import { StrategySelect, type StrategyOption } from "@app/components/StrategySelect"; +import { + OptionSelect, + type OptionSelectOption +} from "@app/components/OptionSelect"; +import { + StrategySelect, + type StrategyOption +} from "@app/components/StrategySelect"; import { ResourceTargetAddressItem } from "@app/components/resource-target-address-item"; import { BrowserGatewayTargetForm } from "@app/components/BrowserGatewayTargetForm"; import { @@ -565,7 +572,9 @@ export default function Page() { } const res = await api - .put>(`/org/${orgId}/resource/`, payload) + .put< + AxiosResponse + >(`/org/${orgId}/resource/`, payload) .catch((e) => { toast({ variant: "destructive", @@ -880,9 +889,7 @@ export default function Page() { variant="outline" size="sm" className="h-7 text-xs gap-1" - onClick={() => - openHealthCheckDialog(row.original) - } + onClick={() => openHealthCheckDialog(row.original)} > {row.original.hcEnabled ? ( @@ -1224,6 +1231,12 @@ export default function Page() { udp: "UDP" }; + const typeOptions: OptionSelectOption[] = + availableTypes.map((type) => ({ + value: type, + label: typeLabels[type] + })); + return ( <>
@@ -1249,14 +1262,14 @@ export default function Page() { - {t("resourceInfo")} + {t("resourceCreateGeneral")} {t("resourceCreateDescription")} - + {/* Name */}
{t("type")}

-
- {availableTypes.map((type) => ( - - ))} -
+ + options={typeOptions} + value={resourceType} + onChange={setResourceType} + cols={6} + />

{t("resourceTypeDescription")}

@@ -1327,24 +1324,32 @@ export default function Page() { {/* Domain/Subdomain (HTTP-based types) */} {isHttpResource && ( - = 1 - } - onDomainChange={(res) => { - if (!res) return; - httpForm.setValue( - "subdomain", - res.subdomain - ); - httpForm.setValue( - "domainId", - res.domainId - ); - }} - /> +
+ = + 1 + } + onDomainChange={(res) => { + if (!res) return; + httpForm.setValue( + "subdomain", + res.subdomain + ); + httpForm.setValue( + "domainId", + res.domainId + ); + }} + /> +

+ {t( + "resourceDomainDescription" + )} +

+
)} {/* Proxy Port (TCP/UDP types) */} @@ -1396,6 +1401,11 @@ export default function Page() { /> + + {t( + "resourcePortDescription" + )} + )} /> @@ -1786,7 +1796,8 @@ export default function Page() { {table.getRowModel() - .rows?.length ? ( + .rows + ?.length ? ( table .getRowModel() .rows.map(