diff --git a/site/src/components/Navbar/Navbar.test.tsx b/site/src/components/Navbar/Navbar.test.tsx index ca7001af5dad7..8bdac69e67443 100644 --- a/site/src/components/Navbar/Navbar.test.tsx +++ b/site/src/components/Navbar/Navbar.test.tsx @@ -1,6 +1,6 @@ import { render, screen, waitFor } from "@testing-library/react" import { App } from "app" -import { Language } from "components/NavbarView/NavbarView" +import { Language } from "./NavbarView" import { rest } from "msw" import { MockEntitlementsWithAuditLog, diff --git a/site/src/components/Navbar/Navbar.tsx b/site/src/components/Navbar/Navbar.tsx index 3e25eed4cb0c0..88042b5bceb8d 100644 --- a/site/src/components/Navbar/Navbar.tsx +++ b/site/src/components/Navbar/Navbar.tsx @@ -4,7 +4,8 @@ import { useFeatureVisibility } from "hooks/useFeatureVisibility" import { useMe } from "hooks/useMe" import { usePermissions } from "hooks/usePermissions" import { FC } from "react" -import { NavbarView } from "../NavbarView/NavbarView" +import { NavbarView } from "./NavbarView" +import { useProxy } from "contexts/ProxyContext" export const Navbar: FC = () => { const { appearance, buildInfo } = useDashboard() @@ -16,6 +17,8 @@ export const Navbar: FC = () => { featureVisibility["audit_log"] && Boolean(permissions.viewAuditLog) const canViewDeployment = Boolean(permissions.viewDeploymentValues) const onSignOut = () => authSend("SIGN_OUT") + const proxyContextValue = useProxy() + const dashboard = useDashboard() return ( { onSignOut={onSignOut} canViewAuditLog={canViewAuditLog} canViewDeployment={canViewDeployment} + proxyContextValue={ + dashboard.experiments.includes("moons") ? proxyContextValue : undefined + } /> ) } diff --git a/site/src/components/NavbarView/NavbarView.stories.tsx b/site/src/components/Navbar/NavbarView.stories.tsx similarity index 100% rename from site/src/components/NavbarView/NavbarView.stories.tsx rename to site/src/components/Navbar/NavbarView.stories.tsx diff --git a/site/src/components/NavbarView/NavbarView.test.tsx b/site/src/components/Navbar/NavbarView.test.tsx similarity index 80% rename from site/src/components/NavbarView/NavbarView.test.tsx rename to site/src/components/Navbar/NavbarView.test.tsx index cae48b7a8ddcf..7c5bf6507fd78 100644 --- a/site/src/components/NavbarView/NavbarView.test.tsx +++ b/site/src/components/Navbar/NavbarView.test.tsx @@ -1,7 +1,26 @@ import { screen } from "@testing-library/react" -import { MockUser, MockUser2 } from "../../testHelpers/entities" +import { + MockPrimaryWorkspaceProxy, + MockUser, + MockUser2, +} from "../../testHelpers/entities" import { render } from "../../testHelpers/renderHelpers" import { Language as navLanguage, NavbarView } from "./NavbarView" +import { ProxyContextValue } from "contexts/ProxyContext" +import { action } from "@storybook/addon-actions" + +const proxyContextValue: ProxyContextValue = { + proxy: { + preferredPathAppURL: "", + preferredWildcardHostname: "", + proxy: MockPrimaryWorkspaceProxy, + }, + isLoading: false, + isFetched: true, + setProxy: jest.fn(), + clearProxy: action("clearProxy"), + proxyLatencies: {}, +} describe("NavbarView", () => { const noop = () => { @@ -23,6 +42,7 @@ describe("NavbarView", () => { it("workspaces nav link has the correct href", async () => { render( { it("templates nav link has the correct href", async () => { render( { it("users nav link has the correct href", async () => { render( { // When render( { it("audit nav link has the correct href", async () => { render( { it("audit nav link is hidden for members", async () => { render( { it("deployment nav link has the correct href", async () => { render( { it("deployment nav link is hidden for members", async () => { render( void canViewAuditLog: boolean canViewDeployment: boolean + proxyContextValue?: ProxyContextValue } export const Language = { @@ -83,7 +95,7 @@ const NavItems: React.FC< ) } -export const NavbarView: React.FC> = ({ +export const NavbarView: FC = ({ user, logo_url, buildInfo, @@ -91,6 +103,7 @@ export const NavbarView: React.FC> = ({ onSignOut, canViewAuditLog, canViewDeployment, + proxyContextValue, }) => { const styles = useStyles() const [isDrawerOpen, setIsDrawerOpen] = useState(false) @@ -145,7 +158,16 @@ export const NavbarView: React.FC> = ({ canViewDeployment={canViewDeployment} /> -
+ + {proxyContextValue && ( + + )} {user && ( > = ({ onSignOut={onSignOut} /> )} -
+ ) } +const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({ + proxyContextValue, +}) => { + const buttonRef = useRef(null) + const [isOpen, setIsOpen] = useState(false) + const selectedProxy = proxyContextValue.proxy.proxy + const closeMenu = () => setIsOpen(false) + const navigate = useNavigate() + + if (!proxyContextValue.isFetched) { + return ( + + ) + } + + return ( + <> + + + {proxyContextValue.proxies?.map((proxy) => ( + { + if (!proxy.healthy) { + displayError("Please select a healthy workspace proxy.") + closeMenu() + return + } + + proxyContextValue.setProxy(proxy) + closeMenu() + }} + key={proxy.id} + selected={proxy.id === selectedProxy?.id} + sx={{ + fontSize: 14, + }} + > + + + + + {proxy.display_name} + + + + ))} + theme.palette.divider }} /> + { + navigate("/settings/workspace-proxies") + }} + > + Proxy settings + + + + ) +} + +const ProxyStatusLatency: FC<{ proxy: TypesGen.Region; latency?: number }> = ({ + proxy, + latency, +}) => { + const theme = useTheme() + let color = theme.palette.success.light + + if (!latency) { + return ( + + theme.palette.text.secondary, + }} + /> + + ) + } + + if (latency >= 300) { + color = theme.palette.error.light + } + + if (!proxy.healthy || latency >= 100) { + color = theme.palette.warning.light + } + + return ( + + {latency.toFixed(0)}ms + + ) +} + const useStyles = makeStyles((theme) => ({ root: { height: navHeight, @@ -192,12 +365,6 @@ const useStyles = makeStyles((theme) => ({ display: "flex", }, }, - profileButton: { - paddingRight: theme.spacing(2), - [theme.breakpoints.up("md")]: { - marginLeft: "auto", - }, - }, mobileMenuButton: { [theme.breakpoints.up("md")]: { display: "none", diff --git a/site/src/components/UsersLayout/UsersLayout.tsx b/site/src/components/UsersLayout/UsersLayout.tsx index e87d651840a54..a4eacd7b80d7d 100644 --- a/site/src/components/UsersLayout/UsersLayout.tsx +++ b/site/src/components/UsersLayout/UsersLayout.tsx @@ -4,7 +4,7 @@ import { makeStyles } from "@mui/styles" import GroupAdd from "@mui/icons-material/GroupAddOutlined" import PersonAdd from "@mui/icons-material/PersonAddOutlined" import { useMachine } from "@xstate/react" -import { USERS_LINK } from "components/NavbarView/NavbarView" +import { USERS_LINK } from "components/Navbar/NavbarView" import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader" import { useFeatureVisibility } from "hooks/useFeatureVisibility" import { usePermissions } from "hooks/usePermissions" diff --git a/site/src/contexts/ProxyContext.tsx b/site/src/contexts/ProxyContext.tsx index 32d3e3ae11d63..42de93234d9f7 100644 --- a/site/src/contexts/ProxyContext.tsx +++ b/site/src/contexts/ProxyContext.tsx @@ -127,8 +127,8 @@ export const ProxyProvider: FC = ({ children }) => { return ( => { // Just overwrite any existing latency. - state[action.proxyID] = action.report - return state + return { + ...state, + [action.proxyID]: action.report, + } } export const useProxyLatency = ( diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx index f23cb7ba8e727..8db1e9493af39 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx @@ -9,10 +9,11 @@ import { HealthyBadge, NotHealthyBadge, } from "components/DeploySettingsLayout/Badges" -import { makeStyles, useTheme } from "@mui/styles" +import { makeStyles } from "@mui/styles" import { combineClasses } from "utils/combineClasses" import { ProxyLatencyReport } from "contexts/useProxyLatency" import { getLatencyColor } from "utils/colors" +import { alpha } from "@mui/material/styles" export const ProxyRow: FC<{ latency?: ProxyLatencyReport @@ -21,7 +22,6 @@ export const ProxyRow: FC<{ preferred: boolean }> = ({ proxy, onSelectRegion, preferred, latency }) => { const styles = useStyles() - const theme = useTheme() const clickable = useClickableTableRow(() => { onSelectRegion(proxy) @@ -47,24 +47,32 @@ export const ProxyRow: FC<{ } avatar={ proxy.icon_url !== "" && ( - + ) } /> - {proxy.path_app_url} - + {proxy.path_app_url} + - - - {latency ? `${latency.latencyMS.toFixed(1)} ms` : "?"} - + + latency + ? getLatencyColor(theme, latency.latencyMS) + : theme.palette.text.secondary, + }} + > + {latency ? `${latency.latencyMS.toFixed(0)} ms` : "Not available"} ) @@ -83,9 +91,11 @@ const ProxyStatus: FC<{ const useStyles = makeStyles((theme) => ({ preferredrow: { - // TODO: What is the best way to show what proxy is currently being used? - backgroundColor: theme.palette.secondary.main, - outline: `3px solid ${theme.palette.secondary.light}`, - outlineOffset: -3, + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.hoverOpacity, + ), + outline: `1px solid ${theme.palette.primary.main}`, + outlineOffset: "-1px", }, })) diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx index 0ae853201328d..fc5ccf87d155e 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx @@ -50,7 +50,9 @@ export const WorkspaceProxyView: FC< Proxy URL Status - Latency + + Latency + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy