diff --git a/site/src/components/Dashboard/Navbar/UserDropdown/BorderedMenu.tsx b/site/src/components/Dashboard/Navbar/UserDropdown/BorderedMenu.tsx index abe85bcb73041..b57984aa6dab7 100644 --- a/site/src/components/Dashboard/Navbar/UserDropdown/BorderedMenu.tsx +++ b/site/src/components/Dashboard/Navbar/UserDropdown/BorderedMenu.tsx @@ -1,6 +1,6 @@ import { css } from "@emotion/css"; import { useTheme } from "@emotion/react"; -import Popover, { PopoverProps } from "@mui/material/Popover"; +import Popover, { type PopoverProps } from "@mui/material/Popover"; import type { FC, PropsWithChildren } from "react"; type BorderedMenuVariant = "user-dropdown"; @@ -18,7 +18,7 @@ export const BorderedMenu: FC> = ({ const paper = css` width: 260px; - border-radius: ${theme.shape.borderRadius}; + border-radius: ${theme.shape.borderRadius}px; box-shadow: ${theme.shadows[6]}; `; diff --git a/site/src/components/DeploySettingsLayout/Sidebar.tsx b/site/src/components/DeploySettingsLayout/Sidebar.tsx index 1228bb0fb0dfc..1a5892d22421d 100644 --- a/site/src/components/DeploySettingsLayout/Sidebar.tsx +++ b/site/src/components/DeploySettingsLayout/Sidebar.tsx @@ -47,7 +47,7 @@ const SidebarNavItem: FC< font-size: 14px; text-decoration: none; padding: ${theme.spacing(1.5, 1.5, 1.5, 2)}; - border-radius: ${theme.shape.borderRadius / 2}; + border-radius: ${theme.shape.borderRadius / 2}px; transition: background-color 0.15s ease-in-out; margin-bottom: 1; position: relative; diff --git a/site/src/components/ErrorBoundary/RuntimeErrorState.tsx b/site/src/components/ErrorBoundary/RuntimeErrorState.tsx index c8bf5ca15a12b..0b6ecdd893b41 100644 --- a/site/src/components/ErrorBoundary/RuntimeErrorState.tsx +++ b/site/src/components/ErrorBoundary/RuntimeErrorState.tsx @@ -1,14 +1,15 @@ import Button from "@mui/material/Button"; import Link from "@mui/material/Link"; -import { makeStyles } from "@mui/styles"; import RefreshOutlined from "@mui/icons-material/RefreshOutlined"; -import { BuildInfoResponse } from "api/typesGenerated"; +import { type FC, useEffect, useState } from "react"; +import { Helmet } from "react-helmet-async"; +import { css } from "@emotion/css"; +import { useTheme, type Interpolation, type Theme } from "@emotion/react"; +import type { BuildInfoResponse } from "api/typesGenerated"; import { CopyButton } from "components/CopyButton/CopyButton"; import { CoderIcon } from "components/Icons/CoderIcon"; import { FullScreenLoader } from "components/Loader/FullScreenLoader"; import { Stack } from "components/Stack/Stack"; -import { FC, useEffect, useState } from "react"; -import { Helmet } from "react-helmet-async"; import { Margins } from "components/Margins/Margins"; const fetchDynamicallyImportedModuleError = @@ -17,7 +18,7 @@ const fetchDynamicallyImportedModuleError = export type RuntimeErrorStateProps = { error: Error }; export const RuntimeErrorState: FC = ({ error }) => { - const styles = useStyles(); + const theme = useTheme(); const [checkingError, setCheckingError] = useState(true); const [staticBuildInfo, setStaticBuildInfo] = useState(); const coderVersion = staticBuildInfo?.version; @@ -52,11 +53,11 @@ export const RuntimeErrorState: FC = ({ error }) => { Codestin Search App {!checkingError ? ( - -
- -

Something went wrong...

-

+ +

+ +

Something went wrong...

+

Please try reloading the page, if that doesn‘t work, you can ask for help in the{" "} @@ -93,20 +94,33 @@ export const RuntimeErrorState: FC = ({ error }) => { {error.stack && ( -

-
+
+
Stacktrace
-
{error.stack}
+
{error.stack}
)} {coderVersion && ( -
Version: {coderVersion}
+
Version: {coderVersion}
)}
@@ -132,8 +146,8 @@ const getStaticBuildInfo = () => { } }; -const useStyles = makeStyles((theme) => ({ - root: { +const styles = { + root: (theme) => ({ paddingTop: theme.spacing(4), paddingBottom: theme.spacing(4), textAlign: "center", @@ -142,36 +156,34 @@ const useStyles = makeStyles((theme) => ({ justifyContent: "center", minHeight: "100%", maxWidth: theme.spacing(75), - }, + }), - innerRoot: { width: "100%" }, - - logo: { + logo: (theme) => ({ fontSize: theme.spacing(8), - }, + }), - title: { + title: (theme) => ({ fontSize: theme.spacing(4), fontWeight: 400, - }, + }), - text: { + text: (theme) => ({ fontSize: 16, color: theme.palette.text.secondary, lineHeight: "160%", marginBottom: theme.spacing(4), - }, + }), - stack: { + stack: (theme) => ({ backgroundColor: theme.palette.background.paper, border: `1px solid ${theme.palette.divider}`, borderRadius: 4, marginTop: theme.spacing(8), display: "block", textAlign: "left", - }, + }), - stackHeader: { + stackHeader: (theme) => ({ fontSize: 10, textTransform: "uppercase", fontWeight: 600, @@ -184,33 +196,18 @@ const useStyles = makeStyles((theme) => ({ flexAlign: "center", justifyContent: "space-between", alignItems: "center", - }, + }), - stackCode: { + stackCode: (theme) => ({ padding: theme.spacing(2), margin: 0, wordWrap: "break-word", whiteSpace: "break-spaces", - }, - - copyButton: { - backgroundColor: "transparent", - border: 0, - borderRadius: 999, - minHeight: theme.spacing(4), - minWidth: theme.spacing(4), - height: theme.spacing(4), - width: theme.spacing(4), - - "& svg": { - width: 16, - height: 16, - }, - }, - - version: { + }), + + version: (theme) => ({ marginTop: theme.spacing(4), fontSize: 12, color: theme.palette.text.secondary, - }, -})); + }), +} satisfies Record>; diff --git a/site/src/components/FileUpload/FileUpload.tsx b/site/src/components/FileUpload/FileUpload.tsx index e3e439e1b712e..0416f2c182d43 100644 --- a/site/src/components/FileUpload/FileUpload.tsx +++ b/site/src/components/FileUpload/FileUpload.tsx @@ -1,13 +1,12 @@ -import { makeStyles } from "@mui/styles"; import { Stack } from "components/Stack/Stack"; -import { FC, DragEvent, useRef, ReactNode } from "react"; +import { type FC, type DragEvent, useRef, type ReactNode } from "react"; import UploadIcon from "@mui/icons-material/CloudUploadOutlined"; import { useClickable } from "hooks/useClickable"; import CircularProgress from "@mui/material/CircularProgress"; -import { combineClasses } from "utils/combineClasses"; import IconButton from "@mui/material/IconButton"; import RemoveIcon from "@mui/icons-material/DeleteOutline"; import FileIcon from "@mui/icons-material/FolderOutlined"; +import { css, type Interpolation, type Theme } from "@emotion/react"; const useFileDrop = ( callback: (file: File) => void, @@ -62,7 +61,6 @@ export const FileUpload: FC = ({ extension, fileTypeRequired, }) => { - const styles = useStyles(); const inputRef = useRef(null); const tarDrop = useFileDrop(onUpload, fileTypeRequired); @@ -75,7 +73,7 @@ export const FileUpload: FC = ({ if (!isUploading && file) { return ( = ({ return ( <>
@@ -106,12 +101,12 @@ export const FileUpload: FC = ({ {isUploading ? ( ) : ( - + )} - {title} - {description} + {title} + {description}
@@ -120,7 +115,7 @@ export const FileUpload: FC = ({ type="file" data-testid="file-upload" ref={inputRef} - className={styles.input} + css={styles.input} accept={extension} onChange={(event) => { const file = event.currentTarget.files?.[0]; @@ -133,48 +128,48 @@ export const FileUpload: FC = ({ ); }; -const useStyles = makeStyles((theme) => ({ - root: { - display: "flex", - alignItems: "center", - justifyContent: "center", - borderRadius: theme.shape.borderRadius, - border: `2px dashed ${theme.palette.divider}`, - padding: theme.spacing(6), - cursor: "pointer", - - "&:hover": { - backgroundColor: theme.palette.background.paper, - }, - }, +const styles = { + root: (theme) => css` + display: flex; + align-items: center; + justify-content: center; + border-radius: ${theme.shape.borderRadius}px; + border: 2px dashed ${theme.palette.divider}; + padding: ${theme.spacing(6)}; + cursor: pointer; + + &:hover { + background-color: ${theme.palette.background.paper}; + } + `, disabled: { pointerEvents: "none", opacity: 0.75, }, - icon: { + icon: (theme) => ({ fontSize: theme.spacing(8), - }, + }), - title: { + title: (theme) => ({ fontSize: theme.spacing(2), - }, + }), - description: { + description: (theme) => ({ color: theme.palette.text.secondary, textAlign: "center", maxWidth: theme.spacing(50), - }, + }), input: { display: "none", }, - file: { + file: (theme) => ({ borderRadius: theme.shape.borderRadius, border: `1px solid ${theme.palette.divider}`, padding: theme.spacing(2), background: theme.palette.background.paper, - }, -})); + }), +} satisfies Record>; diff --git a/site/src/components/FullPageForm/FullPageForm.tsx b/site/src/components/FullPageForm/FullPageForm.tsx index 0fd124b969588..9e8163dceef4e 100644 --- a/site/src/components/FullPageForm/FullPageForm.tsx +++ b/site/src/components/FullPageForm/FullPageForm.tsx @@ -1,11 +1,11 @@ import { Margins } from "components/Margins/Margins"; -import { FC, ReactNode } from "react"; +import { type FC, type ReactNode } from "react"; import { PageHeader, PageHeaderTitle, PageHeaderSubtitle, } from "components/PageHeader/PageHeader"; -import { makeStyles } from "@mui/styles"; +import { useTheme } from "@emotion/react"; export interface FullPageFormProps { title: string; @@ -17,11 +17,11 @@ export const FullPageForm: FC> = ({ detail, children, }) => { - const styles = useStyles(); + const theme = useTheme(); return ( - + {title} {detail && {detail}} @@ -30,9 +30,3 @@ export const FullPageForm: FC> = ({ ); }; - -const useStyles = makeStyles((theme) => ({ - pageHeader: { - paddingBottom: theme.spacing(3), - }, -})); diff --git a/site/src/components/GlobalSnackbar/EnterpriseSnackbar.tsx b/site/src/components/GlobalSnackbar/EnterpriseSnackbar.tsx index 57ba64b608472..b39edb1209bd9 100644 --- a/site/src/components/GlobalSnackbar/EnterpriseSnackbar.tsx +++ b/site/src/components/GlobalSnackbar/EnterpriseSnackbar.tsx @@ -2,10 +2,10 @@ import IconButton from "@mui/material/IconButton"; import Snackbar, { SnackbarProps as MuiSnackbarProps, } from "@mui/material/Snackbar"; -import { makeStyles } from "@mui/styles"; import CloseIcon from "@mui/icons-material/Close"; -import { FC } from "react"; -import { combineClasses } from "utils/combineClasses"; +import { type FC } from "react"; +import { css } from "@emotion/css"; +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; type EnterpriseSnackbarVariant = "error" | "info" | "success"; @@ -30,7 +30,18 @@ export interface EnterpriseSnackbarProps extends MuiSnackbarProps { export const EnterpriseSnackbar: FC< React.PropsWithChildren > = ({ onClose, variant = "info", ContentProps = {}, action, ...rest }) => { - const styles = useStyles(); + const theme = useTheme(); + + const snackbarContentStyles = css` + border: 1px solid ${theme.palette.divider}; + border-left: 4px solid ${variantColor(variant, theme)}; + border-radius: ${theme.shape.borderRadius}px; + padding: ${theme.spacing(1, 3, 1, 2)}; + box-shadow: ${theme.shadows[6]}; + align-items: inherit; + background-color: ${theme.palette.background.paper}; + color: ${theme.palette.text.secondary}; + `; return ( +
{action} - - + +
} ContentProps={{ ...ContentProps, - className: combineClasses({ - [styles.snackbarContent]: true, - [styles.snackbarContentInfo]: variant === "info", - [styles.snackbarContentError]: variant === "error", - [styles.snackbarContentSuccess]: variant === "success", - }), + className: snackbarContentStyles, }} onClose={onClose} /> ); }; -const useStyles = makeStyles((theme) => ({ +const variantColor = (variant: EnterpriseSnackbarVariant, theme: Theme) => { + switch (variant) { + case "error": + return theme.palette.error.main; + case "info": + return theme.palette.info.main; + case "success": + return theme.palette.success.main; + } +}; + +const styles = { actionWrapper: { display: "flex", alignItems: "center", }, - iconButton: { - padding: 0, - }, - closeIcon: { + closeIcon: (theme) => ({ width: 25, height: 25, color: theme.palette.primary.contrastText, - }, - snackbarContent: { - border: `1px solid ${theme.palette.divider}`, - borderLeft: `4px solid ${theme.palette.primary.main}`, - borderRadius: theme.shape.borderRadius, - padding: ` - ${theme.spacing(1)}px - ${theme.spacing(3)}px - ${theme.spacing(1)}px - ${theme.spacing(2)}px - `, - boxShadow: theme.shadows[6], - alignItems: "inherit", - backgroundColor: theme.palette.background.paper, - color: theme.palette.text.secondary, - }, - snackbarContentInfo: { - // Use success color as a highlight - borderLeftColor: theme.palette.primary.main, - }, - snackbarContentError: { - borderLeftColor: theme.palette.error.main, - }, - snackbarContentSuccess: { - borderLeftColor: theme.palette.success.main, - }, -})); + }), +} satisfies Record>; diff --git a/site/src/components/GlobalSnackbar/GlobalSnackbar.tsx b/site/src/components/GlobalSnackbar/GlobalSnackbar.tsx index 879acbe635057..d521812316468 100644 --- a/site/src/components/GlobalSnackbar/GlobalSnackbar.tsx +++ b/site/src/components/GlobalSnackbar/GlobalSnackbar.tsx @@ -1,19 +1,19 @@ -import { makeStyles } from "@mui/styles"; -import { useCallback, useState, FC } from "react"; +import { type FC, useCallback, useState } from "react"; import { useCustomEvent } from "hooks/events"; -import { CustomEventListener } from "utils/events"; +import type { CustomEventListener } from "utils/events"; import { EnterpriseSnackbar } from "./EnterpriseSnackbar"; import { ErrorIcon } from "../Icons/ErrorIcon"; import { Typography } from "../Typography/Typography"; import { - AdditionalMessage, + type AdditionalMessage, isNotificationList, isNotificationText, isNotificationTextPrefixed, MsgType, - NotificationMsg, + type NotificationMsg, SnackbarEventType, } from "./utils"; +import { type Interpolation, type Theme } from "@emotion/react"; const variantFromMsgType = (type: MsgType) => { if (type === MsgType.Error) { @@ -26,7 +26,6 @@ const variantFromMsgType = (type: MsgType) => { }; export const GlobalSnackbar: FC = () => { - const styles = useStyles(); const [open, setOpen] = useState(false); const [notification, setNotification] = useState(); @@ -47,7 +46,7 @@ export const GlobalSnackbar: FC = () => { key={idx} gutterBottom variant="body2" - className={styles.messageSubtitle} + css={styles.messageSubtitle} > {msg} @@ -58,17 +57,17 @@ export const GlobalSnackbar: FC = () => { key={idx} gutterBottom variant="body2" - className={styles.messageSubtitle} + css={styles.messageSubtitle} > {msg.prefix}: {msg.text} ); } else if (isNotificationList(msg)) { return ( -
    +
      {msg.map((item, idx) => (
    • - + {item}
    • @@ -89,12 +88,12 @@ export const GlobalSnackbar: FC = () => { open={open} variant={variantFromMsgType(notification.msgType)} message={ -
      +
      {notification.msgType === MsgType.Error && ( - + )} -
      - +
      + {notification.msg} {notification.additionalMsgs && @@ -112,7 +111,7 @@ export const GlobalSnackbar: FC = () => { ); }; -const useStyles = makeStyles((theme) => ({ +const styles = { list: { paddingLeft: 0, }, @@ -126,11 +125,11 @@ const useStyles = makeStyles((theme) => ({ fontSize: 14, fontWeight: 600, }, - messageSubtitle: { + messageSubtitle: (theme) => ({ marginTop: theme.spacing(1.5), - }, - errorIcon: { + }), + errorIcon: (theme) => ({ color: theme.palette.error.contrastText, marginRight: theme.spacing(2), - }, -})); + }), +} satisfies Record>; diff --git a/site/src/components/PageHeader/FullWidthPageHeader.tsx b/site/src/components/PageHeader/FullWidthPageHeader.tsx index 5803c05ee1998..c81be232be46e 100644 --- a/site/src/components/PageHeader/FullWidthPageHeader.tsx +++ b/site/src/components/PageHeader/FullWidthPageHeader.tsx @@ -1,16 +1,39 @@ -import { makeStyles } from "@mui/styles"; -import { FC, PropsWithChildren } from "react"; -import { combineClasses } from "utils/combineClasses"; +import { type CSSObject, useTheme } from "@emotion/react"; +import { type FC, type PropsWithChildren } from "react"; export const FullWidthPageHeader: FC< PropsWithChildren & { sticky?: boolean } > = ({ children, sticky = true }) => { - const styles = useStyles(); - + const theme = useTheme(); return (
      {children}
      @@ -18,60 +41,47 @@ export const FullWidthPageHeader: FC< }; export const PageHeaderActions: FC = ({ children }) => { - const styles = useStyles(); - return
      {children}
      ; + const theme = useTheme(); + return ( +
      + {children} +
      + ); }; export const PageHeaderTitle: FC = ({ children }) => { - const styles = useStyles(); - return

      {children}

      ; + return ( +

      + {children} +

      + ); }; export const PageHeaderSubtitle: FC = ({ children }) => { - const styles = useStyles(); - return {children}; + const theme = useTheme(); + return ( + + {children} + + ); }; - -const useStyles = makeStyles((theme) => ({ - header: { - ...theme.typography.body2, - padding: theme.spacing(3), - background: theme.palette.background.paper, - borderBottom: `1px solid ${theme.palette.divider}`, - display: "flex", - alignItems: "center", - gap: theme.spacing(6), - - zIndex: 10, - flexWrap: "wrap", - - [theme.breakpoints.down("lg")]: { - position: "unset", - alignItems: "flex-start", - }, - [theme.breakpoints.down("md")]: { - flexDirection: "column", - }, - }, - sticky: { - position: "sticky", - top: 0, - }, - actions: { - marginLeft: "auto", - [theme.breakpoints.down("md")]: { - marginLeft: "unset", - }, - }, - title: { - fontSize: 18, - fontWeight: 500, - margin: 0, - lineHeight: "24px", - }, - subtitle: { - fontSize: 14, - color: theme.palette.text.secondary, - display: "block", - }, -})); diff --git a/site/src/components/PaginationWidget/PageButton.tsx b/site/src/components/PaginationWidget/PageButton.tsx index b81167b13645c..7a8f304b15eb5 100644 --- a/site/src/components/PaginationWidget/PageButton.tsx +++ b/site/src/components/PaginationWidget/PageButton.tsx @@ -1,5 +1,5 @@ import Button from "@mui/material/Button"; -import { makeStyles } from "@mui/styles"; +import { css, useTheme } from "@emotion/react"; interface PageButtonProps { activePage?: number; @@ -18,14 +18,20 @@ export const PageButton = ({ onPageClick, disabled = false, }: PageButtonProps): JSX.Element => { - const styles = useStyles(); + const theme = useTheme(); return (
      ); }; - -const useStyles = makeStyles((theme) => ({ - defaultContainerStyles: { - justifyContent: "center", - alignItems: "center", - display: "flex", - flexDirection: "row", - padding: "20px", - }, - - prevLabelStyles: { - marginRight: theme.spacing(0.5), - }, -})); diff --git a/site/src/components/Paywall/Paywall.tsx b/site/src/components/Paywall/Paywall.tsx index 190aa02c10470..29ffb2e16989f 100644 --- a/site/src/components/Paywall/Paywall.tsx +++ b/site/src/components/Paywall/Paywall.tsx @@ -1,9 +1,9 @@ import Box from "@mui/material/Box"; import Chip from "@mui/material/Chip"; -import { makeStyles } from "@mui/styles"; import Typography from "@mui/material/Typography"; +import { type FC, type ReactNode } from "react"; +import { type Interpolation, type Theme } from "@emotion/react"; import { Stack } from "components/Stack/Stack"; -import { FC, ReactNode } from "react"; export interface PaywallProps { message: string; @@ -13,17 +13,16 @@ export interface PaywallProps { export const Paywall: FC> = (props) => { const { message, description, cta } = props; - const styles = useStyles(); return ( - -
      + +
      - + {message} > = (props) => { {description} @@ -45,8 +44,8 @@ export const Paywall: FC> = (props) => { ); }; -const useStyles = makeStyles((theme) => ({ - root: { +const styles = { + root: (theme) => ({ display: "flex", flexDirection: "column", justifyContent: "center", @@ -57,24 +56,24 @@ const useStyles = makeStyles((theme) => ({ backgroundColor: theme.palette.background.paper, border: `1px solid ${theme.palette.divider}`, borderRadius: theme.shape.borderRadius, - }, - header: { + }), + header: (theme) => ({ marginBottom: theme.spacing(3), - }, + }), title: { fontWeight: 600, fontFamily: "inherit", }, - description: { + description: (theme) => ({ marginTop: theme.spacing(1), fontFamily: "inherit", maxWidth: 420, lineHeight: "160%", - }, - enterpriseChip: { + }), + enterpriseChip: (theme) => ({ background: theme.palette.success.dark, color: theme.palette.success.contrastText, border: `1px solid ${theme.palette.success.light}`, fontSize: 13, - }, -})); + }), +} satisfies Record>; diff --git a/site/src/components/Resources/AgentLatency.tsx b/site/src/components/Resources/AgentLatency.tsx index 47e941d1d8c10..a611f6ba70fa5 100644 --- a/site/src/components/Resources/AgentLatency.tsx +++ b/site/src/components/Resources/AgentLatency.tsx @@ -1,13 +1,13 @@ -import { useRef, useState, FC } from "react"; -import { makeStyles, useTheme } from "@mui/styles"; +import { type FC, useRef, useState } from "react"; +import { useTheme } from "@emotion/react"; import { Theme } from "@mui/material/styles"; +import type { WorkspaceAgent, DERPRegion } from "api/typesGenerated"; import { HelpTooltipText, HelpPopover, HelpTooltipTitle, } from "components/HelpTooltip/HelpTooltip"; import { Stack } from "components/Stack/Stack"; -import { WorkspaceAgent, DERPRegion } from "api/typesGenerated"; import { getLatencyColor } from "utils/latency"; const getDisplayLatency = (theme: Theme, agent: WorkspaceAgent) => { @@ -30,12 +30,11 @@ const getDisplayLatency = (theme: Theme, agent: WorkspaceAgent) => { }; export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => { - const theme: Theme = useTheme(); + const theme = useTheme(); const anchorRef = useRef(null); const [isOpen, setIsOpen] = useState(false); const id = isOpen ? "latency-popover" : undefined; const latency = getDisplayLatency(theme, agent); - const styles = useStyles(); if (!latency || !agent.latency) { return null; @@ -49,8 +48,7 @@ export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => { ref={anchorRef} onMouseEnter={() => setIsOpen(true)} onMouseLeave={() => setIsOpen(false)} - className={styles.trigger} - style={{ color: latency.color }} + css={{ cursor: "pointer", color: latency.color }} > {Math.round(Math.round(latency.latency_ms))}ms @@ -67,7 +65,11 @@ export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => { first row is the preferred relay. - + {Object.entries(agent.latency) .sort(([, a], [, b]) => a.latency_ms - b.latency_ms) .map(([regionName, region]) => ( @@ -76,7 +78,11 @@ export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => { key={regionName} spacing={0.5} justifyContent="space-between" - className={region.preferred ? styles.preferred : undefined} + css={ + region.preferred && { + color: theme.palette.text.primary, + } + } > {regionName} {Math.round(region.latency_ms)}ms @@ -88,15 +94,3 @@ export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => { ); }; - -const useStyles = makeStyles((theme) => ({ - trigger: { - cursor: "pointer", - }, - regions: { - marginTop: theme.spacing(2), - }, - preferred: { - color: theme.palette.text.primary, - }, -})); diff --git a/site/src/components/Resources/SSHButton/SSHButton.tsx b/site/src/components/Resources/SSHButton/SSHButton.tsx index 3a73f5e6af203..846ba5baaa1ea 100644 --- a/site/src/components/Resources/SSHButton/SSHButton.tsx +++ b/site/src/components/Resources/SSHButton/SSHButton.tsx @@ -1,15 +1,16 @@ import Popover from "@mui/material/Popover"; -import { makeStyles } from "@mui/styles"; -import { SecondaryAgentButton } from "components/Resources/AgentButton"; -import { useRef, useState } from "react"; -import { CodeExample } from "../../CodeExample/CodeExample"; -import { Stack } from "../../Stack/Stack"; +import { css } from "@emotion/css"; +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; +import { type FC, type PropsWithChildren, useRef, useState } from "react"; import { HelpTooltipLink, HelpTooltipLinksGroup, HelpTooltipText, } from "components/HelpTooltip/HelpTooltip"; import { docs } from "utils/docs"; +import { CodeExample } from "../../CodeExample/CodeExample"; +import { Stack } from "../../Stack/Stack"; +import { SecondaryAgentButton } from "../AgentButton"; export interface SSHButtonProps { workspaceName: string; @@ -18,16 +19,16 @@ export interface SSHButtonProps { sshPrefix?: string; } -export const SSHButton: React.FC> = ({ +export const SSHButton: FC> = ({ workspaceName, agentName, defaultIsOpen = false, sshPrefix, }) => { + const theme = useTheme(); const anchorRef = useRef(null); const [isOpen, setIsOpen] = useState(defaultIsOpen); const id = isOpen ? "schedule-popover" : undefined; - const styles = useStyles(); const onClose = () => { setIsOpen(false); @@ -45,7 +46,14 @@ export const SSHButton: React.FC> = ({ > = ({ Run the following commands to connect with SSH: - +
      - + Configure SSH hosts on machine: @@ -75,7 +83,7 @@ export const SSHButton: React.FC> = ({
      - + Connect to the agent: @@ -104,23 +112,12 @@ export const SSHButton: React.FC> = ({ ); }; -const useStyles = makeStyles((theme) => ({ - popoverPaper: { - padding: `${theme.spacing(2)} ${theme.spacing(3)} ${theme.spacing(3)}`, - width: theme.spacing(38), - color: theme.palette.text.secondary, - marginTop: theme.spacing(0.25), - }, - - codeExamples: { +const styles = { + codeExamples: (theme) => ({ marginTop: theme.spacing(1.5), - }, + }), codeExampleLabel: { fontSize: 12, }, - - textHelper: { - fontWeight: 400, - }, -})); +} satisfies Record>; diff --git a/site/src/components/Resources/SensitiveValue.tsx b/site/src/components/Resources/SensitiveValue.tsx index 15da9f8593c5f..dcf2fb5a6e710 100644 --- a/site/src/components/Resources/SensitiveValue.tsx +++ b/site/src/components/Resources/SensitiveValue.tsx @@ -1,10 +1,10 @@ import IconButton from "@mui/material/IconButton"; -import { makeStyles } from "@mui/styles"; import Tooltip from "@mui/material/Tooltip"; import VisibilityOffOutlined from "@mui/icons-material/VisibilityOffOutlined"; import VisibilityOutlined from "@mui/icons-material/VisibilityOutlined"; -import { CopyableValue } from "components/CopyableValue/CopyableValue"; import { useState } from "react"; +import { css } from "@emotion/react"; +import { CopyableValue } from "components/CopyableValue/CopyableValue"; const Language = { showLabel: "Show value", @@ -13,7 +13,6 @@ const Language = { export const SensitiveValue: React.FC<{ value: string }> = ({ value }) => { const [shouldDisplay, setShouldDisplay] = useState(false); - const styles = useStyles(); const displayValue = shouldDisplay ? value : "••••••••"; const buttonLabel = shouldDisplay ? Language.hideLabel : Language.showLabel; const icon = shouldDisplay ? ( @@ -23,13 +22,35 @@ export const SensitiveValue: React.FC<{ value: string }> = ({ value }) => { ); return ( -
      - +
      ({ + display: "flex", + alignItems: "center", + gap: theme.spacing(0.5), + })} + > + {displayValue} { setShouldDisplay((value) => !value); }} @@ -42,28 +63,3 @@ export const SensitiveValue: React.FC<{ value: string }> = ({ value }) => {
      ); }; - -const useStyles = makeStyles((theme) => ({ - value: { - // 22px is the button width - width: "calc(100% - 22px)", - overflow: "hidden", - whiteSpace: "nowrap", - textOverflow: "ellipsis", - }, - - sensitiveValue: { - display: "flex", - alignItems: "center", - gap: theme.spacing(0.5), - }, - - button: { - color: "inherit", - - "& .MuiSvgIcon-root": { - width: 16, - height: 16, - }, - }, -})); diff --git a/site/src/components/SignInLayout/SignInLayout.tsx b/site/src/components/SignInLayout/SignInLayout.tsx index 90e5212bb6d21..7a7c2f4b51bc8 100644 --- a/site/src/components/SignInLayout/SignInLayout.tsx +++ b/site/src/components/SignInLayout/SignInLayout.tsx @@ -1,40 +1,40 @@ -import { makeStyles } from "@mui/styles"; -import { FC, ReactNode } from "react"; - -export const useStyles = makeStyles((theme) => ({ - root: { - flex: 1, - height: "-webkit-fill-available", - display: "flex", - justifyContent: "center", - alignItems: "center", - }, - layout: { - display: "flex", - flexDirection: "column", - alignItems: "center", - }, - container: { - maxWidth: 385, - display: "flex", - flexDirection: "column", - alignItems: "center", - }, - footer: { - fontSize: 12, - color: theme.palette.text.secondary, - marginTop: theme.spacing(3), - }, -})); +import { type FC, type ReactNode } from "react"; export const SignInLayout: FC<{ children: ReactNode }> = ({ children }) => { - const styles = useStyles(); - return ( -
      -
      -
      {children}
      -
      +
      +
      +
      + {children} +
      +
      ({ + fontSize: 12, + color: theme.palette.text.secondary, + marginTop: theme.spacing(3), + })} + > {`\u00a9 ${new Date().getFullYear()} Coder Technologies, Inc.`}
      diff --git a/site/src/components/TableLoader/TableLoader.tsx b/site/src/components/TableLoader/TableLoader.tsx index 460f1adb29dbb..72a24b4c3cdcf 100644 --- a/site/src/components/TableLoader/TableLoader.tsx +++ b/site/src/components/TableLoader/TableLoader.tsx @@ -1,28 +1,27 @@ -import { makeStyles } from "@mui/styles"; import TableCell from "@mui/material/TableCell"; -import TableRow, { TableRowProps } from "@mui/material/TableRow"; -import { FC, ReactNode, cloneElement, isValidElement } from "react"; +import TableRow, { type TableRowProps } from "@mui/material/TableRow"; +import { type FC, type ReactNode, cloneElement, isValidElement } from "react"; +import { useTheme } from "@emotion/react"; import { Loader } from "../Loader/Loader"; export const TableLoader: FC = () => { - const styles = useStyles(); + const theme = useTheme(); return ( - + ); }; -const useStyles = makeStyles((theme) => ({ - cell: { - textAlign: "center", - height: theme.spacing(20), - }, -})); - export const TableLoaderSkeleton = ({ rows = 4, children, diff --git a/site/src/components/Timeline/TimelineDateRow.tsx b/site/src/components/Timeline/TimelineDateRow.tsx index ebffbb18e178e..1e67979ad6fb2 100644 --- a/site/src/components/Timeline/TimelineDateRow.tsx +++ b/site/src/components/Timeline/TimelineDateRow.tsx @@ -1,7 +1,7 @@ -import { makeStyles } from "@mui/styles"; import TableCell from "@mui/material/TableCell"; import TableRow from "@mui/material/TableRow"; -import { FC } from "react"; +import { type FC } from "react"; +import { css, useTheme } from "@emotion/react"; import { createDisplayDate } from "./utils"; export interface TimelineDateRow { @@ -9,32 +9,31 @@ export interface TimelineDateRow { } export const TimelineDateRow: FC = ({ date }) => { - const styles = useStyles(); + const theme = useTheme(); return ( - - + + {createDisplayDate(date)} ); }; - -const useStyles = makeStyles((theme) => ({ - dateRow: { - background: theme.palette.background.paper, - - "&:not(:first-of-type) td": { - borderTop: `1px solid ${theme.palette.divider}`, - }, - }, - - dateCell: { - padding: `${theme.spacing(1, 4)} !important`, - background: `${theme.palette.background.paperLight} !important`, - fontSize: 12, - position: "relative", - color: theme.palette.text.secondary, - textTransform: "capitalize", - }, -})); diff --git a/site/src/components/Welcome/Welcome.tsx b/site/src/components/Welcome/Welcome.tsx index 2257301831d54..916ed2c43e36f 100644 --- a/site/src/components/Welcome/Welcome.tsx +++ b/site/src/components/Welcome/Welcome.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from "@mui/styles"; import Typography from "@mui/material/Typography"; -import { FC, PropsWithChildren } from "react"; +import { type FC, type PropsWithChildren } from "react"; +import { css, useTheme } from "@emotion/react"; import { CoderIcon } from "../Icons/CoderIcon"; const Language = { @@ -14,40 +14,41 @@ const Language = { export const Welcome: FC< PropsWithChildren<{ message?: JSX.Element | string }> > = ({ message = Language.defaultMessage }) => { - const styles = useStyles(); + const theme = useTheme(); return (
      -
      - +
      +
      - + {message}
      ); }; - -const useStyles = makeStyles((theme) => ({ - logoBox: { - display: "flex", - justifyContent: "center", - }, - logo: { - color: theme.palette.text.primary, - fontSize: theme.spacing(8), - }, - title: { - textAlign: "center", - fontSize: theme.spacing(4), - fontWeight: 400, - margin: 0, - marginBottom: theme.spacing(2), - marginTop: theme.spacing(2), - lineHeight: 1.25, - - "& strong": { - fontWeight: 600, - }, - }, -})); diff --git a/site/src/pages/TemplatePage/TemplateLayout.tsx b/site/src/pages/TemplatePage/TemplateLayout.tsx index 291f4d8d89229..24f4487048320 100644 --- a/site/src/pages/TemplatePage/TemplateLayout.tsx +++ b/site/src/pages/TemplatePage/TemplateLayout.tsx @@ -1,20 +1,20 @@ -import { makeStyles } from "@mui/styles"; -import { useOrganizationId } from "hooks/useOrganizationId"; -import { createContext, FC, Suspense, useContext } from "react"; +import { css } from "@emotion/css"; +import { useTheme } from "@emotion/react"; +import { createContext, type FC, Suspense, useContext } from "react"; +import { useQuery } from "react-query"; import { NavLink, Outlet, useNavigate, useParams } from "react-router-dom"; -import { combineClasses } from "utils/combineClasses"; -import { Margins } from "components/Margins/Margins"; -import { Stack } from "components/Stack/Stack"; -import { Loader } from "components/Loader/Loader"; -import { TemplatePageHeader } from "./TemplatePageHeader"; +import type { AuthorizationRequest } from "api/typesGenerated"; import { checkAuthorization, getTemplateByName, getTemplateVersion, } from "api/api"; -import { useQuery } from "react-query"; -import { AuthorizationRequest } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; +import { Margins } from "components/Margins/Margins"; +import { Stack } from "components/Stack/Stack"; +import { Loader } from "components/Loader/Loader"; +import { useOrganizationId } from "hooks/useOrganizationId"; +import { TemplatePageHeader } from "./TemplatePageHeader"; const templatePermissions = ( templateId: string, @@ -63,8 +63,8 @@ export const useTemplateLayoutContext = (): TemplateLayoutContextValue => { export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ children = , }) => { + const theme = useTheme(); const navigate = useNavigate(); - const styles = useStyles(); const orgId = useOrganizationId(); const { template: templateName } = useParams() as { template: string }; const { data, error, isLoading } = useQuery({ @@ -75,7 +75,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ if (error) { return ( -
      +
      ); @@ -85,6 +85,34 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ return ; } + const itemStyles = css` + text-decoration: none; + color: ${theme.palette.text.secondary}; + font-size: 14; + display: block; + padding: ${theme.spacing(0, 2, 2)}; + + &:hover { + color: ${theme.palette.text.primary}; + } + `; + + const activeItemStyles = css` + ${itemStyles} + color: ${theme.palette.text.primary}; + position: relative; + + &:before { + content: ""; + left: 0; + bottom: 0; + height: 2; + width: 100%; + background: ${theme.palette.secondary.dark}; + position: absolute; + } + `; + return ( <> = ({ }} /> -
      +
      - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Summary @@ -115,10 +145,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ end to={`/templates/${templateName}/docs`} className={({ isActive }) => - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Docs @@ -127,10 +154,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Source Code @@ -139,10 +163,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Versions @@ -150,10 +171,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Embed @@ -162,10 +180,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) + isActive ? activeItemStyles : itemStyles } > Insights @@ -183,42 +198,3 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ ); }; - -export const useStyles = makeStyles((theme) => { - return { - error: { - margin: theme.spacing(2), - }, - tabs: { - borderBottom: `1px solid ${theme.palette.divider}`, - marginBottom: theme.spacing(5), - }, - - tabItem: { - textDecoration: "none", - color: theme.palette.text.secondary, - fontSize: 14, - display: "block", - padding: theme.spacing(0, 2, 2), - - "&:hover": { - color: theme.palette.text.primary, - }, - }, - - tabItemActive: { - color: theme.palette.text.primary, - position: "relative", - - "&:before": { - content: `""`, - left: 0, - bottom: 0, - height: 2, - width: "100%", - background: theme.palette.secondary.dark, - position: "absolute", - }, - }, - }; -}); diff --git a/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPageView.tsx b/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPageView.tsx index 2c3cd8d5100df..561e2ecbd3d76 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPageView.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPageView.tsx @@ -1,15 +1,14 @@ -import { +import { type ComponentProps, type FC } from "react"; +import type { CreateTemplateVersionRequest, TemplateVersion, TemplateVersionVariable, } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; -import { ComponentProps, FC } from "react"; -import { TemplateVariablesForm } from "./TemplateVariablesForm"; -import { makeStyles } from "@mui/styles"; import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Stack } from "components/Stack/Stack"; +import { TemplateVariablesForm } from "./TemplateVariablesForm"; export interface TemplateVariablesPageViewProps { templateVersion?: TemplateVersion; @@ -41,16 +40,15 @@ export const TemplateVariablesPageView: FC = ({ errors = {}, initialTouched, }) => { - const classes = useStyles(); const hasError = Object.values(errors).some((error) => Boolean(error)); return ( <> - + Template variables {hasError && ( - + ({ marginBottom: theme.spacing(8) })}> {Boolean(errors.buildError) && ( )} @@ -78,17 +76,3 @@ export const TemplateVariablesPageView: FC = ({ ); }; - -const useStyles = makeStyles((theme) => ({ - errorContainer: { - marginBottom: theme.spacing(8), - }, - goBackSection: { - display: "flex", - width: "100%", - marginTop: 32, - }, - pageHeader: { - paddingTop: 0, - }, -})); diff --git a/site/src/pages/TemplatesPage/EmptyTemplates.tsx b/site/src/pages/TemplatesPage/EmptyTemplates.tsx index 2b3c32b469206..8b5fb55136067 100644 --- a/site/src/pages/TemplatesPage/EmptyTemplates.tsx +++ b/site/src/pages/TemplatesPage/EmptyTemplates.tsx @@ -1,13 +1,13 @@ +import { type Interpolation, type Theme } from "@emotion/react"; import Button from "@mui/material/Button"; import Link from "@mui/material/Link"; -import { makeStyles } from "@mui/styles"; -import { TemplateExample } from "api/typesGenerated"; +import { Link as RouterLink } from "react-router-dom"; +import { type FC } from "react"; +import type { TemplateExample } from "api/typesGenerated"; import { CodeExample } from "components/CodeExample/CodeExample"; import { Stack } from "components/Stack/Stack"; import { TableEmpty } from "components/TableEmpty/TableEmpty"; import { TemplateExampleCard } from "components/TemplateExampleCard/TemplateExampleCard"; -import { FC } from "react"; -import { Link as RouterLink } from "react-router-dom"; import { docs } from "utils/docs"; // Those are from https://github.com/coder/coder/tree/main/examples/templates @@ -39,7 +39,6 @@ export const EmptyTemplates: FC<{ canCreateTemplates: boolean; examples: TemplateExample[]; }> = ({ canCreateTemplates, examples }) => { - const styles = useStyles(); const featuredExamples = findFeaturedExamples(examples); if (canCreateTemplates) { @@ -63,12 +62,12 @@ export const EmptyTemplates: FC<{ } cta={ -
      +
      {featuredExamples.map((example) => ( ))}
      @@ -77,7 +76,7 @@ export const EmptyTemplates: FC<{ size="small" component={RouterLink} to="/starter-templates" - className={styles.viewAllButton} + css={styles.viewAllButton} > View all starter templates @@ -89,12 +88,12 @@ export const EmptyTemplates: FC<{ return ( } image={ -
      +
      } @@ -102,12 +101,12 @@ export const EmptyTemplates: FC<{ ); }; -const useStyles = makeStyles((theme) => ({ +const styles = { withImage: { paddingBottom: 0, }, - emptyImage: { + emptyImage: (theme) => ({ maxWidth: "50%", height: theme.spacing(40), overflow: "hidden", @@ -116,25 +115,25 @@ const useStyles = makeStyles((theme) => ({ "& img": { maxWidth: "100%", }, - }, + }), - featuredExamples: { + featuredExamples: (theme) => ({ maxWidth: theme.spacing(100), display: "grid", gridTemplateColumns: "repeat(2, minmax(0, 1fr))", gap: theme.spacing(2), gridAutoRows: "min-content", - }, + }), - template: { + template: (theme) => ({ backgroundColor: theme.palette.background.paperLight, "&:hover": { backgroundColor: theme.palette.divider, }, - }, + }), viewAllButton: { borderRadius: 9999, }, -})); +} satisfies Record>; diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx index 5ab0f9af3fab4..7ded569057a85 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx @@ -1,11 +1,11 @@ -import { makeStyles } from "@mui/styles"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import CircularProgress from "@mui/material/CircularProgress"; -import { GitSSHKey } from "api/typesGenerated"; +import { type FC, type PropsWithChildren } from "react"; +import { useTheme } from "@emotion/react"; +import type { GitSSHKey } from "api/typesGenerated"; import { CodeExample } from "components/CodeExample/CodeExample"; import { Stack } from "components/Stack/Stack"; -import { FC } from "react"; import { ErrorAlert } from "components/Alert/ErrorAlert"; export interface SSHKeysPageViewProps { @@ -16,16 +16,14 @@ export interface SSHKeysPageViewProps { onRegenerateClick: () => void; } -export const SSHKeysPageView: FC< - React.PropsWithChildren -> = ({ +export const SSHKeysPageView: FC> = ({ isLoading, getSSHKeyError, regenerateSSHKeyError, sshKey, onRegenerateClick, }) => { - const styles = useStyles(); + const theme = useTheme(); if (isLoading) { return ( @@ -45,11 +43,28 @@ export const SSHKeysPageView: FC< )} {sshKey && ( <> -

      +

      The following public key is used to authenticate Git in workspaces. You may add it to Git services (such as GitHub) that you need to access from your workspace. Coder configures authentication via{" "} - $GIT_SSH_COMMAND. + + $GIT_SSH_COMMAND + + .

      @@ -62,18 +77,3 @@ export const SSHKeysPageView: FC< ); }; - -const useStyles = makeStyles((theme) => ({ - description: { - fontSize: 14, - color: theme.palette.text.secondary, - margin: 0, - }, - code: { - background: theme.palette.divider, - fontSize: 12, - padding: "2px 4px", - color: theme.palette.text.primary, - borderRadius: 2, - }, -})); diff --git a/site/src/pages/UsersPage/ResetPasswordDialog.tsx b/site/src/pages/UsersPage/ResetPasswordDialog.tsx index 691131c30e51e..42725a1e8f38b 100644 --- a/site/src/pages/UsersPage/ResetPasswordDialog.tsx +++ b/site/src/pages/UsersPage/ResetPasswordDialog.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from "@mui/styles"; -import { FC } from "react"; -import * as TypesGen from "api/typesGenerated"; +import { type FC } from "react"; +import { useTheme } from "@emotion/react"; +import type * as TypesGen from "api/typesGenerated"; import { CodeExample } from "components/CodeExample/CodeExample"; import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"; @@ -26,12 +26,20 @@ export const Language = { export const ResetPasswordDialog: FC< React.PropsWithChildren > = ({ open, onClose, onConfirm, user, newPassword, loading }) => { - const styles = useStyles(); + const theme = useTheme(); const description = ( <>

      {Language.message(user?.username)}

      - + ); @@ -49,12 +57,3 @@ export const ResetPasswordDialog: FC< /> ); }; - -const useStyles = makeStyles((theme) => ({ - codeExample: { - minHeight: "auto", - userSelect: "all", - width: "100%", - marginTop: theme.spacing(3), - }, -})); diff --git a/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx b/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx index 3cdc23936f785..de849f4636599 100644 --- a/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx +++ b/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx @@ -1,32 +1,30 @@ -import Box, { BoxProps } from "@mui/material/Box"; -import { makeStyles, useTheme } from "@mui/styles"; +import Box, { type BoxProps } from "@mui/material/Box"; import TableCell from "@mui/material/TableCell"; import TableRow from "@mui/material/TableRow"; +import Skeleton from "@mui/material/Skeleton"; +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; +import { type FC } from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type * as TypesGen from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { Pill } from "components/Pill/Pill"; -import { type FC } from "react"; -import * as TypesGen from "api/typesGenerated"; -import { combineClasses } from "utils/combineClasses"; import { AvatarData } from "components/AvatarData/AvatarData"; +import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"; import { EmptyState } from "components/EmptyState/EmptyState"; import { TableLoaderSkeleton, TableRowSkeleton, } from "components/TableLoader/TableLoader"; import { TableRowMenu } from "components/TableRowMenu/TableRowMenu"; -import { EditRolesButton } from "./EditRolesButton"; import { Stack } from "components/Stack/Stack"; import { EnterpriseBadge } from "components/DeploySettingsLayout/Badges"; -import dayjs from "dayjs"; -import { SxProps, Theme } from "@mui/material/styles"; +import { EditRolesButton } from "./EditRolesButton"; import HideSourceOutlined from "@mui/icons-material/HideSourceOutlined"; import KeyOutlined from "@mui/icons-material/KeyOutlined"; import GitHub from "@mui/icons-material/GitHub"; import PasswordOutlined from "@mui/icons-material/PasswordOutlined"; -import relativeTime from "dayjs/plugin/relativeTime"; import ShieldOutlined from "@mui/icons-material/ShieldOutlined"; -import Skeleton from "@mui/material/Skeleton"; -import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"; dayjs.extend(relativeTime); @@ -89,8 +87,6 @@ export const UsersTableBody: FC< actorID, oidcRoleSyncEnabled, }) => { - const styles = useStyles(); - return ( @@ -185,10 +181,10 @@ export const UsersTableBody: FC< ))} @@ -200,12 +196,10 @@ export const UsersTableBody: FC< /> {user.status} @@ -273,9 +267,9 @@ const LoginType = ({ authMethods: TypesGen.AuthMethods; value: TypesGen.LoginType; }) => { - let displayName = value as string; + let displayName: string = value; let icon = <>; - const iconStyles: SxProps = { width: 14, height: 14 }; + const iconStyles = { width: 14, height: 14 }; if (value === "password") { displayName = "Password"; @@ -314,7 +308,7 @@ const LoginType = ({ }; const LastSeen = ({ value, ...boxProps }: { value: string } & BoxProps) => { - const theme: Theme = useTheme(); + const theme = useTheme(); const t = dayjs(value); const now = dayjs(); @@ -348,19 +342,19 @@ const LastSeen = ({ value, ...boxProps }: { value: string } & BoxProps) => { ); }; -const useStyles = makeStyles((theme) => ({ +const styles = { status: { textTransform: "capitalize", }, - suspended: { + suspended: (theme) => ({ color: theme.palette.text.secondary, - }, - rolePill: { + }), + rolePill: (theme) => ({ backgroundColor: theme.palette.background.paperLight, borderColor: theme.palette.divider, - }, - rolePillOwner: { + }), + rolePillOwner: (theme) => ({ backgroundColor: theme.palette.info.dark, borderColor: theme.palette.info.light, - }, -})); + }), +} satisfies Record>; diff --git a/site/src/pages/WorkspacePage/BuildRow.tsx b/site/src/pages/WorkspacePage/BuildRow.tsx index 64c61b7c36a31..693e1508dd5af 100644 --- a/site/src/pages/WorkspacePage/BuildRow.tsx +++ b/site/src/pages/WorkspacePage/BuildRow.tsx @@ -1,16 +1,15 @@ -import { makeStyles } from "@mui/styles"; import TableCell from "@mui/material/TableCell"; -import { WorkspaceBuild } from "api/typesGenerated"; +import { type CSSObject, type Interpolation, type Theme } from "@emotion/react"; +import { useNavigate } from "react-router-dom"; +import type { WorkspaceBuild } from "api/typesGenerated"; +import { BuildAvatar } from "components/BuildAvatar/BuildAvatar"; import { Stack } from "components/Stack/Stack"; import { TimelineEntry } from "components/Timeline/TimelineEntry"; import { useClickable } from "hooks/useClickable"; -import { useNavigate } from "react-router-dom"; -import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { displayWorkspaceBuildDuration, getDisplayWorkspaceBuildInitiatedBy, } from "utils/workspace"; -import { BuildAvatar } from "components/BuildAvatar/BuildAvatar"; export interface BuildRowProps { build: WorkspaceBuild; @@ -23,7 +22,6 @@ const transitionMessages = { }; export const BuildRow: React.FC = ({ build }) => { - const styles = useStyles(); const initiatedBy = getDisplayWorkspaceBuildInitiatedBy(build); const navigate = useNavigate(); const clickableProps = useClickable(() => @@ -32,26 +30,18 @@ export const BuildRow: React.FC = ({ build }) => { return ( - - - + + + = ({ build }) => { workspace - + {new Date(build.created_at).toLocaleTimeString()} - + Reason: {build.reason} - + Duration:{" "} {displayWorkspaceBuildDuration(build)} - + Version: {build.template_version_name} @@ -90,10 +80,10 @@ export const BuildRow: React.FC = ({ build }) => { ); }; -const useStyles = makeStyles((theme) => ({ - buildWrapper: { +const styles = { + buildWrapper: (theme) => ({ padding: theme.spacing(2, 4), - }, + }), buildCell: { padding: "0 !important", @@ -101,36 +91,25 @@ const useStyles = makeStyles((theme) => ({ borderBottom: 0, }, - buildSummary: { - ...theme.typography.body1, + buildSummary: (theme) => ({ + ...(theme.typography.body1 as CSSObject), fontFamily: "inherit", - }, + }), - buildInfo: { - ...theme.typography.body2, + buildInfo: (theme) => ({ + ...(theme.typography.body2 as CSSObject), fontSize: 12, fontFamily: "inherit", color: theme.palette.text.secondary, display: "block", - }, + }), - buildTime: { + buildTime: (theme) => ({ color: theme.palette.text.secondary, fontSize: 12, - }, - - buildRight: { - width: "auto", - }, - - buildExtraInfo: { - ...theme.typography.body2, - fontFamily: MONOSPACE_FONT_FAMILY, - color: theme.palette.text.secondary, - whiteSpace: "nowrap", - }, + }), fullWidth: { width: "100%", }, -})); +} satisfies Record>; diff --git a/site/src/pages/WorkspacePage/UpdateBuildParametersDialog.tsx b/site/src/pages/WorkspacePage/UpdateBuildParametersDialog.tsx index fadc9a8a94b72..f91f807ac8a17 100644 --- a/site/src/pages/WorkspacePage/UpdateBuildParametersDialog.tsx +++ b/site/src/pages/WorkspacePage/UpdateBuildParametersDialog.tsx @@ -1,25 +1,26 @@ -import { makeStyles } from "@mui/styles"; import Dialog from "@mui/material/Dialog"; import DialogContent from "@mui/material/DialogContent"; import DialogContentText from "@mui/material/DialogContentText"; import DialogTitle from "@mui/material/DialogTitle"; -import { DialogProps } from "components/Dialogs/Dialog"; -import { FC } from "react"; +import DialogActions from "@mui/material/DialogActions"; +import Button from "@mui/material/Button"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { type FC } from "react"; +import { css } from "@emotion/css"; +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; import { getFormHelpers } from "utils/formUtils"; +import type { DialogProps } from "components/Dialogs/Dialog"; import { FormFields, VerticalForm } from "components/Form/Form"; -import { +import type { TemplateVersionParameter, WorkspaceBuildParameter, } from "api/typesGenerated"; import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"; -import { useFormik } from "formik"; import { getInitialRichParameterValues, useValidationSchemaForRichParameters, } from "utils/richParameters"; -import * as Yup from "yup"; -import DialogActions from "@mui/material/DialogActions"; -import Button from "@mui/material/Button"; export type UpdateBuildParametersDialogProps = DialogProps & { onClose: () => void; @@ -30,7 +31,7 @@ export type UpdateBuildParametersDialogProps = DialogProps & { export const UpdateBuildParametersDialog: FC< UpdateBuildParametersDialogProps > = ({ missedParameters, onUpdate, ...dialogProps }) => { - const styles = useStyles(); + const theme = useTheme(); const form = useFormik({ initialValues: { rich_parameter_values: getInitialRichParameterValues(missedParameters), @@ -56,17 +57,26 @@ export const UpdateBuildParametersDialog: FC< > Workspace parameters - - + + This template has new parameters that must be configured to complete the update @@ -96,7 +106,7 @@ export const UpdateBuildParametersDialog: FC< )} - + @@ -114,48 +124,18 @@ export const UpdateBuildParametersDialog: FC< ); }; -const useStyles = makeStyles((theme) => ({ - title: { - padding: theme.spacing(3, 5), - - "& h2": { - fontSize: theme.spacing(2.5), - fontWeight: 400, - }, - }, - - content: { +const styles = { + content: (theme) => ({ padding: theme.spacing(0, 5, 0, 5), - }, + }), - info: { - margin: 0, - }, - - form: { + form: (theme) => ({ paddingTop: theme.spacing(4), - }, - - infoTitle: { - fontSize: theme.spacing(2), - fontWeight: 600, - display: "flex", - alignItems: "center", - gap: theme.spacing(1), - }, - - warningIcon: { - color: theme.palette.warning.light, - fontSize: theme.spacing(1.5), - }, - - formFooter: { - flexDirection: "column", - }, + }), - dialogActions: { + dialogActions: (theme) => ({ padding: theme.spacing(5), flexDirection: "column", gap: theme.spacing(1), - }, -})); + }), +} satisfies Record>; diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx index ebfab404172d4..7dbcd6cc0527a 100644 --- a/site/src/pages/WorkspacePage/Workspace.tsx +++ b/site/src/pages/WorkspacePage/Workspace.tsx @@ -1,22 +1,14 @@ +import { type Interpolation, type Theme } from "@emotion/react"; import Button from "@mui/material/Button"; -import { makeStyles } from "@mui/styles"; -import { Avatar } from "components/Avatar/Avatar"; -import { AgentRow } from "components/Resources/AgentRow"; -import { - ActiveTransition, - WorkspaceBuildProgress, -} from "./WorkspaceBuildProgress"; -import { FC, useEffect, useState } from "react"; +import AlertTitle from "@mui/material/AlertTitle"; +import { type FC, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -import * as TypesGen from "api/typesGenerated"; +import dayjs from "dayjs"; +import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDetail } from "components/Alert/Alert"; -import { BuildsTable } from "./BuildsTable"; import { Margins } from "components/Margins/Margins"; import { Resources } from "components/Resources/Resources"; import { Stack } from "components/Stack/Stack"; -import { WorkspaceActions } from "pages/WorkspacePage/WorkspaceActions/WorkspaceActions"; -import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner"; -import { WorkspaceStats } from "./WorkspaceStats"; import { FullWidthPageHeader, PageHeaderActions, @@ -26,9 +18,17 @@ import { import { TemplateVersionWarnings } from "components/TemplateVersionWarnings/TemplateVersionWarnings"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { DormantWorkspaceBanner } from "components/WorkspaceDeletion"; +import { Avatar } from "components/Avatar/Avatar"; +import { AgentRow } from "components/Resources/AgentRow"; import { useLocalStorage } from "hooks"; -import AlertTitle from "@mui/material/AlertTitle"; -import dayjs from "dayjs"; +import { WorkspaceActions } from "pages/WorkspacePage/WorkspaceActions/WorkspaceActions"; +import { + ActiveTransition, + WorkspaceBuildProgress, +} from "./WorkspaceBuildProgress"; +import { BuildsTable } from "./BuildsTable"; +import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner"; +import { WorkspaceStats } from "./WorkspaceStats"; export enum WorkspaceErrors { GET_BUILDS_ERROR = "getBuildsError", @@ -112,7 +112,6 @@ export const Workspace: FC> = ({ isLoadingMoreBuilds, hasMoreBuilds, }) => { - const styles = useStyles(); const navigate = useNavigate(); const serverVersion = buildInfo?.version || ""; const { saveLocal, getLocal } = useLocalStorage(); @@ -219,12 +218,8 @@ export const Workspace: FC> = ({ )} - - + + {workspace.outdated && ( An update is available for your workspace @@ -282,7 +277,7 @@ export const Workspace: FC> = ({ Workspace build is pending -
      +
      This workspace build job is waiting for a provisioner to become available. If you have been waiting for an extended period of time, please contact your administrator for @@ -364,58 +359,22 @@ export const Workspace: FC> = ({ ); }; -const spacerWidth = 300; - -export const useStyles = makeStyles((theme) => { - return { - content: { - marginTop: theme.spacing(4), - }, - - statusBadge: { - marginLeft: theme.spacing(2), - }, - - actions: { - [theme.breakpoints.down("md")]: { - flexDirection: "column", - }, - }, - - firstColumnSpacer: { - flex: 2, - }, - - secondColumnSpacer: { - flex: `0 0 ${spacerWidth}px`, - }, - - layout: { - alignItems: "flex-start", - }, +const styles = { + content: (theme) => ({ + marginTop: theme.spacing(4), + }), - main: { - width: "100%", + actions: (theme) => ({ + [theme.breakpoints.down("md")]: { + flexDirection: "column", }, + }), - timelineContents: { - margin: 0, - }, - logs: { - border: `1px solid ${theme.palette.divider}`, - }, + firstColumnSpacer: { + flex: 2, + }, - errorDetails: { - color: theme.palette.text.secondary, - fontSize: 12, - }, - - fullWidth: { - width: "100%", - }, - - alertPendingInQueue: { - marginBottom: 12, - }, - }; -}); + alertPendingInQueue: { + marginBottom: 12, + }, +} satisfies Record>; diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsLayout.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsLayout.tsx index 4c9d5aea616dc..a3c2340fda298 100644 --- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsLayout.tsx +++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsLayout.tsx @@ -1,16 +1,16 @@ -import { makeStyles } from "@mui/styles"; -import { Sidebar } from "./Sidebar"; -import { Stack } from "components/Stack/Stack"; -import { createContext, FC, Suspense, useContext } from "react"; +import { createContext, type FC, Suspense, useContext } from "react"; import { Helmet } from "react-helmet-async"; -import { pageTitle } from "utils/page"; -import { Loader } from "components/Loader/Loader"; import { Outlet, useParams } from "react-router-dom"; -import { Margins } from "components/Margins/Margins"; -import { workspaceByOwnerAndName } from "api/queries/workspaces"; import { useQuery } from "react-query"; +import { useTheme } from "@emotion/react"; +import type { Workspace } from "api/typesGenerated"; +import { workspaceByOwnerAndName } from "api/queries/workspaces"; import { ErrorAlert } from "components/Alert/ErrorAlert"; -import { type Workspace } from "api/typesGenerated"; +import { Loader } from "components/Loader/Loader"; +import { Margins } from "components/Margins/Margins"; +import { Stack } from "components/Stack/Stack"; +import { pageTitle } from "utils/page"; +import { Sidebar } from "./Sidebar"; const WorkspaceSettings = createContext(undefined); @@ -26,7 +26,7 @@ export function useWorkspaceSettings() { } export const WorkspaceSettingsLayout: FC = () => { - const styles = useStyles(); + const theme = useTheme(); const params = useParams() as { workspace: string; username: string; @@ -51,14 +51,18 @@ export const WorkspaceSettingsLayout: FC = () => { - + {isError ? ( ) : ( }> -
      +
      @@ -69,13 +73,3 @@ export const WorkspaceSettingsLayout: FC = () => { ); }; - -const useStyles = makeStyles((theme) => ({ - wrapper: { - padding: theme.spacing(6, 0), - }, - - content: { - width: "100%", - }, -}));