diff --git a/site/src/contexts/ProxyContext.tsx b/site/src/contexts/ProxyContext.tsx index bfbdb43c09..85ab9c395d 100644 --- a/site/src/contexts/ProxyContext.tsx +++ b/site/src/contexts/ProxyContext.tsx @@ -13,6 +13,7 @@ import { cachedQuery } from "#/api/queries/util"; import type { Region, WorkspaceProxy } from "#/api/typesGenerated"; import { useAuthenticated } from "#/hooks/useAuthenticated"; import { useEmbeddedMetadata } from "#/hooks/useEmbeddedMetadata"; +import { useFeatureVisibility } from "#/modules/dashboard/useFeatureVisibility"; import { type ProxyLatencyReport, useProxyLatency } from "./useProxyLatency"; export type Proxies = readonly Region[] | readonly WorkspaceProxy[]; @@ -97,6 +98,7 @@ export const ProxyProvider: FC = ({ children }) => { const { permissions } = useAuthenticated(); const { metadata } = useEmbeddedMetadata(); + const { workspace_proxy: workspaceProxyEnabled } = useFeatureVisibility(); const { data: proxiesResp, @@ -106,11 +108,15 @@ export const ProxyProvider: FC = ({ children }) => { } = useQuery( cachedQuery({ metadata: metadata.regions, - queryKey: ["get-proxies"], + queryKey: ["get-proxies", workspaceProxyEnabled], queryFn: async (): Promise => { - const apiCall = permissions.editWorkspaceProxies - ? API.getWorkspaceProxies - : API.getWorkspaceProxyRegions; + // Detailed proxy status requires the workspace_proxy entitlement. + // Fall back to regions when unlicensed so admins do not hit a + // Premium feature error on every page load. + const apiCall = + permissions.editWorkspaceProxies && workspaceProxyEnabled + ? API.getWorkspaceProxies + : API.getWorkspaceProxyRegions; const resp = await apiCall(); return resp.regions; diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyPage.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyPage.tsx index c0ed076bb8..37a770b098 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyPage.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyPage.tsx @@ -1,5 +1,6 @@ import type { FC } from "react"; import { useProxy } from "#/contexts/ProxyContext"; +import { useFeatureVisibility } from "#/modules/dashboard/useFeatureVisibility"; import { WorkspaceProxyView } from "./WorkspaceProxyView"; const WorkspaceProxyPage: FC = () => { @@ -11,6 +12,7 @@ const WorkspaceProxyPage: FC = () => { isLoading: proxiesLoading, proxy, } = useProxy(); + const { workspace_proxy: workspaceProxyEnabled } = useFeatureVisibility(); return ( { hasLoaded={proxiesFetched} getWorkspaceProxiesError={proxiesError} preferredProxy={proxy.proxy} + showPaywall={!workspaceProxyEnabled} /> ); }; diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx index 132dcb42f0..4c7232ef3c 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx @@ -11,6 +11,9 @@ import { WorkspaceProxyView } from "./WorkspaceProxyView"; const meta: Meta = { title: "pages/UserSettingsPage/WorkspaceProxyView", component: WorkspaceProxyView, + args: { + showPaywall: false, + }, }; export default meta; @@ -36,6 +39,13 @@ export const Example: Story = { }, }; +export const Paywall: Story = { + args: { + ...Example.args, + showPaywall: true, + }, +}; + export const Loading: Story = { args: { ...Example.args, diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx index 4719bf0250..946e8fb6d6 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx @@ -1,9 +1,11 @@ import type { FC } from "react"; import type { Region } from "#/api/typesGenerated"; import { ErrorAlert } from "#/components/Alert/ErrorAlert"; +import { PaywallPremium } from "#/components/Paywall/PaywallPremium"; import { SettingsHeader, SettingsHeaderDescription, + SettingsHeaderDocsLink, SettingsHeaderTitle, } from "#/components/SettingsHeader/SettingsHeader"; import { @@ -16,6 +18,7 @@ import { import { TableEmpty } from "#/components/TableEmpty/TableEmpty"; import { TableLoader } from "#/components/TableLoader/TableLoader"; import type { ProxyLatencyReport } from "#/contexts/useProxyLatency"; +import { docs } from "#/utils/docs"; import { ProxyRow } from "./WorkspaceProxyRow"; interface WorkspaceProxyViewProps { @@ -26,6 +29,7 @@ interface WorkspaceProxyViewProps { hasLoaded: boolean; preferredProxy?: Region; selectProxyError?: unknown; + showPaywall: boolean; } export const WorkspaceProxyView: FC = ({ @@ -35,10 +39,17 @@ export const WorkspaceProxyView: FC = ({ isLoading, hasLoaded, selectProxyError, + showPaywall, }) => { return (
- + + } + > Workspace Proxies Workspace proxies improve terminal and web app connections to @@ -46,28 +57,38 @@ export const WorkspaceProxyView: FC = ({ - {Boolean(getWorkspaceProxiesError) && ( - - )} - {Boolean(selectProxyError) && } + {showPaywall ? ( + + ) : ( + <> + {Boolean(getWorkspaceProxiesError) && ( + + )} + {Boolean(selectProxyError) && } - - - - Proxy - Status - Latency - - - - - -
+ + + + Proxy + Status + Latency + + + + + +
+ + )}
); };