diff --git a/site/src/modules/resources/AgentRow.tsx b/site/src/modules/resources/AgentRow.tsx index 6dd52bb31b..ae8dadcc39 100644 --- a/site/src/modules/resources/AgentRow.tsx +++ b/site/src/modules/resources/AgentRow.tsx @@ -41,6 +41,7 @@ import { TerminalLink } from "./TerminalLink/TerminalLink"; import { useAgentContainers } from "./useAgentContainers"; import { useAgentLogs } from "./useAgentLogs"; import { VSCodeDesktopButton } from "./VSCodeDesktopButton/VSCodeDesktopButton"; +import { WildcardHostnameWarning } from "./WildcardHostnameWarning"; interface AgentRowProps { agent: WorkspaceAgent; @@ -155,6 +156,10 @@ export const AgentRow: FC = ({ // Check if any devcontainers have errors to gray out agent border const hasDevcontainerErrors = devcontainers?.some((dc) => dc.error); + const hasSubdomainApps = agent.apps?.some((app) => app.subdomain); + const shouldShowWildcardWarning = + hasSubdomainApps && !proxy.proxy?.wildcard_hostname; + return ( = ({ styles.agentRow, styles[`agentRow-${agent.status}`], styles[`agentRow-lifecycle-${agent.lifecycle_state}`], - hasDevcontainerErrors && styles.agentRowWithErrors, + (hasDevcontainerErrors || shouldShowWildcardWarning) && + styles.agentRowWithErrors, ]} >
@@ -226,6 +232,8 @@ export const AgentRow: FC = ({ )} + {shouldShowWildcardWarning && } + {shouldDisplayAppsSection && (
{shouldDisplayAgentApps && ( diff --git a/site/src/modules/resources/WildcardHostnameWarning.tsx b/site/src/modules/resources/WildcardHostnameWarning.tsx new file mode 100644 index 0000000000..2210575ae4 --- /dev/null +++ b/site/src/modules/resources/WildcardHostnameWarning.tsx @@ -0,0 +1,84 @@ +import AlertTitle from "@mui/material/AlertTitle"; +import type { WorkspaceResource } from "api/typesGenerated"; +import { Alert, AlertDetail } from "components/Alert/Alert"; +import { Link } from "components/Link/Link"; +import { useProxy } from "contexts/ProxyContext"; +import { useAuthenticated } from "hooks/useAuthenticated"; +import type { FC } from "react"; +import { docs } from "utils/docs"; + +interface WildcardHostnameWarningProps { + // If resources are provided, show template-focused warning + resources?: WorkspaceResource[]; +} + +export const WildcardHostnameWarning: FC = ({ + resources, +}) => { + const { proxy } = useProxy(); + const { permissions } = useAuthenticated(); + + const hasResources = Boolean(resources); + const canEditDeploymentConfig = Boolean(permissions.editDeploymentConfig); + + if (proxy.proxy?.wildcard_hostname) { + return null; + } + + if (hasResources) { + const hasSubdomainCoderApp = resources!.some((resource) => { + return resource.agents?.some((agent) => + agent.apps?.some((app) => app.subdomain), + ); + }); + + if (!hasSubdomainCoderApp) { + return null; + } + } + + return ( + + Some workspace applications will not work + +
+ {hasResources + ? "This template contains coder_app resources with" + : "One or more apps in this workspace have"}{" "} + + subdomain = true + + {canEditDeploymentConfig ? ( + <> + , but subdomain applications are not configured. Users won't be + able to access these applications until you configure the{" "} + + --wildcard-access-url + {" "} + flag when starting the Coder server. + + ) : ( + ", which requires a Coder deployment with a Wildcard Access URL configured. Please contact your administrator." + )} +
+
+ + + Learn more about wildcard access URL + + +
+
+
+ ); +}; diff --git a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx index 79c990544b..855ccbd19e 100644 --- a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx +++ b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx @@ -37,6 +37,7 @@ import { ProvisionerAlert, } from "modules/provisioners/ProvisionerAlert"; import { ProvisionerStatusAlert } from "modules/provisioners/ProvisionerStatusAlert"; +import { WildcardHostnameWarning } from "modules/resources/WildcardHostnameWarning"; import { isBinaryData } from "modules/templates/TemplateFiles/isBinaryData"; import { TemplateFileTree } from "modules/templates/TemplateFiles/TemplateFileTree"; import { TemplateResourcesTable } from "modules/templates/TemplateResourcesTable/TemplateResourcesTable"; @@ -203,7 +204,7 @@ export const TemplateVersionEditor: FC = ({ if (logsContentRef.current) { logsContentRef.current.scrollTop = logsContentRef.current.scrollHeight; } - }, [buildLogs]); + }, [buildLogs, resources]); useLeaveSiteWarning(dirty); @@ -630,6 +631,10 @@ export const TemplateVersionEditor: FC = ({ logs={buildLogs} /> )} + + {resources && ( + + )} )}