mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
chore: use emotion for styling (pt. 6) (#10298)
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { ComponentProps, FC } from "react";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { type ComponentProps, type FC } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import RefreshIcon from "@mui/icons-material/RefreshOutlined";
|
||||
import {
|
||||
HelpTooltipText,
|
||||
@ -9,7 +9,7 @@ import {
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipContext,
|
||||
} from "components/HelpTooltip/HelpTooltip";
|
||||
import { WorkspaceAgent } from "api/typesGenerated";
|
||||
import type { WorkspaceAgent } from "api/typesGenerated";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
|
||||
type AgentOutdatedTooltipProps = ComponentProps<typeof HelpPopover> & {
|
||||
@ -28,7 +28,11 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
onClose,
|
||||
anchorEl,
|
||||
}) => {
|
||||
const styles = useStyles();
|
||||
const theme = useTheme();
|
||||
const versionLabelStyles = {
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary,
|
||||
};
|
||||
|
||||
return (
|
||||
<HelpPopover
|
||||
@ -50,12 +54,12 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
</div>
|
||||
|
||||
<Stack spacing={0.5}>
|
||||
<span className={styles.versionLabel}>Agent version</span>
|
||||
<span css={versionLabelStyles}>Agent version</span>
|
||||
<span>{agent.version}</span>
|
||||
</Stack>
|
||||
|
||||
<Stack spacing={0.5}>
|
||||
<span className={styles.versionLabel}>Server version</span>
|
||||
<span css={versionLabelStyles}>Server version</span>
|
||||
<span>{serverVersion}</span>
|
||||
</Stack>
|
||||
|
||||
@ -73,10 +77,3 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
versionLabel: {
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}));
|
||||
|
@ -1,18 +1,17 @@
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import Link from "@mui/material/Link";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import { type FC, useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { getApiKey } from "api/api";
|
||||
import type * as TypesGen from "api/typesGenerated";
|
||||
import { useProxy } from "contexts/ProxyContext";
|
||||
import { PrimaryAgentButton } from "components/Resources/AgentButton";
|
||||
import { FC, useState } from "react";
|
||||
import { combineClasses } from "utils/combineClasses";
|
||||
import * as TypesGen from "api/typesGenerated";
|
||||
import { createAppLinkHref } from "utils/apps";
|
||||
import { generateRandomString } from "utils/random";
|
||||
import { BaseIcon } from "./BaseIcon";
|
||||
import { ShareIcon } from "./ShareIcon";
|
||||
import { useProxy } from "contexts/ProxyContext";
|
||||
import { createAppLinkHref } from "utils/apps";
|
||||
import { getApiKey } from "api/api";
|
||||
|
||||
const Language = {
|
||||
appTitle: (appName: string, identifier: string): string =>
|
||||
@ -31,7 +30,7 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
|
||||
const appsHost = proxy.preferredWildcardHostname;
|
||||
const [fetchingSessionToken, setFetchingSessionToken] = useState(false);
|
||||
|
||||
const styles = useStyles();
|
||||
const theme = useTheme();
|
||||
const username = workspace.owner_name;
|
||||
|
||||
let appSlug = app.slug;
|
||||
@ -65,12 +64,18 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
|
||||
}
|
||||
if (app.health === "unhealthy") {
|
||||
canClick = false;
|
||||
icon = <ErrorOutlineIcon className={styles.unhealthyIcon} />;
|
||||
icon = <ErrorOutlineIcon css={{ color: theme.palette.warning.light }} />;
|
||||
primaryTooltip = "Unhealthy";
|
||||
}
|
||||
if (!appsHost && app.subdomain) {
|
||||
canClick = false;
|
||||
icon = <ErrorOutlineIcon className={styles.notConfiguredIcon} />;
|
||||
icon = (
|
||||
<ErrorOutlineIcon
|
||||
css={{
|
||||
color: theme.palette.grey[300],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
primaryTooltip =
|
||||
"Your admin has not configured subdomain application access";
|
||||
}
|
||||
@ -86,7 +91,13 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
|
||||
endIcon={isPrivateApp ? undefined : <ShareIcon app={app} />}
|
||||
disabled={!canClick}
|
||||
>
|
||||
<span className={combineClasses({ [styles.appName]: !isPrivateApp })}>
|
||||
<span
|
||||
css={
|
||||
!isPrivateApp && {
|
||||
marginRight: theme.spacing(1),
|
||||
}
|
||||
}
|
||||
>
|
||||
{appDisplayName}
|
||||
</span>
|
||||
</PrimaryAgentButton>
|
||||
@ -98,7 +109,10 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
|
||||
<Link
|
||||
href={href}
|
||||
target="_blank"
|
||||
className={canClick ? styles.link : styles.disabledLink}
|
||||
css={{
|
||||
pointerEvents: canClick ? undefined : "none",
|
||||
textDecoration: "none !important",
|
||||
}}
|
||||
onClick={
|
||||
canClick
|
||||
? async (event) => {
|
||||
@ -143,26 +157,3 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
link: {
|
||||
textDecoration: "none !important",
|
||||
},
|
||||
|
||||
disabledLink: {
|
||||
pointerEvents: "none",
|
||||
textDecoration: "none !important",
|
||||
},
|
||||
|
||||
unhealthyIcon: {
|
||||
color: theme.palette.warning.light,
|
||||
},
|
||||
|
||||
notConfiguredIcon: {
|
||||
color: theme.palette.grey[300],
|
||||
},
|
||||
|
||||
appName: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
@ -1,7 +1,12 @@
|
||||
import Box from "@mui/material/Box";
|
||||
import Link from "@mui/material/Link";
|
||||
import Popover from "@mui/material/Popover";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined";
|
||||
import { css } from "@emotion/css";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useRef, useState } from "react";
|
||||
import { useQuery } from "react-query";
|
||||
import { colors } from "theme/colors";
|
||||
import {
|
||||
HelpTooltipLink,
|
||||
@ -11,16 +16,12 @@ import {
|
||||
} from "components/HelpTooltip/HelpTooltip";
|
||||
import { SecondaryAgentButton } from "components/Resources/AgentButton";
|
||||
import { docs } from "utils/docs";
|
||||
import Box from "@mui/material/Box";
|
||||
import { useQuery } from "react-query";
|
||||
import { getAgentListeningPorts } from "api/api";
|
||||
import {
|
||||
import type {
|
||||
WorkspaceAgent,
|
||||
WorkspaceAgentListeningPort,
|
||||
} from "api/typesGenerated";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import { portForwardURL } from "utils/portForward";
|
||||
import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined";
|
||||
|
||||
export interface PortForwardButtonProps {
|
||||
host: string;
|
||||
@ -30,10 +31,10 @@ export interface PortForwardButtonProps {
|
||||
}
|
||||
|
||||
export const PortForwardButton: React.FC<PortForwardButtonProps> = (props) => {
|
||||
const theme = useTheme();
|
||||
const anchorRef = useRef<HTMLButtonElement>(null);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const id = isOpen ? "schedule-popover" : undefined;
|
||||
const styles = useStyles();
|
||||
const portsQuery = useQuery({
|
||||
queryKey: ["portForward", props.agent.id],
|
||||
queryFn: () => getAgentListeningPorts(props.agent.id),
|
||||
@ -78,7 +79,14 @@ export const PortForwardButton: React.FC<PortForwardButtonProps> = (props) => {
|
||||
)}
|
||||
</SecondaryAgentButton>
|
||||
<Popover
|
||||
classes={{ paper: styles.popoverPaper }}
|
||||
classes={{
|
||||
paper: css`
|
||||
padding: 0;
|
||||
width: ${theme.spacing(38)};
|
||||
color: ${theme.palette.text.secondary};
|
||||
margin-top: ${theme.spacing(0.5)};
|
||||
`,
|
||||
}}
|
||||
id={id}
|
||||
open={isOpen}
|
||||
anchorEl={anchorRef.current}
|
||||
@ -245,31 +253,3 @@ export const PortForwardPopoverView: React.FC<
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
popoverPaper: {
|
||||
padding: 0,
|
||||
width: theme.spacing(38),
|
||||
color: theme.palette.text.secondary,
|
||||
marginTop: theme.spacing(0.5),
|
||||
},
|
||||
|
||||
openUrlButton: {
|
||||
flexShrink: 0,
|
||||
},
|
||||
|
||||
portField: {
|
||||
// The default border don't contrast well with the popover
|
||||
"& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: colors.gray[10],
|
||||
},
|
||||
},
|
||||
|
||||
code: {
|
||||
margin: theme.spacing(2, 0),
|
||||
},
|
||||
|
||||
form: {
|
||||
margin: theme.spacing(2, 0),
|
||||
},
|
||||
}));
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { FC, ReactNode, PropsWithChildren } from "react";
|
||||
import { type FC, type ReactNode, type PropsWithChildren } from "react";
|
||||
import { SectionAction } from "./SectionAction";
|
||||
import { type Interpolation, type Theme } from "@emotion/react";
|
||||
|
||||
type SectionLayout = "fixed" | "fluid";
|
||||
|
||||
@ -31,12 +32,13 @@ export const Section: SectionFC = ({
|
||||
children,
|
||||
layout = "fixed",
|
||||
}) => {
|
||||
const styles = useStyles({ layout });
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<section className={className} id={id} data-testid={id}>
|
||||
<div className={styles.inner}>
|
||||
<div css={{ maxWidth: layout === "fluid" ? "100%" : 500 }}>
|
||||
{(title || description) && (
|
||||
<div className={styles.header}>
|
||||
<div css={styles.header}>
|
||||
<div>
|
||||
{title && (
|
||||
<Typography variant="h4" sx={{ fontSize: 24 }}>
|
||||
@ -44,18 +46,16 @@ export const Section: SectionFC = ({
|
||||
</Typography>
|
||||
)}
|
||||
{description && typeof description === "string" && (
|
||||
<Typography className={styles.description}>
|
||||
{description}
|
||||
</Typography>
|
||||
<Typography css={styles.description}>{description}</Typography>
|
||||
)}
|
||||
{description && typeof description !== "string" && (
|
||||
<div className={styles.description}>{description}</div>
|
||||
<div css={styles.description}>{description}</div>
|
||||
)}
|
||||
</div>
|
||||
{toolbar && <div>{toolbar}</div>}
|
||||
</div>
|
||||
)}
|
||||
{alert && <div className={styles.alert}>{alert}</div>}
|
||||
{alert && <div css={{ marginBottom: theme.spacing(1) }}>{alert}</div>}
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
@ -65,23 +65,17 @@ export const Section: SectionFC = ({
|
||||
// Sub-components
|
||||
Section.Action = SectionAction;
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
inner: ({ layout }: { layout: SectionLayout }) => ({
|
||||
maxWidth: layout === "fluid" ? "100%" : 500,
|
||||
}),
|
||||
alert: {
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
header: {
|
||||
const styles = {
|
||||
header: (theme) => ({
|
||||
marginBottom: theme.spacing(3),
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
description: {
|
||||
}),
|
||||
description: (theme) => ({
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 16,
|
||||
marginTop: theme.spacing(0.5),
|
||||
lineHeight: "140%",
|
||||
},
|
||||
}));
|
||||
}),
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
Reference in New Issue
Block a user