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