mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
fix(site): hide ws proxy on menu when disabled (#11101)
This commit is contained in:
@ -1,32 +1,13 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { AccessURLPage } from "./AccessURLPage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/AccessURL",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet(
|
||||
{ path: "/health/access-url" },
|
||||
<AccessURLPage />,
|
||||
),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/access-url",
|
||||
element: <AccessURLPage />,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -1,29 +1,13 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { DERPPage } from "./DERPPage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/DERP",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet({ path: "/health/derp" }, <DERPPage />),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/derp",
|
||||
element: <DERPPage />,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -1,36 +1,18 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { DERPRegionPage } from "./DERPRegionPage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const firstRegionId = Object.values(MockHealth.derp.regions)[0].region
|
||||
?.RegionID;
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/DERPRegion",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
location: { pathParams: { regionId: firstRegionId } },
|
||||
routing: reactRouterOutlet(
|
||||
{ path: `/health/derp/regions/:regionId` },
|
||||
<DERPRegionPage />,
|
||||
),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/derp/regions/:regionId",
|
||||
element: <DERPRegionPage />,
|
||||
params: { regionId: firstRegionId },
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -1,32 +1,13 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { DatabasePage } from "./DatabasePage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/Database",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet(
|
||||
{ path: "/health/database" },
|
||||
<DatabasePage />,
|
||||
),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/database",
|
||||
element: <DatabasePage />,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -12,22 +12,16 @@ import Tooltip from "@mui/material/Tooltip";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import { NavLink, Outlet } from "react-router-dom";
|
||||
import { css } from "@emotion/css";
|
||||
import { kebabCase } from "lodash/fp";
|
||||
import kebabCase from "lodash/fp/kebabCase";
|
||||
import { Suspense } from "react";
|
||||
import { HealthIcon } from "./Content";
|
||||
import { HealthSeverity } from "api/typesGenerated";
|
||||
import NotificationsOffOutlined from "@mui/icons-material/NotificationsOffOutlined";
|
||||
|
||||
const sections = {
|
||||
derp: "DERP",
|
||||
access_url: "Access URL",
|
||||
websocket: "Websocket",
|
||||
database: "Database",
|
||||
workspace_proxy: "Workspace Proxy",
|
||||
} as const;
|
||||
import { useDashboard } from "components/Dashboard/DashboardProvider";
|
||||
|
||||
export function HealthLayout() {
|
||||
const theme = useTheme();
|
||||
const dashboard = useDashboard();
|
||||
const queryClient = useQueryClient();
|
||||
const { data: healthStatus } = useQuery({
|
||||
...health(),
|
||||
@ -36,6 +30,16 @@ export function HealthLayout() {
|
||||
const { mutate: forceRefresh, isLoading: isRefreshing } = useMutation(
|
||||
refreshHealth(queryClient),
|
||||
);
|
||||
const sections = {
|
||||
derp: "DERP",
|
||||
access_url: "Access URL",
|
||||
websocket: "Websocket",
|
||||
database: "Database",
|
||||
workspace_proxy: dashboard.experiments.includes("moons")
|
||||
? "Workspace Proxy"
|
||||
: undefined,
|
||||
} as const;
|
||||
const visibleSections = filterVisibleSections(sections);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -106,13 +110,13 @@ export function HealthLayout() {
|
||||
}}
|
||||
>
|
||||
{healthStatus.healthy
|
||||
? Object.keys(sections).some(
|
||||
(key) =>
|
||||
healthStatus[key as keyof typeof sections]
|
||||
.warnings !== null &&
|
||||
healthStatus[key as keyof typeof sections].warnings
|
||||
.length > 0,
|
||||
)
|
||||
? Object.keys(visibleSections).some((key) => {
|
||||
const section =
|
||||
healthStatus[key as keyof typeof visibleSections];
|
||||
return (
|
||||
section.warnings && section.warnings.length > 0
|
||||
);
|
||||
})
|
||||
? "All systems operational, but performance might be degraded"
|
||||
: "All systems operational"
|
||||
: "Some issues have been detected"}
|
||||
@ -145,12 +149,13 @@ export function HealthLayout() {
|
||||
</div>
|
||||
|
||||
<nav css={{ display: "flex", flexDirection: "column", gap: 1 }}>
|
||||
{Object.keys(sections)
|
||||
{Object.keys(visibleSections)
|
||||
.sort()
|
||||
.map((key) => {
|
||||
const label = sections[key as keyof typeof sections];
|
||||
const label =
|
||||
visibleSections[key as keyof typeof visibleSections];
|
||||
const healthSection =
|
||||
healthStatus[key as keyof typeof sections];
|
||||
healthStatus[key as keyof typeof visibleSections];
|
||||
|
||||
return (
|
||||
<NavLink
|
||||
@ -218,3 +223,21 @@ export function HealthLayout() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const filterVisibleSections = <T extends object>(sections: T) => {
|
||||
return Object.keys(sections).reduce(
|
||||
(visible, sectionName) => {
|
||||
const sectionValue = sections[sectionName as keyof typeof sections];
|
||||
|
||||
if (!sectionValue) {
|
||||
return visible;
|
||||
}
|
||||
|
||||
return {
|
||||
...visible,
|
||||
[sectionName]: sectionValue,
|
||||
};
|
||||
},
|
||||
{} as Partial<typeof sections>,
|
||||
);
|
||||
};
|
||||
|
@ -1,32 +1,13 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { WebsocketPage } from "./WebsocketPage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/Websocket",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet(
|
||||
{ path: "/health/derp/websocket" },
|
||||
<WebsocketPage />,
|
||||
),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/websocket",
|
||||
element: <WebsocketPage />,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -1,32 +1,13 @@
|
||||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { WorkspaceProxyPage } from "./WorkspaceProxyPage";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
import {
|
||||
reactRouterOutlet,
|
||||
reactRouterParameters,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { useQueryClient } from "react-query";
|
||||
import { MockHealth } from "testHelpers/entities";
|
||||
import { generateMeta } from "./storybook";
|
||||
|
||||
const meta: Meta = {
|
||||
title: "pages/Health/WorkspaceProxy",
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet(
|
||||
{ path: "/health/workspace-proxy" },
|
||||
<WorkspaceProxyPage />,
|
||||
),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["health"], MockHealth);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
...generateMeta({
|
||||
path: "/health/workspace-proxy",
|
||||
element: <WorkspaceProxyPage />,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
@ -4,21 +4,32 @@ import {
|
||||
reactRouterOutlet,
|
||||
RouteDefinition,
|
||||
} from "storybook-addon-react-router-v6";
|
||||
import { MockHealth, MockHealthSettings } from "testHelpers/entities";
|
||||
import {
|
||||
MockBuildInfo,
|
||||
MockEntitlements,
|
||||
MockExperiments,
|
||||
MockHealth,
|
||||
MockHealthSettings,
|
||||
} from "testHelpers/entities";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { HEALTH_QUERY_KEY, HEALTH_QUERY_SETTINGS_KEY } from "api/queries/debug";
|
||||
import { DashboardProvider } from "components/Dashboard/DashboardProvider";
|
||||
import { HealthLayout } from "./HealthLayout";
|
||||
|
||||
type MetaOptions = {
|
||||
element: RouteDefinition;
|
||||
path: string;
|
||||
params?: Record<string, string>;
|
||||
};
|
||||
|
||||
export const generateMeta = ({ element, path }: MetaOptions): Meta => {
|
||||
export const generateMeta = ({ element, path, params }: MetaOptions): Meta => {
|
||||
return {
|
||||
render: HealthLayout,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlet({ path: `/health/${path}` }, element),
|
||||
location: { pathParams: params },
|
||||
routing: reactRouterOutlet({ path }, element),
|
||||
}),
|
||||
},
|
||||
decorators: [
|
||||
@ -28,6 +39,19 @@ export const generateMeta = ({ element, path }: MetaOptions): Meta => {
|
||||
queryClient.setQueryData(HEALTH_QUERY_SETTINGS_KEY, MockHealthSettings);
|
||||
return <Story />;
|
||||
},
|
||||
(Story) => {
|
||||
const queryClient = useQueryClient();
|
||||
queryClient.setQueryData(["buildInfo"], MockBuildInfo);
|
||||
queryClient.setQueryData(["entitlements"], MockEntitlements);
|
||||
queryClient.setQueryData(["experiments"], MockExperiments);
|
||||
queryClient.setQueryData(["appearance"], MockExperiments);
|
||||
|
||||
return (
|
||||
<DashboardProvider>
|
||||
<Story />
|
||||
</DashboardProvider>
|
||||
);
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user