From fba94922b1244351cfb38797622cf5a4e756a037 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 28 Aug 2025 18:08:41 +0000 Subject: [PATCH 01/56] refactor: replace Popover with Tooltip in AgentLatency --- .../components/HelpTooltip/HelpTooltip.tsx | 49 ++++++----- site/src/modules/resources/AgentLatency.tsx | 82 ++++++++++--------- 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.tsx b/site/src/components/HelpTooltip/HelpTooltip.tsx index 2bcaef1eb6847..b05b9934903ed 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.tsx @@ -3,18 +3,16 @@ import { css, type Interpolation, type Theme, - useTheme, } from "@emotion/react"; import Link from "@mui/material/Link"; -import { - Popover, - PopoverContent, - type PopoverContentProps, - type PopoverProps, - PopoverTrigger, - usePopover, -} from "components/deprecated/Popover/Popover"; +import { TooltipContentProps, TooltipProps } from "@radix-ui/react-tooltip"; +import { usePopover } from "components/deprecated/Popover/Popover"; import { Stack } from "components/Stack/Stack"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "components/Tooltip/Tooltip"; import { CircleHelpIcon, ExternalLinkIcon } from "lucide-react"; import { type FC, @@ -23,6 +21,7 @@ import { type PropsWithChildren, type ReactNode, } from "react"; +import { cn } from "utils/cn"; type Icon = typeof CircleHelpIcon; @@ -30,24 +29,23 @@ type Size = "small" | "medium"; export const HelpTooltipIcon = CircleHelpIcon; -export const HelpTooltip: FC = (props) => { - return ; +export const HelpTooltip: FC = (props) => { + return ; }; -export const HelpTooltipContent: FC = (props) => { - const theme = useTheme(); - +export const HelpTooltipContent: FC = ({ + className, + ...props +}) => { return ( - ); }; @@ -76,7 +74,7 @@ export const HelpTooltipTrigger = forwardRef< }); return ( - + - + ); }); @@ -155,6 +153,7 @@ export const HelpTooltipAction: FC = ({ onClick, ariaLabel, }) => { + // TODO dismiss tooltip const popover = usePopover(); return ( diff --git a/site/src/modules/resources/AgentLatency.tsx b/site/src/modules/resources/AgentLatency.tsx index 4be2a4cf52a07..0f5f436b62341 100644 --- a/site/src/modules/resources/AgentLatency.tsx +++ b/site/src/modules/resources/AgentLatency.tsx @@ -1,6 +1,5 @@ import { type Theme, useTheme } from "@emotion/react"; import type { DERPRegion, WorkspaceAgent } from "api/typesGenerated"; -import { PopoverTrigger } from "components/deprecated/Popover/Popover"; import { HelpTooltip, HelpTooltipContent, @@ -8,6 +7,7 @@ import { HelpTooltipTitle, } from "components/HelpTooltip/HelpTooltip"; import { Stack } from "components/Stack/Stack"; +import { TooltipProvider, TooltipTrigger } from "components/Tooltip/Tooltip"; import type { FC } from "react"; import { getLatencyColor } from "utils/latency"; @@ -43,45 +43,47 @@ export const AgentLatency: FC = ({ agent }) => { } return ( - - - - {Math.round(latency.latency_ms)}ms - - - - Latency - - This is the latency overhead on non peer to peer connections. The - first row is the preferred relay. - - - - {Object.entries(agent.latency) - .sort(([, a], [, b]) => a.latency_ms - b.latency_ms) - .map(([regionName, region]) => ( - + + + + {Math.round(latency.latency_ms)}ms + + + + Latency + + This is the latency overhead on non peer to peer connections. The + first row is the preferred relay. + + + + {Object.entries(agent.latency) + .sort(([, a], [, b]) => a.latency_ms - b.latency_ms) + .map(([regionName, region]) => ( + - {regionName} - {Math.round(region.latency_ms)}ms - - ))} - - - - + > + {regionName} + {Math.round(region.latency_ms)}ms + + ))} + + + + + ); }; From e230f38027cf201b67ab530fa62974df6296d7a0 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 28 Aug 2025 18:23:48 +0000 Subject: [PATCH 02/56] refactor: replace PopoverTrigger with TooltipTrigger in AgentStatus --- site/src/modules/resources/AgentStatus.tsx | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/site/src/modules/resources/AgentStatus.tsx b/site/src/modules/resources/AgentStatus.tsx index 8f6b923e70d68..543c31313d043 100644 --- a/site/src/modules/resources/AgentStatus.tsx +++ b/site/src/modules/resources/AgentStatus.tsx @@ -6,13 +6,13 @@ import type { WorkspaceAgentDevcontainer, } from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; -import { PopoverTrigger } from "components/deprecated/Popover/Popover"; import { HelpTooltip, HelpTooltipContent, HelpTooltipText, HelpTooltipTitle, } from "components/HelpTooltip/HelpTooltip"; +import { TooltipProvider, TooltipTrigger } from "components/Tooltip/Tooltip"; import { TriangleAlertIcon } from "lucide-react"; import type { FC } from "react"; @@ -62,9 +62,9 @@ interface DevcontainerStatusProps { const StartTimeoutLifecycle: FC = ({ agent }) => { return ( - + - + Agent is taking too long to start @@ -87,9 +87,9 @@ const StartTimeoutLifecycle: FC = ({ agent }) => { const StartErrorLifecycle: FC = ({ agent }) => { return ( - + - + Error starting the agent @@ -123,9 +123,9 @@ const ShuttingDownLifecycle: FC = () => { const ShutdownTimeoutLifecycle: FC = ({ agent }) => { return ( - + - + Agent is taking too long to stop @@ -147,9 +147,9 @@ const ShutdownTimeoutLifecycle: FC = ({ agent }) => { const ShutdownErrorLifecycle: FC = ({ agent }) => { return ( - + - + Error stopping the agent @@ -243,9 +243,9 @@ const ConnectingStatus: FC = () => { const TimeoutStatus: FC = ({ agent }) => { return ( - + - + Agent is taking too long to connect @@ -266,20 +266,22 @@ const TimeoutStatus: FC = ({ agent }) => { export const AgentStatus: FC = ({ agent }) => { return ( - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + ); }; @@ -308,9 +310,9 @@ const SubAgentStatus: FC = ({ agent }) => { const DevcontainerStartError: FC = ({ agent }) => { return ( - + - + Error starting the devcontainer agent From 75c9fdfc4cd0457e80368f3b6ebdcd45779bba2c Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 28 Aug 2025 18:47:33 +0000 Subject: [PATCH 03/56] refactor: replace PopoverTrigger with TooltipTrigger in AgentOutdatedTooltip --- .../components/HelpTooltip/HelpTooltip.tsx | 12 +-- .../resources/AgentOutdatedTooltip.tsx | 83 ++++++++++--------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.tsx b/site/src/components/HelpTooltip/HelpTooltip.tsx index b05b9934903ed..8c788661bff62 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.tsx @@ -6,7 +6,6 @@ import { } from "@emotion/react"; import Link from "@mui/material/Link"; import { TooltipContentProps, TooltipProps } from "@radix-ui/react-tooltip"; -import { usePopover } from "components/deprecated/Popover/Popover"; import { Stack } from "components/Stack/Stack"; import { Tooltip, @@ -43,7 +42,7 @@ export const HelpTooltipContent: FC = ({ align="start" {...props} className={cn( - "w-[320px] p-5 bg-surface-secondary border-surface-quaternary", + "w-[320px] p-5 bg-surface-secondary border-surface-quaternary text-sm", className, )} /> @@ -153,19 +152,12 @@ export const HelpTooltipAction: FC = ({ onClick, ariaLabel, }) => { - // TODO dismiss tooltip - const popover = usePopover(); - return ( - + }> { From 9887b0946fb9451a1425dc052de3dc8ccbbd373c Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Tue, 2 Sep 2025 23:10:36 +0000 Subject: [PATCH 25/56] refactor: move default collisionPadding from HelpTooltip to Popover --- site/src/components/HelpTooltip/HelpTooltip.tsx | 1 - site/src/components/Popover/Popover.tsx | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.tsx b/site/src/components/HelpTooltip/HelpTooltip.tsx index 4c41a56b0e331..93abe7c056b56 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.tsx @@ -46,7 +46,6 @@ export const HelpTooltipContent: FC = ({ Date: Wed, 3 Sep 2025 00:08:24 +0000 Subject: [PATCH 26/56] refactor: replace deprecated Popover in SelectMenu --- site/src/components/SelectMenu/SelectMenu.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/site/src/components/SelectMenu/SelectMenu.tsx b/site/src/components/SelectMenu/SelectMenu.tsx index ece4128769705..5ecba4cb7d286 100644 --- a/site/src/components/SelectMenu/SelectMenu.tsx +++ b/site/src/components/SelectMenu/SelectMenu.tsx @@ -1,11 +1,15 @@ import MenuItem, { type MenuItemProps } from "@mui/material/MenuItem"; import MenuList, { type MenuListProps } from "@mui/material/MenuList"; +import type { + PopoverContentProps, + PopoverTriggerProps, +} from "@radix-ui/react-popover"; import { Button, type ButtonProps } from "components/Button/Button"; import { Popover, PopoverContent, PopoverTrigger, -} from "components/deprecated/Popover/Popover"; +} from "components/Popover/Popover"; import { SearchField, type SearchFieldProps, @@ -26,9 +30,21 @@ const SIDE_PADDING = 16; export const SelectMenu = Popover; -export const SelectMenuTrigger = PopoverTrigger; +export const SelectMenuTrigger: FC = (props) => { + return ; +}; -export const SelectMenuContent = PopoverContent; +export const SelectMenuContent: FC = (props) => { + return ( + + ); +}; type SelectMenuButtonProps = ButtonProps & { startIcon?: React.ReactNode; From bda70b2faf6920a07a6e2a1921d1517f81b3088d Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Wed, 3 Sep 2025 00:10:32 +0000 Subject: [PATCH 27/56] style: prettier --- .../dashboard/Navbar/DeploymentDropdown.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx b/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx index b78e3a6954a58..6de9435c3fd03 100644 --- a/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx +++ b/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx @@ -139,17 +139,17 @@ const DeploymentDropdownContent: FC = ({ const styles = { menuItem: (theme) => css` - text-decoration: none; - color: inherit; - gap: 8px; - padding: 8px 20px; - font-size: 14px; + text-decoration: none; + color: inherit; + gap: 8px; + padding: 8px 20px; + font-size: 14px; - &:hover { - background-color: ${theme.palette.action.hover}; - transition: background-color 0.3s ease; - } - `, + &:hover { + background-color: ${theme.palette.action.hover}; + transition: background-color 0.3s ease; + } + `, menuItemIcon: (theme) => ({ color: theme.palette.text.secondary, width: 20, From 6a37c4948ba941ec13d63d8755958ed1bce58bb7 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Wed, 3 Sep 2025 00:27:08 +0000 Subject: [PATCH 28/56] refactor: replace deprecated Popover in DeploymentDropdown --- .../dashboard/Navbar/DeploymentDropdown.tsx | 101 ++++++++---------- 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx b/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx index 6de9435c3fd03..b38201f3a8c3d 100644 --- a/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx +++ b/site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx @@ -1,12 +1,12 @@ -import { css, type Interpolation, type Theme, useTheme } from "@emotion/react"; +import { css, type Interpolation, type Theme } from "@emotion/react"; import MenuItem from "@mui/material/MenuItem"; +import { PopoverClose } from "@radix-ui/react-popover"; import { Button } from "components/Button/Button"; import { Popover, PopoverContent, PopoverTrigger, - usePopover, -} from "components/deprecated/Popover/Popover"; +} from "components/Popover/Popover"; import { ChevronDownIcon } from "lucide-react"; import { linkToAuditing } from "modules/navigation"; import type { FC } from "react"; @@ -27,8 +27,6 @@ export const DeploymentDropdown: FC = ({ canViewConnectionLog, canViewHealth, }) => { - const theme = useTheme(); - if ( !canViewAuditLog && !canViewConnectionLog && @@ -41,7 +39,7 @@ export const DeploymentDropdown: FC = ({ return ( - + - + = ({ ); }; -const classNames = { - paper: (css, theme) => css` - padding: 0; - width: 404px; - color: ${theme.palette.text.secondary}; - margin-top: 4px; - `, -} satisfies Record; - const styles = { portCount: (theme) => ({ fontSize: 12, From a6cf0dab9945fd8f2ea2003f4e592602414b06c7 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Wed, 3 Sep 2025 00:55:18 +0000 Subject: [PATCH 34/56] refactor: replace deprecated Popover in EditRolesButton --- .../UserTable/EditRolesButton.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/site/src/pages/OrganizationSettingsPage/UserTable/EditRolesButton.tsx b/site/src/pages/OrganizationSettingsPage/UserTable/EditRolesButton.tsx index 4983e671aa5a6..757729f25ab38 100644 --- a/site/src/pages/OrganizationSettingsPage/UserTable/EditRolesButton.tsx +++ b/site/src/pages/OrganizationSettingsPage/UserTable/EditRolesButton.tsx @@ -7,7 +7,7 @@ import { Popover, PopoverContent, PopoverTrigger, -} from "components/deprecated/Popover/Popover"; +} from "components/Popover/Popover"; import { HelpTooltip, HelpTooltipContent, @@ -130,7 +130,7 @@ const EnabledEditRolesButton: FC = ({ return ( - + Date: Wed, 3 Sep 2025 21:44:44 +0000 Subject: [PATCH 37/56] refactor: replace deprecated Popover in BuildParametersPopover --- .../BuildParametersPopover.tsx | 46 ++++++------- .../WorkspaceActions/RetryButton.stories.tsx | 66 ++++++++++++++++++- site/src/testHelpers/entities.ts | 21 ++++++ 3 files changed, 106 insertions(+), 27 deletions(-) diff --git a/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx b/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx index 7aef1dc7c7357..d4e5dc7773fcd 100644 --- a/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx @@ -7,12 +7,6 @@ import type { WorkspaceBuildParameter, } from "api/typesGenerated"; import { Button } from "components/Button/Button"; -import { - Popover, - PopoverContent, - PopoverTrigger, - usePopover, -} from "components/deprecated/Popover/Popover"; import { FormFields } from "components/Form/Form"; import { TopbarButton } from "components/FullPageLayout/Topbar"; import { @@ -21,13 +15,18 @@ import { HelpTooltipText, HelpTooltipTitle, } from "components/HelpTooltip/HelpTooltip"; +import { Link } from "components/Link/Link"; import { Loader } from "components/Loader/Loader"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "components/Popover/Popover"; import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"; import { useFormik } from "formik"; import { ChevronDownIcon } from "lucide-react"; -import type { FC } from "react"; +import { useState, type FC } from "react"; import { useQuery } from "react-query"; -import { useNavigate } from "react-router"; import { docs } from "utils/docs"; import { getFormHelpers } from "utils/formUtils"; import { @@ -48,6 +47,7 @@ export const BuildParametersPopover: FC = ({ label, onSubmit, }) => { + const [isOpen, setIsOpen] = useState(false); const { data: parameters } = useQuery({ queryKey: ["workspace", workspace.id, "parameters"], queryFn: () => API.getWorkspaceParameters(workspace), @@ -57,8 +57,8 @@ export const BuildParametersPopover: FC = ({ : undefined; return ( - - + + = ({ {label} - + @@ -88,6 +86,7 @@ interface BuildParametersPopoverContentProps { ephemeralParameters?: TemplateVersionParameter[]; buildParameters?: WorkspaceBuildParameter[]; onSubmit: (buildParameters: WorkspaceBuildParameter[]) => void; + setIsOpen: React.Dispatch>; } const BuildParametersPopoverContent: FC = ({ @@ -95,23 +94,15 @@ const BuildParametersPopoverContent: FC = ({ ephemeralParameters, buildParameters, onSubmit, + setIsOpen, }) => { const theme = useTheme(); - const popover = usePopover(); - const navigate = useNavigate(); if ( !workspace.template_use_classic_parameter_flow && ephemeralParameters && ephemeralParameters.length > 0 ) { - const handleGoToParameters = () => { - popover.setOpen(false); - navigate( - `/@${workspace.owner_name}/${workspace.name}/settings/parameters`, - ); - }; - return (

@@ -137,9 +128,12 @@ const BuildParametersPopoverContent: FC = ({

- + ); } @@ -165,7 +159,7 @@ const BuildParametersPopoverContent: FC = ({
{ onSubmit(buildParameters); - popover.setOpen(false); + setIsOpen(false); }} ephemeralParameters={ephemeralParameters} buildParameters={buildParameters.map( diff --git a/site/src/pages/WorkspacePage/WorkspaceActions/RetryButton.stories.tsx b/site/src/pages/WorkspacePage/WorkspaceActions/RetryButton.stories.tsx index 12ff75dc64616..b99b8cba4b3fc 100644 --- a/site/src/pages/WorkspacePage/WorkspaceActions/RetryButton.stories.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceActions/RetryButton.stories.tsx @@ -1,4 +1,8 @@ -import { MockWorkspace } from "testHelpers/entities"; +import { + MockNonClassicParameterFlowWorkspace, + MockTemplateVersionParameter6, + MockWorkspace, +} from "testHelpers/entities"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, waitFor, within } from "storybook/test"; import { RetryButton } from "./RetryButton"; @@ -52,3 +56,63 @@ export const WithOpenBuildParameters: Story = { }); }, }; + +export const WithOpenEphemeralBuildParameters: Story = { + args: { + enableBuildParameters: true, + workspace: MockWorkspace, + }, + parameters: { + queries: [ + { + key: ["workspace", MockWorkspace.id, "parameters"], + data: { + templateVersionRichParameters: [MockTemplateVersionParameter6], + buildParameters: [], + }, + }, + ], + }, + play: async ({ canvasElement, step }) => { + const screen = within(canvasElement); + + await step("open popover", async () => { + await userEvent.click(screen.getByTestId("build-parameters-button")); + await waitFor(() => + expect(screen.getByText("Build Options")).toBeInTheDocument(), + ); + }); + }, +}; + +export const WithOpenEphemeralBuildParametersNotClassic: Story = { + args: { + enableBuildParameters: true, + workspace: MockNonClassicParameterFlowWorkspace, + }, + parameters: { + queries: [ + { + key: [ + "workspace", + MockNonClassicParameterFlowWorkspace.id, + "parameters", + ], + data: { + templateVersionRichParameters: [MockTemplateVersionParameter6], + buildParameters: [], + }, + }, + ], + }, + play: async ({ canvasElement, step }) => { + const screen = within(canvasElement); + + await step("open popover", async () => { + await userEvent.click(screen.getByTestId("build-parameters-button")); + await waitFor(() => + expect(screen.getByText("Build Options")).toBeInTheDocument(), + ); + }); + }, +}; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index fb7ab29659835..4a803fef8a917 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -1598,6 +1598,12 @@ export const MockPendingWorkspace: TypesGen.Workspace = { }, }; +export const MockNonClassicParameterFlowWorkspace: TypesGen.Workspace = { + ...MockWorkspace, + id: "test-non-classic-parameter-flow-workspace", + template_use_classic_parameter_flow: false, +}; + // just over one page of workspaces export const MockWorkspacesResponse: TypesGen.WorkspacesResponse = { workspaces: range(1, 27).map((id: number) => ({ @@ -1695,6 +1701,21 @@ const MockTemplateVersionParameter5: TypesGen.TemplateVersionParameter = { ephemeral: false, }; +export const MockTemplateVersionParameter6: TypesGen.TemplateVersionParameter = + { + name: "ephemeral_parameter", + type: "string", + form_type: "input", + description: "This is ephemeral parameter", + description_plaintext: "Markdown: This is ephemeral parameter", + default_value: "abc", + mutable: true, + icon: "/icon/folder.svg", + options: [], + required: true, + ephemeral: true, + }; + export const MockTemplateVersionVariable1: TypesGen.TemplateVersionVariable = { name: "first_variable", description: "This is first variable.", From 244792ab446a30076da4ae9a45564e3fdfcf8592 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 4 Sep 2025 00:55:10 +0000 Subject: [PATCH 38/56] refactor: extract TemplateInsightsControls component --- .../TemplateInsightsControls.stories.tsx | 32 ++++++++++ .../TemplateInsightsPage.tsx | 64 +++++++++++++------ 2 files changed, 77 insertions(+), 19 deletions(-) create mode 100644 site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx new file mode 100644 index 0000000000000..4eb311a8d9c47 --- /dev/null +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import type { ComponentProps } from "react"; +import { TemplateInsightsControls } from "./TemplateInsightsPage"; + +const meta: Meta = { + title: "pages/TemplatePage/TemplateInsightsControls", + component: TemplateInsightsControls, +}; + +export default meta; +type Story = StoryObj; + +const defaultArgs: Partial> = { + dateRange: { startDate: new Date(), endDate: new Date() }, + setDateRange: () => {}, + searchParams: new URLSearchParams(), + setSearchParams: () => {}, +}; + +export const Day: Story = { + args: { + ...defaultArgs, + interval: "day", + }, +}; + +export const Week: Story = { + args: { + ...defaultArgs, + interval: "week", + }, +}; diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 0c12d96625156..3a74da6b4fb07 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -47,7 +47,7 @@ import { } from "react"; import { Helmet } from "react-helmet-async"; import { useQuery } from "react-query"; -import { useSearchParams } from "react-router"; +import { type SetURLSearchParams, useSearchParams } from "react-router"; import { getLatencyColor } from "utils/latency"; import { addTime, @@ -105,24 +105,13 @@ export default function TemplateInsightsPage() { - { - // When going from daily to week we need to set a safe week range - if (interval === "week") { - setDateRange(lastWeeks(DEFAULT_NUMBER_OF_WEEKS)); - } - searchParams.set("interval", interval); - setSearchParams(searchParams); - }} - /> - {interval === "day" ? ( - - ) : ( - - )} - + } templateInsights={templateInsights} userLatency={userLatency} @@ -134,6 +123,43 @@ export default function TemplateInsightsPage() { ); } +interface TemplateInsightsControlsProps { + interval: "day" | "week"; + dateRange: DateRangeValue; + setDateRange: (value: DateRangeValue) => void; + searchParams: URLSearchParams; + setSearchParams: SetURLSearchParams; +} + +export const TemplateInsightsControls: FC = ({ + interval, + dateRange, + setDateRange, + searchParams, + setSearchParams, +}) => { + return ( + <> + { + // When going from daily to week we need to set a safe week range + if (interval === "week") { + setDateRange(lastWeeks(DEFAULT_NUMBER_OF_WEEKS)); + } + searchParams.set("interval", interval); + setSearchParams(searchParams); + }} + /> + {interval === "day" ? ( + + ) : ( + + )} + + ); +}; + const getDefaultInterval = (template: Template) => { const now = new Date(); const templateCreateDate = new Date(template.created_at); From 07fd1e2c1a4cdd4da41385111702dcca716bd1e2 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 4 Sep 2025 01:08:47 +0000 Subject: [PATCH 39/56] test: use set past dateRange --- .../TemplateInsightsControls.stories.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx index 4eb311a8d9c47..2baf6c6c9b985 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx @@ -11,7 +11,10 @@ export default meta; type Story = StoryObj; const defaultArgs: Partial> = { - dateRange: { startDate: new Date(), endDate: new Date() }, + dateRange: { + startDate: new Date("2025-08-05"), + endDate: new Date("2025-08-07"), + }, setDateRange: () => {}, searchParams: new URLSearchParams(), setSearchParams: () => {}, From 8bd2cd03d24c4c9d5ee901b0ad589d49772aa711 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 4 Sep 2025 01:14:39 +0000 Subject: [PATCH 40/56] test: add play functions to TemplateInsightsControls.stories --- .../TemplateInsightsControls.stories.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx index 2baf6c6c9b985..1e1e0e8198f6e 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsControls.stories.tsx @@ -1,5 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; +import { within } from "@testing-library/react"; import type { ComponentProps } from "react"; +import { userEvent } from "storybook/test"; import { TemplateInsightsControls } from "./TemplateInsightsPage"; const meta: Meta = { @@ -25,6 +27,11 @@ export const Day: Story = { ...defaultArgs, interval: "day", }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const datePicker = canvas.getAllByRole("button")[1]; + await userEvent.click(datePicker); + }, }; export const Week: Story = { @@ -32,4 +39,9 @@ export const Week: Story = { ...defaultArgs, interval: "week", }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const dropdown = canvas.getAllByRole("button")[1]; + await userEvent.click(dropdown); + }, }; From bdacfb1767ccb56679a8a44478ba4a7bb0fe215f Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Thu, 4 Sep 2025 22:08:18 +0000 Subject: [PATCH 41/56] refactor: replace deprecated Popover in DateRange --- .../pages/TemplatePage/TemplateInsightsPage/DateRange.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/DateRange.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/DateRange.tsx index 3d9fb8120efbf..6c53a7e9b4b37 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/DateRange.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/DateRange.tsx @@ -6,7 +6,7 @@ import { Popover, PopoverContent, PopoverTrigger, -} from "components/deprecated/Popover/Popover"; +} from "components/Popover/Popover"; import dayjs from "dayjs"; import { MoveRightIcon } from "lucide-react"; import { type ComponentProps, type FC, useRef, useState } from "react"; @@ -45,7 +45,7 @@ export const DateRange: FC = ({ value, onChange }) => { return ( - +