From 88bfab222a68bbc723ac9ab55103f51c2d2447a4 Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Mon, 3 Aug 2026 11:32:42 +0000 Subject: [PATCH] refactor(site): demui PortForwardButton and popover view Migrate the port-forward popover off MUI and Emotion onto shadcn Select/FormField and Tailwind. Replaces FormControl, Select, MenuItem, TextField, Stack, and Link usage in `PortForwardButton` / `PortForwardPopoverView`, and updates the popover stories to match. --- .../modules/resources/PortForwardButton.tsx | 547 ++++++++---------- .../PortForwardPopoverView.stories.tsx | 10 +- 2 files changed, 234 insertions(+), 323 deletions(-) diff --git a/site/src/modules/resources/PortForwardButton.tsx b/site/src/modules/resources/PortForwardButton.tsx index 5e88c50b047..281f3cdd7b1 100644 --- a/site/src/modules/resources/PortForwardButton.tsx +++ b/site/src/modules/resources/PortForwardButton.tsx @@ -1,10 +1,3 @@ -import { type Interpolation, type Theme, useTheme } from "@emotion/react"; -import FormControl from "@mui/material/FormControl"; -import Link from "@mui/material/Link"; -import MenuItem from "@mui/material/MenuItem"; -import Select from "@mui/material/Select"; -import Stack from "@mui/material/Stack"; -import TextField from "@mui/material/TextField"; import { useFormik } from "formik"; import { BuildingIcon, @@ -15,7 +8,7 @@ import { ShareIcon, XIcon, } from "lucide-react"; -import { type FC, useState } from "react"; +import { type FC, useId, useState } from "react"; import { useMutation } from "react-query"; import * as Yup from "yup"; import { @@ -29,21 +22,30 @@ import { type WorkspaceAgentListeningPort, type WorkspaceAgentPortShare, type WorkspaceAgentPortShareLevel, + WorkspaceAgentPortShareLevels, type WorkspaceAgentPortShareProtocol, - WorkspaceAppSharingLevels, } from "#/api/typesGenerated"; import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown"; import { Button } from "#/components/Button/Button"; +import { FormField } from "#/components/FormField/FormField"; import { HelpPopoverLink, HelpPopoverText, HelpPopoverTitle, } from "#/components/HelpPopover/HelpPopover"; +import { Label } from "#/components/Label/Label"; import { Popover, PopoverContent, PopoverTrigger, } from "#/components/Popover/Popover"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "#/components/Select/Select"; import { Spinner } from "#/components/Spinner/Spinner"; import { Tooltip, @@ -86,7 +88,9 @@ export const PortForwardButton: FC = ({ - - + + ); })}
- - + - - HTTP - HTTPS - - - Organization - {canSharePortsAuthenticated ? ( - Authenticated - ) : ( - disabledAuthenticatedMenuItem - )} - {canSharePortsPublic ? ( - Public - ) : ( - disabledPublicMenuItem - )} - +
+ + +
+
+ + +
-
+
)} @@ -574,103 +591,3 @@ export const PortForwardPopoverView: FC = ({ ); }; - -const styles = { - portCount: (theme) => ({ - fontSize: 12, - fontWeight: 500, - height: 20, - minWidth: 20, - padding: "0 4px", - borderRadius: "50%", - display: "flex", - alignItems: "center", - justifyContent: "center", - backgroundColor: theme.palette.action.selected, - }), - - portLink: (theme) => ({ - color: theme.palette.text.primary, - fontSize: 14, - display: "flex", - alignItems: "center", - gap: 8, - paddingTop: 8, - paddingBottom: 8, - fontWeight: 500, - minWidth: 80, - }), - - portNumber: (theme) => ({ - marginLeft: "auto", - color: theme.palette.text.secondary, - fontSize: 13, - fontWeight: 400, - }), - - shareLevelSelect: () => ({ - boxShadow: "none", - ".MuiOutlinedInput-notchedOutline": { border: 0 }, - "&.MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline": { - border: 0, - }, - "&.MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": { - border: 0, - }, - }), - - newPortForm: (theme) => ({ - border: `1px solid ${theme.palette.divider}`, - borderRadius: "4px", - marginTop: 8, - display: "flex", - alignItems: "center", - "&:focus-within": { - borderColor: theme.palette.primary.main, - }, - width: "100%", - }), - - listeningPortProtocol: (theme) => ({ - boxShadow: "none", - ".MuiOutlinedInput-notchedOutline": { border: 0 }, - "&.MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline": { - border: 0, - }, - "&.MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": { - border: 0, - }, - border: `1px solid ${theme.palette.divider}`, - borderRadius: "4px", - marginTop: 8, - minWidth: "100px", - }), - - newPortInput: (theme) => ({ - fontSize: 14, - height: 34, - padding: "0 12px", - background: "none", - border: 0, - outline: "none", - color: theme.palette.text.primary, - appearance: "textfield", - display: "block", - width: "100%", - }), - noPortText: (theme) => ({ - color: theme.palette.text.secondary, - paddingTop: 20, - paddingBottom: 10, - textAlign: "center", - }), - sharedPortLink: () => ({ - minWidth: 80, - }), - protocolFormControl: () => ({ - minWidth: 90, - }), - shareLevelFormControl: () => ({ - minWidth: 140, - }), -} satisfies Record>; diff --git a/site/src/modules/resources/PortForwardPopoverView.stories.tsx b/site/src/modules/resources/PortForwardPopoverView.stories.tsx index 7cb19d4a060..4d4edb2ed2e 100644 --- a/site/src/modules/resources/PortForwardPopoverView.stories.tsx +++ b/site/src/modules/resources/PortForwardPopoverView.stories.tsx @@ -14,14 +14,7 @@ const meta: Meta = { component: PortForwardPopoverView, decorators: [ (Story) => ( -
({ - width: 404, - border: `1px solid ${theme.palette.divider}`, - borderRadius: 8, - backgroundColor: theme.palette.background.paper, - })} - > +
), @@ -34,6 +27,7 @@ const meta: Meta = { workspace: MockWorkspace, portSharingControlsEnabled: true, host: "*.coder.com", + refetchSharedPorts: () => {}, }, };