diff --git a/site/src/components/PortForwardButton/PortForwardButton.stories.tsx b/site/src/components/PortForwardButton/PortForwardButton.stories.tsx new file mode 100644 index 0000000000000..89369b42a4d22 --- /dev/null +++ b/site/src/components/PortForwardButton/PortForwardButton.stories.tsx @@ -0,0 +1,25 @@ +import { Story } from "@storybook/react" +import { MockWorkspace, MockWorkspaceAgent } from "../../testHelpers/renderHelpers" +import { PortForwardButton, PortForwardButtonProps } from "./PortForwardButton" + +export default { + title: "components/PortForwardButton", + component: PortForwardButton, +} + +const Template: Story = (args) => + +export const Closed = Template.bind({}) +Closed.args = { + username: MockWorkspace.owner_name, + workspaceName: MockWorkspace.name, + agentName: MockWorkspaceAgent.name, +} + +export const Opened = Template.bind({}) +Opened.args = { + username: MockWorkspace.owner_name, + workspaceName: MockWorkspace.name, + agentName: MockWorkspaceAgent.name, + defaultIsOpen: true, +} diff --git a/site/src/components/PortForwardButton/PortForwardButton.tsx b/site/src/components/PortForwardButton/PortForwardButton.tsx new file mode 100644 index 0000000000000..4691465092a2e --- /dev/null +++ b/site/src/components/PortForwardButton/PortForwardButton.tsx @@ -0,0 +1,131 @@ +import Button from "@material-ui/core/Button" +import Link from "@material-ui/core/Link" +import Popover from "@material-ui/core/Popover" +import { makeStyles } from "@material-ui/core/styles" +import TextField from "@material-ui/core/TextField" +import OpenInNewOutlined from "@material-ui/icons/OpenInNewOutlined" +import { Stack } from "components/Stack/Stack" +import { useRef, useState } from "react" +import { colors } from "theme/colors" +import { CodeExample } from "../CodeExample/CodeExample" +import { HelpTooltipLink, HelpTooltipLinksGroup, HelpTooltipText } from "../Tooltips/HelpTooltip" + +export interface PortForwardButtonProps { + username: string + workspaceName: string + agentName: string + defaultIsOpen?: boolean +} + +export const PortForwardButton: React.FC> = ({ + workspaceName, + agentName, + username, + defaultIsOpen = false, +}) => { + const anchorRef = useRef(null) + const [isOpen, setIsOpen] = useState(defaultIsOpen) + const id = isOpen ? "schedule-popover" : undefined + const styles = useStyles() + const [port, setPort] = useState("3000") + const { location } = window + const urlExample = + process.env.CODER_ENABLE_WILDCARD_APPS === "true" + ? `${location.protocol}//${port}--${agentName}--${workspaceName}--${username}.${location.host}` + : `${location.protocol}//${location.host}/@${username}/${workspaceName}.${agentName}/apps/${port}` + + const onClose = () => { + setIsOpen(false) + } + + return ( + <> + + + + + You can port forward this resource by typing the{" "} + port, workspace name, agent name and your username in + the URL like the example below + + + + + + Or you can use the following form to open it in a new tab. + + + + { + setPort(e.currentTarget.value) + }} + /> + + + + + + + + Port forward + + + + + + ) +} + +const useStyles = makeStyles((theme) => ({ + popoverPaper: { + padding: `${theme.spacing(2.5)}px ${theme.spacing(3.5)}px ${theme.spacing(3.5)}px`, + width: theme.spacing(46), + color: theme.palette.text.secondary, + marginTop: theme.spacing(0.25), + }, + + openUrlButton: { + flexShrink: 0, + }, + + portField: { + // The default border don't contrast well with the popover + "& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { + borderColor: colors.gray[10], + }, + }, +})) diff --git a/site/src/components/Resources/Resources.tsx b/site/src/components/Resources/Resources.tsx index 21a9459cc764f..380b05c5d7a65 100644 --- a/site/src/components/Resources/Resources.tsx +++ b/site/src/components/Resources/Resources.tsx @@ -10,6 +10,7 @@ import { Skeleton } from "@material-ui/lab" import useTheme from "@material-ui/styles/useTheme" import { CloseDropdown, OpenDropdown } from "components/DropdownArrows/DropdownArrows" import { ErrorSummary } from "components/ErrorSummary/ErrorSummary" +import { PortForwardButton } from "components/PortForwardButton/PortForwardButton" import { TableCellDataPrimary } from "components/TableCellData/TableCellData" import { FC, useState } from "react" import { getDisplayAgentStatus, getDisplayVersionStatus } from "util/workspace" @@ -150,6 +151,11 @@ export const Resources: FC> = ({ {canUpdateWorkspace && agent.status === "connected" && ( <> + ({ }, link: { - display: "flex", + display: "inline-flex", alignItems: "center", + width: "fit-content", }, linkIcon: { diff --git a/site/webpack.common.ts b/site/webpack.common.ts index 6c6e662493796..22d349769767c 100644 --- a/site/webpack.common.ts +++ b/site/webpack.common.ts @@ -14,9 +14,13 @@ import { Configuration, EnvironmentPlugin } from "webpack" const environmentPlugin = new EnvironmentPlugin({ INSPECT_XSTATE: "", CODER_VERSION: "main", + CODER_ENABLE_WILDCARD_APPS: "", }) console.info(`--- Setting INSPECT_XSTATE to '${process.env.INSPECT_XSTATE || ""}'`) console.info(`--- Setting CODER_VERSION to '${process.env.CODER_VERSION || "main"}'`) +console.info( + `--- Setting CODER_ENABLE_WILDCARD_APPS to '${process.env.CODER_ENABLE_WILDCARD_APPS ?? ""}'`, +) console.info(`--- Setting NODE_ENV to '${process.env.NODE_ENV || ""}'`) /** 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