feat: show warning in AppLink if hostname is long enough to break port forwarding (#19506)

closes #15178 

<img width="1840" height="1191" alt="image"
src="https://github.com/user-attachments/assets/26d2002a-fa2f-46eb-9c06-b29420123f0a"
/>
This commit is contained in:
Andrew Aquino
2025-08-27 11:51:41 -07:00
committed by GitHub
parent fe01ae767e
commit 6c01a772eb
2 changed files with 40 additions and 2 deletions
@@ -168,6 +168,21 @@ export const InternalApp: Story = {
},
};
export const InternalAppHostnameTooLong: Story = {
args: {
workspace: MockWorkspace,
app: {
...MockWorkspaceApp,
display_name: "Check my URL",
subdomain: true,
subdomain_name:
// 64 characters long; surpasses DNS hostname limit of 63 characters
"app_name_makes_subdomain64--agent_name--workspace_name--username",
},
agent: MockWorkspaceAgent,
},
};
export const BlockingStartupScriptRunning: Story = {
args: {
workspace: MockWorkspace,
+25 -2
View File
@@ -1,5 +1,6 @@
import type * as TypesGen from "api/typesGenerated";
import { DropdownMenuItem } from "components/DropdownMenu/DropdownMenu";
import { Link } from "components/Link/Link";
import { Spinner } from "components/Spinner/Spinner";
import {
Tooltip,
@@ -11,7 +12,7 @@ import { useProxy } from "contexts/ProxyContext";
import { CircleAlertIcon } from "lucide-react";
import { isExternalApp, needsSessionToken } from "modules/apps/apps";
import { useAppLink } from "modules/apps/useAppLink";
import { type FC, useState } from "react";
import { type FC, type ReactNode, useState } from "react";
import { AgentButton } from "../AgentButton";
import { BaseIcon } from "./BaseIcon";
import { ShareIcon } from "./ShareIcon";
@@ -48,7 +49,7 @@ export const AppLink: FC<AppLinkProps> = ({
// To avoid bugs in the healthcheck code locking users out of apps, we no
// longer block access to apps if they are unhealthy/initializing.
let canClick = true;
let primaryTooltip = "";
let primaryTooltip: ReactNode = "";
let icon = !iconError && (
<BaseIcon app={app} onIconPathError={() => setIconError(true)} />
);
@@ -80,6 +81,28 @@ export const AppLink: FC<AppLinkProps> = ({
"Your admin has not configured subdomain application access";
}
if (app.subdomain_name && app.subdomain_name.length > 63) {
icon = (
<CircleAlertIcon
aria-hidden="true"
className="size-icon-sm text-content-warning"
/>
);
primaryTooltip = (
<>
Port forwarding will not work because hostname is too long, see the{" "}
<Link
href="https://coder.com/docs/user-guides/workspace-access/port-forwarding#dashboard"
target="_blank"
size="sm"
>
documentation
</Link>{" "}
for more details
</>
);
}
if (isExternalApp(app) && needsSessionToken(app) && !link.hasToken) {
canClick = false;
}