diff --git a/site/src/modules/dashboard/Navbar/ProxyMenu.stories.tsx b/site/src/modules/dashboard/Navbar/ProxyMenu.stories.tsx index 5d61a5777d..4a25ef9605 100644 --- a/site/src/modules/dashboard/Navbar/ProxyMenu.stories.tsx +++ b/site/src/modules/dashboard/Navbar/ProxyMenu.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { fn, userEvent, within } from "storybook/test"; import { getAuthorizationKey } from "#/api/queries/authCheck"; +import type * as TypesGen from "#/api/typesGenerated"; import { AuthProvider } from "#/contexts/auth/AuthProvider"; import { getPreferredProxy } from "#/contexts/ProxyContext"; import { permissionChecks } from "#/modules/permissions"; @@ -14,6 +15,50 @@ import { import { withDesktopViewport } from "#/testHelpers/storybook"; import { ProxyMenu } from "./ProxyMenu"; +const buildProxies = (count: number): TypesGen.WorkspaceProxy[] => { + const seedProxy = MockWorkspaceProxies[0]; + const proxies: TypesGen.WorkspaceProxy[] = []; + + for (let index = 0; index < count; index++) { + const suffix = String(index + 1).padStart(12, "0"); + const id = `10000000-0000-4000-8000-${suffix}`; + const isHealthy = index % 7 !== 0; + + proxies.push({ + ...seedProxy, + id, + name: `region-${index + 1}`, + display_name: `Region ${index + 1}`, + healthy: isHealthy, + }); + } + + return proxies; +}; + +const buildLatencies = ( + proxies: TypesGen.WorkspaceProxy[], +): typeof MockProxyLatencies => { + const latencies: typeof MockProxyLatencies = {}; + + for (const [index, proxy] of proxies.entries()) { + if (!proxy.healthy) { + continue; + } + + latencies[proxy.id] = { + accurate: true, + latencyMS: 20 + index * 3, + at: new Date(), + nextHopProtocol: "h2", + }; + } + + return latencies; +}; + +const manyProxies = buildProxies(45); + const defaultProxyContextValue = { latenciesLoaded: true, proxyLatencies: MockProxyLatencies, @@ -77,3 +122,18 @@ export const SingleProxy: Story = { await userEvent.click(canvas.getByRole("button")); }, }; + +export const ManyProxiesOpened: Story = { + args: { + proxyContextValue: { + ...defaultProxyContextValue, + proxies: manyProxies, + proxyLatencies: buildLatencies(manyProxies), + proxy: getPreferredProxy(manyProxies, undefined), + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await userEvent.click(canvas.getByRole("button")); + }, +}; diff --git a/site/src/modules/dashboard/Navbar/ProxyMenu.tsx b/site/src/modules/dashboard/Navbar/ProxyMenu.tsx index 30ee274066..3070e06d2f 100644 --- a/site/src/modules/dashboard/Navbar/ProxyMenu.tsx +++ b/site/src/modules/dashboard/Navbar/ProxyMenu.tsx @@ -124,51 +124,53 @@ export const ProxyMenu: FC = ({ proxyContextValue }) => { )} {proxyContextValue.proxies && ( - - {sortProxiesByLatency(proxyContextValue.proxies, latencies).map( - (proxy) => ( - { - e.preventDefault(); - if (!proxy.healthy) { - toast.error( - `Failed to select proxy "${proxy.display_name}".`, - { - description: - "Please select a healthy workspace proxy.", - }, - ); - closeMenu(); - return; - } +
+ + {sortProxiesByLatency(proxyContextValue.proxies, latencies).map( + (proxy) => ( + { + e.preventDefault(); + if (!proxy.healthy) { + toast.error( + `Failed to select proxy "${proxy.display_name}".`, + { + description: + "Please select a healthy workspace proxy.", + }, + ); + closeMenu(); + return; + } - proxyContextValue.setProxy(proxy); - closeMenu(); - }} - > -
-
- +
+
+ +
+ + {proxy.display_name} + +
- - {proxy.display_name} - - -
- - ), - )} - + + ), + )} + +
)}