Skip to content

Commit 0964e8c

Browse files
committed
feat: add listening ports protocol selector
1 parent 08451ce commit 0964e8c

File tree

2 files changed

+85
-44
lines changed

2 files changed

+85
-44
lines changed

site/src/modules/resources/PortForwardButton.tsx

+77-44
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Stack from "@mui/material/Stack";
1616
import TextField from "@mui/material/TextField";
1717
import Tooltip from "@mui/material/Tooltip";
1818
import { type FormikContextType, useFormik } from "formik";
19-
import type { FC } from "react";
19+
import { useState, type FC } from "react";
2020
import { useQuery, useMutation } from "react-query";
2121
import * as Yup from "yup";
2222
import { getAgentListeningPorts } from "api/api";
@@ -48,7 +48,7 @@ import { type ClassName, useClassName } from "hooks/useClassName";
4848
import { useDashboard } from "modules/dashboard/useDashboard";
4949
import { docs } from "utils/docs";
5050
import { getFormHelpers } from "utils/formUtils";
51-
import { portForwardURL } from "utils/portForward";
51+
import { getWorkspaceListeningPortsProtocol, portForwardURL, saveWorkspaceListeningPortsProtocol } from "utils/portForward";
5252

5353
export interface PortForwardButtonProps {
5454
host: string;
@@ -135,6 +135,7 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
135135
portSharingControlsEnabled,
136136
}) => {
137137
const theme = useTheme();
138+
const [listeningPortProtocol, setListeningPortProtocol] = useState(getWorkspaceListeningPortsProtocol(workspaceID));
138139

139140
const sharedPortsQuery = useQuery({
140141
...workspacePortShares(workspaceID),
@@ -253,52 +254,68 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
253254
? "No open ports were detected."
254255
: "The listening ports are exclusively accessible to you."}
255256
</HelpTooltipText>
256-
<form
257-
css={styles.newPortForm}
258-
onSubmit={(e) => {
259-
e.preventDefault();
260-
const formData = new FormData(e.currentTarget);
261-
const port = Number(formData.get("portNumber"));
262-
const url = portForwardURL(
263-
host,
264-
port,
265-
agent.name,
266-
workspaceName,
267-
username,
268-
);
269-
window.open(url, "_blank");
270-
}}
271-
>
272-
<input
273-
aria-label="Port number"
274-
name="portNumber"
275-
type="number"
276-
placeholder="Connect to port..."
277-
min={9}
278-
max={65535}
279-
required
280-
css={styles.newPortInput}
281-
/>
282-
<Button
283-
type="submit"
284-
size="small"
285-
variant="text"
286-
css={{
287-
paddingLeft: 12,
288-
paddingRight: 12,
289-
minWidth: 0,
257+
<Stack direction="row" gap={1} alignItems="flex-end" justifyContent="flex-end">
258+
<form
259+
css={styles.newPortForm}
260+
onSubmit={(e) => {
261+
e.preventDefault();
262+
const formData = new FormData(e.currentTarget);
263+
const port = Number(formData.get("portNumber"));
264+
const url = portForwardURL(
265+
host,
266+
port,
267+
agent.name,
268+
workspaceName,
269+
username,
270+
);
271+
window.open(url, "_blank");
290272
}}
291273
>
292-
<OpenInNewOutlined
274+
<input
275+
aria-label="Port number"
276+
name="portNumber"
277+
type="number"
278+
placeholder="Connect to port..."
279+
min={9}
280+
max={65535}
281+
required
282+
css={styles.newPortInput}
283+
/>
284+
<Button
285+
type="submit"
286+
size="small"
287+
variant="text"
293288
css={{
294-
flexShrink: 0,
295-
width: 14,
296-
height: 14,
297-
color: theme.palette.text.primary,
289+
paddingLeft: 12,
290+
paddingRight: 12,
291+
minWidth: 0,
298292
}}
299-
/>
300-
</Button>
301-
</form>
293+
>
294+
<OpenInNewOutlined
295+
css={{
296+
flexShrink: 0,
297+
width: 14,
298+
height: 14,
299+
color: theme.palette.text.primary,
300+
}}
301+
/>
302+
</Button>
303+
</form>
304+
<FormControl size="small" css={styles.protocolFormControl}>
305+
<Select
306+
css={styles.listeningPortProtocol}
307+
value={listeningPortProtocol}
308+
onChange={async (event) => {
309+
const selectedProtocol = event.target.value as "http" | "https";
310+
setListeningPortProtocol(selectedProtocol);
311+
saveWorkspaceListeningPortsProtocol(workspaceID, selectedProtocol);
312+
}}
313+
>
314+
<MenuItem value="http">HTTP</MenuItem>
315+
<MenuItem value="https">HTTPS</MenuItem>
316+
</Select>
317+
</FormControl>
318+
</Stack>
302319
</header>
303320
<div
304321
css={{
@@ -618,6 +635,22 @@ const styles = {
618635
"&:focus-within": {
619636
borderColor: theme.palette.primary.main,
620637
},
638+
width: "100%",
639+
}),
640+
641+
listeningPortProtocol: (theme) => ({
642+
boxShadow: "none",
643+
".MuiOutlinedInput-notchedOutline": { border: 0 },
644+
"&.MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline": {
645+
border: 0,
646+
},
647+
"&.MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": {
648+
border: 0,
649+
},
650+
border: `1px solid ${theme.palette.divider}`,
651+
borderRadius: "4px",
652+
marginTop: 8,
653+
minWidth: "100px",
621654
}),
622655

623656
newPortInput: (theme) => ({

site/src/utils/portForward.ts

+8
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,11 @@ export const openMaybePortForwardedURL = (
6262
open(uri);
6363
}
6464
};
65+
66+
export const saveWorkspaceListeningPortsProtocol = (workspaceID: string, protocol: "http" | "https") => {
67+
localStorage.setItem(`listening-ports-protocol-workspace-${workspaceID}`, protocol);
68+
}
69+
70+
export const getWorkspaceListeningPortsProtocol = (workspaceID: string) => {
71+
return localStorage.getItem(`listening-ports-protocol-workspace-${workspaceID}`) || "http";
72+
}

0 commit comments

Comments
 (0)