mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
site: new dark theme (#10331)
This commit is contained in:
@ -7,14 +7,21 @@ import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
|
|||||||
import { withRouter } from "storybook-addon-react-router-v6";
|
import { withRouter } from "storybook-addon-react-router-v6";
|
||||||
import { HelmetProvider } from "react-helmet-async";
|
import { HelmetProvider } from "react-helmet-async";
|
||||||
import { dark } from "theme/mui";
|
import { dark } from "theme/mui";
|
||||||
|
import { dark as experimental } from "theme/experimental";
|
||||||
|
import colors from "theme/tailwind";
|
||||||
import "theme/globalFonts";
|
import "theme/globalFonts";
|
||||||
import { QueryClient, QueryClientProvider } from "react-query";
|
import { QueryClient, QueryClientProvider } from "react-query";
|
||||||
|
|
||||||
|
const theme = {
|
||||||
|
...dark,
|
||||||
|
experimental,
|
||||||
|
};
|
||||||
|
|
||||||
export const decorators = [
|
export const decorators = [
|
||||||
(Story) => (
|
(Story) => (
|
||||||
<StyledEngineProvider injectFirst>
|
<StyledEngineProvider injectFirst>
|
||||||
<MuiThemeProvider theme={dark}>
|
<MuiThemeProvider theme={theme}>
|
||||||
<EmotionThemeProvider theme={dark}>
|
<EmotionThemeProvider theme={theme}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<Story />
|
<Story />
|
||||||
</EmotionThemeProvider>
|
</EmotionThemeProvider>
|
||||||
@ -39,6 +46,19 @@ export const decorators = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
|
backgrounds: {
|
||||||
|
default: "dark",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
name: "dark",
|
||||||
|
value: colors.gray[950],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "light",
|
||||||
|
value: colors.gray[50],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
argTypesRegex: "^(on|handler)[A-Z].*",
|
argTypesRegex: "^(on|handler)[A-Z].*",
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import CssBaseline from "@mui/material/CssBaseline";
|
import CssBaseline from "@mui/material/CssBaseline";
|
||||||
import { QueryClient, QueryClientProvider } from "react-query";
|
import { QueryClient, QueryClientProvider } from "react-query";
|
||||||
import { AuthProvider } from "components/AuthProvider/AuthProvider";
|
import { AuthProvider } from "components/AuthProvider/AuthProvider";
|
||||||
import { FC, PropsWithChildren, ReactNode } from "react";
|
import type { FC, PropsWithChildren, ReactNode } from "react";
|
||||||
import { HelmetProvider } from "react-helmet-async";
|
import { HelmetProvider } from "react-helmet-async";
|
||||||
import { AppRouter } from "./AppRouter";
|
import { AppRouter } from "./AppRouter";
|
||||||
import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary";
|
import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary";
|
||||||
|
@ -10,62 +10,50 @@ const meta: Meta<typeof Avatar> = {
|
|||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof Avatar>;
|
type Story = StoryObj<typeof Avatar>;
|
||||||
|
|
||||||
export const Letter: Story = {
|
export const WithLetter: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: "Coder",
|
children: "Coder",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LetterXL = {
|
export const WithLetterXL = {
|
||||||
args: {
|
args: {
|
||||||
children: "Coder",
|
children: "Coder",
|
||||||
size: "xl",
|
size: "xl",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LetterDarken = {
|
export const WithImage = {
|
||||||
args: {
|
|
||||||
children: "Coder",
|
|
||||||
colorScheme: "darken",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Image = {
|
|
||||||
args: {
|
args: {
|
||||||
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ImageXL = {
|
export const WithImageXL = {
|
||||||
args: {
|
args: {
|
||||||
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
||||||
size: "xl",
|
size: "xl",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MuiIcon = {
|
export const WithMuiIcon = {
|
||||||
args: {
|
args: {
|
||||||
|
background: true,
|
||||||
children: <PauseIcon />,
|
children: <PauseIcon />,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MuiIconDarken = {
|
export const WithMuiIconXL = {
|
||||||
args: {
|
|
||||||
children: <PauseIcon />,
|
|
||||||
colorScheme: "darken",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const MuiIconXL = {
|
|
||||||
args: {
|
args: {
|
||||||
|
background: true,
|
||||||
children: <PauseIcon />,
|
children: <PauseIcon />,
|
||||||
size: "xl",
|
size: "xl",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AvatarIconDarken = {
|
export const WithAvatarIcon = {
|
||||||
args: {
|
args: {
|
||||||
|
background: true,
|
||||||
children: <AvatarIcon src="/icon/database.svg" alt="Database" />,
|
children: <AvatarIcon src="/icon/database.svg" alt="Database" />,
|
||||||
colorScheme: "darken",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ import { visuallyHidden } from "@mui/utils";
|
|||||||
|
|
||||||
export type AvatarProps = MuiAvatarProps & {
|
export type AvatarProps = MuiAvatarProps & {
|
||||||
size?: "xs" | "sm" | "md" | "xl";
|
size?: "xs" | "sm" | "md" | "xl";
|
||||||
colorScheme?: "light" | "darken";
|
background?: boolean;
|
||||||
fitImage?: boolean;
|
fitImage?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,14 +33,6 @@ const sizeStyles = {
|
|||||||
},
|
},
|
||||||
} satisfies Record<string, Interpolation<Theme>>;
|
} satisfies Record<string, Interpolation<Theme>>;
|
||||||
|
|
||||||
const colorStyles = {
|
|
||||||
light: {},
|
|
||||||
darken: (theme) => ({
|
|
||||||
background: theme.palette.divider,
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
}),
|
|
||||||
} satisfies Record<string, Interpolation<Theme>>;
|
|
||||||
|
|
||||||
const fitImageStyles = css`
|
const fitImageStyles = css`
|
||||||
& .MuiAvatar-img {
|
& .MuiAvatar-img {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
@ -49,18 +41,24 @@ const fitImageStyles = css`
|
|||||||
|
|
||||||
export const Avatar: FC<AvatarProps> = ({
|
export const Avatar: FC<AvatarProps> = ({
|
||||||
size = "md",
|
size = "md",
|
||||||
colorScheme = "light",
|
|
||||||
fitImage,
|
fitImage,
|
||||||
children,
|
children,
|
||||||
|
background,
|
||||||
...muiProps
|
...muiProps
|
||||||
}) => {
|
}) => {
|
||||||
|
const fromName = !muiProps.src && typeof children === "string";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MuiAvatar
|
<MuiAvatar
|
||||||
{...muiProps}
|
{...muiProps}
|
||||||
css={[
|
css={[
|
||||||
sizeStyles[size],
|
sizeStyles[size],
|
||||||
colorStyles[colorScheme],
|
|
||||||
fitImage && fitImageStyles,
|
fitImage && fitImageStyles,
|
||||||
|
(theme) => ({
|
||||||
|
background:
|
||||||
|
background || fromName ? theme.palette.divider : undefined,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
}),
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{typeof children === "string" ? firstLetter(children) : children}
|
{typeof children === "string" ? firstLetter(children) : children}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { type ReactNode } from "react";
|
import { type ReactNode } from "react";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
import { Avatar } from "components/Avatar/Avatar";
|
||||||
import { type CSSObject, useTheme } from "@emotion/react";
|
import { type CSSObject, useTheme } from "@emotion/react";
|
||||||
import { colors } from "theme/colors";
|
|
||||||
|
|
||||||
type AvatarCardProps = {
|
type AvatarCardProps = {
|
||||||
header: string;
|
header: string;
|
||||||
imgUrl: string;
|
imgUrl: string;
|
||||||
altText: string;
|
altText: string;
|
||||||
|
background?: boolean;
|
||||||
|
|
||||||
subtitle?: ReactNode;
|
subtitle?: ReactNode;
|
||||||
maxWidth?: number | "none";
|
maxWidth?: number | "none";
|
||||||
@ -16,6 +16,7 @@ export function AvatarCard({
|
|||||||
header,
|
header,
|
||||||
imgUrl,
|
imgUrl,
|
||||||
altText,
|
altText,
|
||||||
|
background,
|
||||||
subtitle,
|
subtitle,
|
||||||
maxWidth = "none",
|
maxWidth = "none",
|
||||||
}: AvatarCardProps) {
|
}: AvatarCardProps) {
|
||||||
@ -71,12 +72,7 @@ export function AvatarCard({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Avatar
|
<Avatar background={background} src={imgUrl} alt={altText} size="md">
|
||||||
src={imgUrl}
|
|
||||||
alt={altText}
|
|
||||||
size="md"
|
|
||||||
css={{ backgroundColor: colors.gray[7] }}
|
|
||||||
>
|
|
||||||
{header}
|
{header}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</div>
|
</div>
|
||||||
|
38
site/src/components/Badges/Badges.stories.tsx
Normal file
38
site/src/components/Badges/Badges.stories.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import type { Meta, StoryObj } from "@storybook/react";
|
||||||
|
import {
|
||||||
|
Badges,
|
||||||
|
AlphaBadge,
|
||||||
|
EnabledBadge,
|
||||||
|
EntitledBadge,
|
||||||
|
EnterpriseBadge,
|
||||||
|
} from "./Badges";
|
||||||
|
|
||||||
|
const meta: Meta<typeof Badges> = {
|
||||||
|
title: "components/Badges",
|
||||||
|
component: Badges,
|
||||||
|
args: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Badges>;
|
||||||
|
|
||||||
|
export const Enabled: Story = {
|
||||||
|
args: {
|
||||||
|
children: <EnabledBadge />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const Entitled: Story = {
|
||||||
|
args: {
|
||||||
|
children: <EntitledBadge />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const Enterprise: Story = {
|
||||||
|
args: {
|
||||||
|
children: <EnterpriseBadge />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const Alpha: Story = {
|
||||||
|
args: {
|
||||||
|
children: <AlphaBadge />,
|
||||||
|
},
|
||||||
|
};
|
@ -2,7 +2,7 @@ import type { PropsWithChildren, FC } from "react";
|
|||||||
import Tooltip from "@mui/material/Tooltip";
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import { type Interpolation, type Theme } from "@emotion/react";
|
import { type Interpolation, type Theme } from "@emotion/react";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import { colors } from "theme/colors";
|
import colors from "theme/tailwind";
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
badge: {
|
badge: {
|
||||||
@ -20,16 +20,16 @@ const styles = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
enabledBadge: (theme) => ({
|
enabledBadge: (theme) => ({
|
||||||
border: `1px solid ${theme.palette.success.light}`,
|
border: `1px solid ${theme.experimental.roles.success.outline}`,
|
||||||
backgroundColor: theme.palette.success.dark,
|
backgroundColor: theme.experimental.roles.success.background,
|
||||||
}),
|
}),
|
||||||
errorBadge: (theme) => ({
|
errorBadge: (theme) => ({
|
||||||
border: `1px solid ${theme.palette.error.light}`,
|
border: `1px solid ${theme.experimental.roles.error.outline}`,
|
||||||
backgroundColor: theme.palette.error.dark,
|
backgroundColor: theme.experimental.roles.error.background,
|
||||||
}),
|
}),
|
||||||
warnBadge: (theme) => ({
|
warnBadge: (theme) => ({
|
||||||
border: `1px solid ${theme.palette.warning.light}`,
|
border: `1px solid ${theme.experimental.roles.warning.outline}`,
|
||||||
backgroundColor: theme.palette.warning.dark,
|
backgroundColor: theme.experimental.roles.warning.background,
|
||||||
}),
|
}),
|
||||||
} satisfies Record<string, Interpolation<Theme>>;
|
} satisfies Record<string, Interpolation<Theme>>;
|
||||||
|
|
||||||
@ -111,9 +111,9 @@ export const AlphaBadge: FC = () => {
|
|||||||
css={[
|
css={[
|
||||||
styles.badge,
|
styles.badge,
|
||||||
{
|
{
|
||||||
border: `1px solid ${colors.violet[10]}`,
|
border: `1px solid ${colors.violet[600]}`,
|
||||||
backgroundColor: colors.violet[14],
|
backgroundColor: colors.violet[950],
|
||||||
color: colors.violet[1],
|
color: colors.violet[50],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
@ -46,7 +46,7 @@ export const BuildAvatar: FC<BuildAvatarProps> = ({ build, size }) => {
|
|||||||
}}
|
}}
|
||||||
badgeContent={<div></div>}
|
badgeContent={<div></div>}
|
||||||
>
|
>
|
||||||
<Avatar size={size} colorScheme="darken">
|
<Avatar background size={size}>
|
||||||
<BuildIcon transition={build.transition} />
|
<BuildIcon transition={build.transition} />
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</StyledBadge>
|
</StyledBadge>
|
||||||
|
@ -48,15 +48,13 @@ export const LicenseBannerView: React.FC<LicenseBannerViewProps> = ({
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
background-color: ${type === "error"
|
background-color: ${type === "error" ? colors.red[10] : colors.orange[10]};
|
||||||
? colors.red[12]
|
|
||||||
: theme.palette.warning.main};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (messages.length === 1) {
|
if (messages.length === 1) {
|
||||||
return (
|
return (
|
||||||
<div css={containerStyles}>
|
<div css={containerStyles}>
|
||||||
<Pill text={Language.licenseIssue} type={type} lightBorder />
|
<Pill text={Language.licenseIssue} type={type} />
|
||||||
<div css={styles.leftContent}>
|
<div css={styles.leftContent}>
|
||||||
<span>{messages[0]}</span>
|
<span>{messages[0]}</span>
|
||||||
|
|
||||||
@ -70,11 +68,7 @@ export const LicenseBannerView: React.FC<LicenseBannerViewProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div css={containerStyles}>
|
<div css={containerStyles}>
|
||||||
<Pill
|
<Pill text={Language.licenseIssues(messages.length)} type={type} />
|
||||||
text={Language.licenseIssues(messages.length)}
|
|
||||||
type={type}
|
|
||||||
lightBorder
|
|
||||||
/>
|
|
||||||
<div css={styles.leftContent}>
|
<div css={styles.leftContent}>
|
||||||
<div>
|
<div>
|
||||||
{Language.exceeded}
|
{Language.exceeded}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { Pill } from "components/Pill/Pill";
|
import { Pill } from "components/Pill/Pill";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import { colors } from "theme/colors";
|
import { colors } from "theme/colors";
|
||||||
import { useTheme } from "@mui/system";
|
import { css, useTheme } from "@emotion/react";
|
||||||
import { css } from "@emotion/react";
|
|
||||||
import { readableForegroundColor } from "utils/colors";
|
import { readableForegroundColor } from "utils/colors";
|
||||||
|
|
||||||
export interface ServiceBannerViewProps {
|
export interface ServiceBannerViewProps {
|
||||||
@ -43,7 +42,7 @@ export const ServiceBannerView: React.FC<ServiceBannerViewProps> = ({
|
|||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{isPreview && <Pill text="Preview" type="info" lightBorder />}
|
{isPreview && <Pill text="Preview" type="info" />}
|
||||||
<div
|
<div
|
||||||
css={css`
|
css={css`
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
@ -3,20 +3,12 @@ import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined";
|
|||||||
import { css, useTheme } from "@emotion/react";
|
import { css, useTheme } from "@emotion/react";
|
||||||
import type { PropsWithChildren, FC } from "react";
|
import type { PropsWithChildren, FC } from "react";
|
||||||
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
||||||
import { DisabledBadge, EnabledBadge } from "./Badges";
|
import { DisabledBadge, EnabledBadge } from "../Badges/Badges";
|
||||||
|
|
||||||
export const OptionName: FC<PropsWithChildren> = (props) => {
|
export const OptionName: FC<PropsWithChildren> = (props) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
|
|
||||||
return (
|
return <span css={{ display: "block" }}>{children}</span>;
|
||||||
<span
|
|
||||||
css={{
|
|
||||||
display: "block",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const OptionDescription: FC<PropsWithChildren> = (props) => {
|
export const OptionDescription: FC<PropsWithChildren> = (props) => {
|
||||||
|
@ -12,8 +12,8 @@ import { Stack } from "components/Stack/Stack";
|
|||||||
import type { ElementType, FC, PropsWithChildren, ReactNode } from "react";
|
import type { ElementType, FC, PropsWithChildren, ReactNode } from "react";
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
import { useDashboard } from "components/Dashboard/DashboardProvider";
|
import { useDashboard } from "components/Dashboard/DashboardProvider";
|
||||||
import { useTheme } from "@mui/system";
|
|
||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
|
import { useTheme } from "@emotion/react";
|
||||||
|
|
||||||
const SidebarNavItem: FC<
|
const SidebarNavItem: FC<
|
||||||
PropsWithChildren<{ href: string; icon: ReactNode }>
|
PropsWithChildren<{ href: string; icon: ReactNode }>
|
||||||
@ -74,11 +74,7 @@ export const Sidebar: React.FC = () => {
|
|||||||
const dashboard = useDashboard();
|
const dashboard = useDashboard();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav css={{ width: 245 }}>
|
||||||
css={{
|
|
||||||
width: 245,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SidebarNavItem
|
<SidebarNavItem
|
||||||
href="general"
|
href="general"
|
||||||
icon={<SidebarNavItemIcon icon={LaunchOutlined} />}
|
icon={<SidebarNavItemIcon icon={LaunchOutlined} />}
|
||||||
|
@ -97,14 +97,14 @@ const styles = {
|
|||||||
}),
|
}),
|
||||||
successButton: (theme) => ({
|
successButton: (theme) => ({
|
||||||
"&.MuiButton-contained": {
|
"&.MuiButton-contained": {
|
||||||
backgroundColor: theme.palette.success.main,
|
backgroundColor: theme.palette.success.dark,
|
||||||
|
|
||||||
"&:not(.MuiLoadingButton-loading)": {
|
"&:not(.MuiLoadingButton-loading)": {
|
||||||
color: theme.palette.primary.contrastText,
|
color: theme.palette.primary.contrastText,
|
||||||
},
|
},
|
||||||
|
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
backgroundColor: theme.palette.success.dark,
|
backgroundColor: theme.palette.success.main,
|
||||||
|
|
||||||
"@media (hover: none)": {
|
"@media (hover: none)": {
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
type PropsWithChildren,
|
type PropsWithChildren,
|
||||||
useContext,
|
useContext,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { AlphaBadge } from "components/DeploySettingsLayout/Badges";
|
import { AlphaBadge } from "components/Badges/Badges";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import {
|
import {
|
||||||
FormFooter as BaseFormFooter,
|
FormFooter as BaseFormFooter,
|
||||||
|
@ -37,7 +37,9 @@ export const GroupAvatar: FC<GroupAvatarProps> = ({ name, avatarURL }) => {
|
|||||||
}}
|
}}
|
||||||
badgeContent={<Group />}
|
badgeContent={<Group />}
|
||||||
>
|
>
|
||||||
<Avatar src={avatarURL}>{name}</Avatar>
|
<Avatar src={avatarURL} background>
|
||||||
|
{name}
|
||||||
|
</Avatar>
|
||||||
</StyledBadge>
|
</StyledBadge>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,14 @@ export default meta;
|
|||||||
type Story = StoryObj<typeof InfoTooltip>;
|
type Story = StoryObj<typeof InfoTooltip>;
|
||||||
|
|
||||||
export const Example: Story = {};
|
export const Example: Story = {};
|
||||||
|
|
||||||
|
export const Notice: Story = {
|
||||||
|
args: {
|
||||||
|
type: "notice",
|
||||||
|
message: "Unfortunately, there's a radio connected to my brain",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const Warning: Story = {
|
export const Warning: Story = {
|
||||||
args: {
|
args: {
|
||||||
type: "warning",
|
type: "warning",
|
||||||
|
@ -6,10 +6,11 @@ import {
|
|||||||
} from "components/HelpTooltip/HelpTooltip";
|
} from "components/HelpTooltip/HelpTooltip";
|
||||||
import InfoIcon from "@mui/icons-material/InfoOutlined";
|
import InfoIcon from "@mui/icons-material/InfoOutlined";
|
||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
import { colors } from "theme/colors";
|
import { useTheme } from "@emotion/react";
|
||||||
|
|
||||||
interface InfoTooltipProps {
|
interface InfoTooltipProps {
|
||||||
type?: "warning" | "info";
|
// TODO: use a `ThemeRole` type or something
|
||||||
|
type?: "warning" | "notice" | "info";
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
message: ReactNode;
|
message: ReactNode;
|
||||||
}
|
}
|
||||||
@ -17,12 +18,15 @@ interface InfoTooltipProps {
|
|||||||
export const InfoTooltip: FC<InfoTooltipProps> = (props) => {
|
export const InfoTooltip: FC<InfoTooltipProps> = (props) => {
|
||||||
const { title, message, type = "info" } = props;
|
const { title, message, type = "info" } = props;
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
const iconColor = theme.experimental.roles[type].outline;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HelpTooltip
|
<HelpTooltip
|
||||||
size="small"
|
size="small"
|
||||||
icon={InfoIcon}
|
icon={InfoIcon}
|
||||||
iconClassName={css`
|
iconClassName={css`
|
||||||
color: ${type === "info" ? colors.blue[5] : colors.yellow[5]};
|
color: ${iconColor};
|
||||||
`}
|
`}
|
||||||
buttonClassName={css`
|
buttonClassName={css`
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -11,7 +11,7 @@ import { type FC, memo } from "react";
|
|||||||
import ReactMarkdown, { type Options } from "react-markdown";
|
import ReactMarkdown, { type Options } from "react-markdown";
|
||||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
import gfm from "remark-gfm";
|
import gfm from "remark-gfm";
|
||||||
import { colors } from "theme/colors";
|
import colors from "theme/tailwind";
|
||||||
import { darcula } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
import { darcula } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||||
|
|
||||||
interface MarkdownProps {
|
interface MarkdownProps {
|
||||||
@ -227,7 +227,7 @@ const markdownStyles: Interpolation<Theme> = (theme: Theme) => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
"& .key, & .property, & .inserted, .keyword": {
|
"& .key, & .property, & .inserted, .keyword": {
|
||||||
color: colors.turquoise[7],
|
color: colors.teal[300],
|
||||||
},
|
},
|
||||||
|
|
||||||
"& .deleted": {
|
"& .deleted": {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Chip from "@mui/material/Chip";
|
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import { type FC, type ReactNode } from "react";
|
import { type FC, type ReactNode } from "react";
|
||||||
import { type Interpolation, type Theme } from "@emotion/react";
|
import { type Interpolation, type Theme } from "@emotion/react";
|
||||||
|
import { EnterpriseBadge } from "components/Badges/Badges";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
|
||||||
export interface PaywallProps {
|
export interface PaywallProps {
|
||||||
@ -21,12 +21,7 @@ export const Paywall: FC<React.PropsWithChildren<PaywallProps>> = (props) => {
|
|||||||
<Typography variant="h5" css={styles.title}>
|
<Typography variant="h5" css={styles.title}>
|
||||||
{message}
|
{message}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Chip
|
<EnterpriseBadge />
|
||||||
css={styles.enterpriseChip}
|
|
||||||
label="Enterprise"
|
|
||||||
size="small"
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{description && (
|
{description && (
|
||||||
|
@ -9,38 +9,16 @@ const meta: Meta<typeof Pill> = {
|
|||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof Pill>;
|
type Story = StoryObj<typeof Pill>;
|
||||||
|
|
||||||
export const Primary: Story = {
|
export const Default: Story = {
|
||||||
args: {
|
args: {
|
||||||
text: "Primary",
|
text: "Default",
|
||||||
type: "primary",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Secondary: Story = {
|
export const Danger: Story = {
|
||||||
args: {
|
args: {
|
||||||
text: "Secondary",
|
text: "Danger",
|
||||||
type: "secondary",
|
type: "danger",
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Success: Story = {
|
|
||||||
args: {
|
|
||||||
text: "Success",
|
|
||||||
type: "success",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Info: Story = {
|
|
||||||
args: {
|
|
||||||
text: "Information",
|
|
||||||
type: "info",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Warning: Story = {
|
|
||||||
args: {
|
|
||||||
text: "Warning",
|
|
||||||
type: "warning",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,16 +29,37 @@ export const Error: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Default: Story = {
|
export const Warning: Story = {
|
||||||
args: {
|
|
||||||
text: "Default",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const WarningLight: Story = {
|
|
||||||
args: {
|
args: {
|
||||||
text: "Warning",
|
text: "Warning",
|
||||||
type: "warning",
|
type: "warning",
|
||||||
lightBorder: true,
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Notice: Story = {
|
||||||
|
args: {
|
||||||
|
text: "Notice",
|
||||||
|
type: "notice",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Info: Story = {
|
||||||
|
args: {
|
||||||
|
text: "Information",
|
||||||
|
type: "info",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Success: Story = {
|
||||||
|
args: {
|
||||||
|
text: "Success",
|
||||||
|
type: "success",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Active: Story = {
|
||||||
|
args: {
|
||||||
|
text: "Active",
|
||||||
|
type: "active",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,65 +1,43 @@
|
|||||||
import { type FC, type ReactNode, useMemo, forwardRef } from "react";
|
import { type FC, type ReactNode, useMemo, forwardRef } from "react";
|
||||||
import { css, type Interpolation, type Theme } from "@emotion/react";
|
import { css, type Interpolation, type Theme } from "@emotion/react";
|
||||||
import { colors } from "theme/colors";
|
import { colors } from "theme/colors";
|
||||||
|
import type { ThemeRole } from "theme/experimental";
|
||||||
|
|
||||||
export type PillType =
|
export type PillType = ThemeRole | keyof typeof themeOverrides;
|
||||||
| "primary"
|
|
||||||
| "secondary"
|
|
||||||
| "error"
|
|
||||||
| "warning"
|
|
||||||
| "info"
|
|
||||||
| "success"
|
|
||||||
| "neutral";
|
|
||||||
|
|
||||||
export interface PillProps {
|
export interface PillProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: ReactNode;
|
icon?: ReactNode;
|
||||||
text: ReactNode;
|
text: ReactNode;
|
||||||
type?: PillType;
|
type?: PillType;
|
||||||
lightBorder?: boolean;
|
|
||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeOverrides = {
|
const themeOverrides = {
|
||||||
primary: (lightBorder) => ({
|
neutral: {
|
||||||
backgroundColor: colors.blue[13],
|
|
||||||
borderColor: lightBorder ? colors.blue[5] : colors.blue[7],
|
|
||||||
}),
|
|
||||||
secondary: (lightBorder) => ({
|
|
||||||
backgroundColor: colors.indigo[13],
|
|
||||||
borderColor: lightBorder ? colors.indigo[6] : colors.indigo[8],
|
|
||||||
}),
|
|
||||||
neutral: (lightBorder) => ({
|
|
||||||
backgroundColor: colors.gray[13],
|
backgroundColor: colors.gray[13],
|
||||||
borderColor: lightBorder ? colors.gray[6] : colors.gray[8],
|
borderColor: colors.gray[6],
|
||||||
}),
|
},
|
||||||
} satisfies Record<string, (lightBorder?: boolean) => Interpolation<Theme>>;
|
} satisfies Record<string, Interpolation<Theme>>;
|
||||||
|
|
||||||
const themeStyles =
|
const themeStyles = (type: ThemeRole) => (theme: Theme) => {
|
||||||
(type: PillType, lightBorder?: boolean) => (theme: Theme) => {
|
const palette = theme.experimental.roles[type];
|
||||||
const palette = theme.palette[type];
|
return {
|
||||||
return {
|
backgroundColor: palette.background,
|
||||||
backgroundColor: palette.dark,
|
borderColor: palette.outline,
|
||||||
borderColor: lightBorder ? palette.light : palette.main,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
|
export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
const {
|
const { icon, text = null, type = "neutral", ...attrs } = props;
|
||||||
lightBorder,
|
|
||||||
icon,
|
|
||||||
text = null,
|
|
||||||
type = "neutral",
|
|
||||||
...attrs
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const typeStyles = useMemo(() => {
|
const typeStyles = useMemo(() => {
|
||||||
if (type in themeOverrides) {
|
if (type in themeOverrides) {
|
||||||
return themeOverrides[type as keyof typeof themeOverrides](lightBorder);
|
return themeOverrides[type as keyof typeof themeOverrides];
|
||||||
}
|
}
|
||||||
return themeStyles(type, lightBorder);
|
return themeStyles(type as ThemeRole);
|
||||||
}, [type, lightBorder]);
|
}, [type]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -39,7 +39,7 @@ export const ResourceAvatar: FC<ResourceAvatarProps> = ({ resource }) => {
|
|||||||
: getIconPathResource(resource.type);
|
: getIconPathResource(resource.type);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Avatar colorScheme="darken">
|
<Avatar background>
|
||||||
<AvatarIcon src={avatarSrc} alt={resource.name} />
|
<AvatarIcon src={avatarSrc} alt={resource.name} />
|
||||||
</Avatar>
|
</Avatar>
|
||||||
);
|
);
|
||||||
|
@ -9,7 +9,6 @@ import { type FC } from "react";
|
|||||||
import { TemplateVersionParameter } from "api/typesGenerated";
|
import { TemplateVersionParameter } from "api/typesGenerated";
|
||||||
import { MemoizedMarkdown } from "components/Markdown/Markdown";
|
import { MemoizedMarkdown } from "components/Markdown/Markdown";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import { colors } from "theme/colors";
|
|
||||||
import { MultiTextField } from "./MultiTextField";
|
import { MultiTextField } from "./MultiTextField";
|
||||||
|
|
||||||
const isBoolean = (parameter: TemplateVersionParameter) => {
|
const isBoolean = (parameter: TemplateVersionParameter) => {
|
||||||
@ -43,11 +42,6 @@ const styles = {
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
labelImmutable: {
|
|
||||||
marginTop: 4,
|
|
||||||
marginBottom: 4,
|
|
||||||
color: colors.yellow[7],
|
|
||||||
},
|
|
||||||
textField: {
|
textField: {
|
||||||
".small & .MuiInputBase-root": {
|
".small & .MuiInputBase-root": {
|
||||||
height: 36,
|
height: 36,
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { useTheme } from "@mui/styles";
|
|
||||||
import { useMonaco } from "@monaco-editor/react";
|
import { useMonaco } from "@monaco-editor/react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { hslToHex } from "utils/colors";
|
|
||||||
import { editor } from "monaco-editor";
|
import { editor } from "monaco-editor";
|
||||||
import { Theme } from "@mui/material/styles";
|
import { type Theme, useTheme } from "@emotion/react";
|
||||||
|
|
||||||
// Theme based on https://github.com/brijeshb42/monaco-themes/blob/master/themes/Dracula.json
|
// Theme based on https://github.com/brijeshb42/monaco-themes/blob/master/themes/Dracula.json
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- The theme is not typed
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- The theme is not typed
|
||||||
@ -208,12 +206,11 @@ export const coderTheme = (theme: Theme): editor.IStandaloneThemeData => ({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
colors: {
|
colors: {
|
||||||
"editor.foreground": hslToHex(theme.palette.text.primary),
|
"editor.foreground": theme.palette.text.primary,
|
||||||
"editor.background": hslToHex(theme.palette.background.paper),
|
"editor.background": theme.palette.background.paper,
|
||||||
"editor.selectionBackground": hslToHex(theme.palette.action.hover),
|
"editor.selectionBackground": theme.palette.action.hover,
|
||||||
"editor.lineHighlightBackground": hslToHex(
|
"editor.lineHighlightBackground": theme.palette.background.paperLight,
|
||||||
theme.palette.background.paperLight,
|
|
||||||
),
|
|
||||||
"editorCursor.foreground": "#f8f8f0",
|
"editorCursor.foreground": "#f8f8f0",
|
||||||
"editorWhitespace.foreground": "#3B3A32",
|
"editorWhitespace.foreground": "#3B3A32",
|
||||||
"editorIndentGuide.activeBackground": "#9D550FB0",
|
"editorIndentGuide.activeBackground": "#9D550FB0",
|
||||||
@ -224,7 +221,7 @@ export const coderTheme = (theme: Theme): editor.IStandaloneThemeData => ({
|
|||||||
export const useCoderTheme = (): { isLoading: boolean; name: string } => {
|
export const useCoderTheme = (): { isLoading: boolean; name: string } => {
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const monaco = useMonaco();
|
const monaco = useMonaco();
|
||||||
const theme = useTheme<Theme>();
|
const theme = useTheme();
|
||||||
const name = "coder";
|
const name = "coder";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -3,7 +3,7 @@ import { NavLink, NavLinkProps } from "react-router-dom";
|
|||||||
import { combineClasses } from "utils/combineClasses";
|
import { combineClasses } from "utils/combineClasses";
|
||||||
import { Margins } from "components/Margins/Margins";
|
import { Margins } from "components/Margins/Margins";
|
||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
import { useTheme } from "@mui/material/styles";
|
import { useTheme } from "@emotion/react";
|
||||||
|
|
||||||
export const Tabs = ({ children }: { children: ReactNode }) => {
|
export const Tabs = ({ children }: { children: ReactNode }) => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Avatar, AvatarProps } from "components/Avatar/Avatar";
|
import { Avatar, type AvatarProps } from "components/Avatar/Avatar";
|
||||||
import { FC } from "react";
|
import { type FC } from "react";
|
||||||
|
|
||||||
export type UserAvatarProps = {
|
export type UserAvatarProps = {
|
||||||
username: string;
|
username: string;
|
||||||
@ -12,7 +12,7 @@ export const UserAvatar: FC<UserAvatarProps> = ({
|
|||||||
...avatarProps
|
...avatarProps
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Avatar title={username} src={avatarURL} {...avatarProps}>
|
<Avatar background title={username} src={avatarURL} {...avatarProps}>
|
||||||
{username}
|
{username}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
import { type FC } from "react";
|
|
||||||
import InfoIcon from "@mui/icons-material/InfoOutlined";
|
import InfoIcon from "@mui/icons-material/InfoOutlined";
|
||||||
import { useQuery } from "react-query";
|
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Skeleton from "@mui/material/Skeleton";
|
import Skeleton from "@mui/material/Skeleton";
|
||||||
import Link from "@mui/material/Link";
|
import Link from "@mui/material/Link";
|
||||||
|
import { type FC } from "react";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
|
import { useTheme } from "@emotion/react";
|
||||||
import { templateVersion } from "api/queries/templates";
|
import { templateVersion } from "api/queries/templates";
|
||||||
import {
|
import {
|
||||||
HelpTooltip,
|
HelpTooltip,
|
||||||
@ -14,7 +15,6 @@ import {
|
|||||||
HelpTooltipText,
|
HelpTooltipText,
|
||||||
HelpTooltipTitle,
|
HelpTooltipTitle,
|
||||||
} from "components/HelpTooltip/HelpTooltip";
|
} from "components/HelpTooltip/HelpTooltip";
|
||||||
import { colors } from "theme/colors";
|
|
||||||
|
|
||||||
export const Language = {
|
export const Language = {
|
||||||
outdatedLabel: "Outdated",
|
outdatedLabel: "Outdated",
|
||||||
@ -37,13 +37,14 @@ export const WorkspaceOutdatedTooltip: FC<TooltipProps> = ({
|
|||||||
templateName,
|
templateName,
|
||||||
}) => {
|
}) => {
|
||||||
const { data: activeVersion } = useQuery(templateVersion(latestVersionId));
|
const { data: activeVersion } = useQuery(templateVersion(latestVersionId));
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HelpTooltip
|
<HelpTooltip
|
||||||
size="small"
|
size="small"
|
||||||
icon={InfoIcon}
|
icon={InfoIcon}
|
||||||
iconClassName={css`
|
iconClassName={css`
|
||||||
color: ${colors.yellow[5]};
|
color: ${theme.experimental.roles.notice.outline};
|
||||||
`}
|
`}
|
||||||
buttonClassName={css`
|
buttonClassName={css`
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -73,7 +73,14 @@ export const WorkspaceStatusText: FC<
|
|||||||
role="status"
|
role="status"
|
||||||
data-testid="build-status"
|
data-testid="build-status"
|
||||||
className={className}
|
className={className}
|
||||||
css={[styles.root, styles[`type-${type}`]]}
|
css={[
|
||||||
|
styles.root,
|
||||||
|
(theme) => ({
|
||||||
|
color: type
|
||||||
|
? theme.experimental.roles[type].fill
|
||||||
|
: theme.experimental.l1.text,
|
||||||
|
}),
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { type Interpolation, type Theme } from "@emotion/react";
|
import { type Interpolation, type Theme } from "@emotion/react";
|
||||||
import { type FC } from "react";
|
import { type FC } from "react";
|
||||||
import type { AuditLog } from "api/typesGenerated";
|
import type { AuditLog } from "api/typesGenerated";
|
||||||
import { colors } from "theme/colors";
|
import colors from "theme/tailwind";
|
||||||
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
||||||
|
|
||||||
const getDiffValue = (value: unknown): string => {
|
const getDiffValue = (value: unknown): string => {
|
||||||
@ -79,10 +79,10 @@ const styles = {
|
|||||||
overflowWrap: "anywhere",
|
overflowWrap: "anywhere",
|
||||||
},
|
},
|
||||||
|
|
||||||
diffOld: (theme) => ({
|
diffOld: {
|
||||||
backgroundColor: theme.palette.error.dark,
|
backgroundColor: colors.red[950],
|
||||||
color: theme.palette.error.contrastText,
|
color: colors.red[50],
|
||||||
}),
|
},
|
||||||
|
|
||||||
diffRow: {
|
diffRow: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -103,10 +103,10 @@ const styles = {
|
|||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
diffNew: (theme) => ({
|
diffNew: {
|
||||||
backgroundColor: theme.palette.success.dark,
|
backgroundColor: colors.green[950],
|
||||||
color: theme.palette.success.contrastText,
|
color: colors.green[50],
|
||||||
}),
|
},
|
||||||
|
|
||||||
diffValue: {
|
diffValue: {
|
||||||
padding: 1,
|
padding: 1,
|
||||||
@ -114,10 +114,10 @@ const styles = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
diffValueOld: {
|
diffValueOld: {
|
||||||
backgroundColor: colors.red[12],
|
backgroundColor: colors.red[800],
|
||||||
},
|
},
|
||||||
|
|
||||||
diffValueNew: {
|
diffValueNew: {
|
||||||
backgroundColor: colors.green[12],
|
backgroundColor: colors.green[800],
|
||||||
},
|
},
|
||||||
} satisfies Record<string, Interpolation<Theme>>;
|
} satisfies Record<string, Interpolation<Theme>>;
|
||||||
|
@ -10,7 +10,7 @@ export const AuditPaywall: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<Paywall
|
<Paywall
|
||||||
message="Audit logs"
|
message="Audit logs"
|
||||||
description="Audit Logs allows Auditors to monitor user operations in their deployment. To use this feature, you have to upgrade your account."
|
description="Audit Logs allows Auditors to monitor user operations in their deployment. To use this feature, you need an Enterprise license."
|
||||||
cta={
|
cta={
|
||||||
<Stack direction="row" alignItems="center">
|
<Stack direction="row" alignItems="center">
|
||||||
<Link href={docs("/admin/upgrade")} target="_blank" rel="noreferrer">
|
<Link href={docs("/admin/upgrade")} target="_blank" rel="noreferrer">
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
|
import InputAdornment from "@mui/material/InputAdornment";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||||
|
import Switch from "@mui/material/Switch";
|
||||||
|
import TextField from "@mui/material/TextField";
|
||||||
|
import Link from "@mui/material/Link";
|
||||||
|
import { useTheme } from "@emotion/react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { BlockPicker } from "react-color";
|
||||||
|
import { useFormik } from "formik";
|
||||||
|
import type { UpdateAppearanceConfig } from "api/typesGenerated";
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import {
|
import {
|
||||||
Badges,
|
Badges,
|
||||||
DisabledBadge,
|
DisabledBadge,
|
||||||
EnterpriseBadge,
|
EnterpriseBadge,
|
||||||
EntitledBadge,
|
EntitledBadge,
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
} from "components/Badges/Badges";
|
||||||
import InputAdornment from "@mui/material/InputAdornment";
|
|
||||||
import { Fieldset } from "components/DeploySettingsLayout/Fieldset";
|
import { Fieldset } from "components/DeploySettingsLayout/Fieldset";
|
||||||
import { getFormHelpers } from "utils/formUtils";
|
|
||||||
import Button from "@mui/material/Button";
|
|
||||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
|
||||||
import { BlockPicker } from "react-color";
|
|
||||||
import Switch from "@mui/material/Switch";
|
|
||||||
import TextField from "@mui/material/TextField";
|
|
||||||
import type { UpdateAppearanceConfig } from "api/typesGenerated";
|
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import { useFormik } from "formik";
|
import { getFormHelpers } from "utils/formUtils";
|
||||||
import Link from "@mui/material/Link";
|
|
||||||
import { colors } from "theme/colors";
|
import { colors } from "theme/colors";
|
||||||
import { hslToHex } from "utils/colors";
|
|
||||||
import { useTheme } from "@emotion/react";
|
|
||||||
|
|
||||||
export type AppearanceSettingsPageViewProps = {
|
export type AppearanceSettingsPageViewProps = {
|
||||||
appearance: UpdateAppearanceConfig;
|
appearance: UpdateAppearanceConfig;
|
||||||
@ -31,7 +30,7 @@ export type AppearanceSettingsPageViewProps = {
|
|||||||
) => void;
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fallbackBgColor = hslToHex(colors.blue[7]);
|
const fallbackBgColor = colors.blue[7];
|
||||||
|
|
||||||
export const AppearanceSettingsPageView = ({
|
export const AppearanceSettingsPageView = ({
|
||||||
appearance,
|
appearance,
|
||||||
|
@ -7,7 +7,7 @@ import TableHead from "@mui/material/TableHead";
|
|||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import type { DeploymentValues, ExternalAuthConfig } from "api/typesGenerated";
|
import type { DeploymentValues, ExternalAuthConfig } from "api/typesGenerated";
|
||||||
import { Alert } from "components/Alert/Alert";
|
import { Alert } from "components/Alert/Alert";
|
||||||
import { EnterpriseBadge } from "components/DeploySettingsLayout/Badges";
|
import { EnterpriseBadge } from "components/Badges/Badges";
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import { docs } from "utils/docs";
|
import { docs } from "utils/docs";
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { type Interpolation, type Theme } from "@emotion/react";
|
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import { useTheme } from "@mui/styles";
|
|
||||||
import Skeleton from "@mui/material/Skeleton";
|
import Skeleton from "@mui/material/Skeleton";
|
||||||
import AddIcon from "@mui/icons-material/AddOutlined";
|
import AddIcon from "@mui/icons-material/AddOutlined";
|
||||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { ClibaseOption } from "api/typesGenerated";
|
import type { ClibaseOption } from "api/typesGenerated";
|
||||||
import {
|
import { Badges, EnabledBadge, DisabledBadge } from "components/Badges/Badges";
|
||||||
Badges,
|
|
||||||
EnabledBadge,
|
|
||||||
DisabledBadge,
|
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { ClibaseOption } from "api/typesGenerated";
|
import type { ClibaseOption } from "api/typesGenerated";
|
||||||
import {
|
import {
|
||||||
Badges,
|
Badges,
|
||||||
DisabledBadge,
|
DisabledBadge,
|
||||||
EnabledBadge,
|
EnabledBadge,
|
||||||
EnterpriseBadge,
|
EnterpriseBadge,
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
} from "components/Badges/Badges";
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { ClibaseOption } from "api/typesGenerated";
|
import type { ClibaseOption } from "api/typesGenerated";
|
||||||
import {
|
import {
|
||||||
Badges,
|
Badges,
|
||||||
DisabledBadge,
|
DisabledBadge,
|
||||||
EnabledBadge,
|
EnabledBadge,
|
||||||
EnterpriseBadge,
|
EnterpriseBadge,
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
} from "components/Badges/Badges";
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { ClibaseOption } from "api/typesGenerated";
|
import type { ClibaseOption } from "api/typesGenerated";
|
||||||
import {
|
import { Badges, DisabledBadge, EnabledBadge } from "components/Badges/Badges";
|
||||||
Badges,
|
|
||||||
DisabledBadge,
|
|
||||||
EnabledBadge,
|
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
|
||||||
import { Header } from "components/DeploySettingsLayout/Header";
|
import { Header } from "components/DeploySettingsLayout/Header";
|
||||||
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
import OptionsTable from "components/DeploySettingsLayout/OptionsTable";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
@ -86,11 +86,7 @@ const ExternalAuthPageView: FC<ExternalAuthPageViewProps> = ({
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
<Avatar
|
<Avatar size="sm" src={install.account.avatar_url}>
|
||||||
size="sm"
|
|
||||||
src={install.account.avatar_url}
|
|
||||||
colorScheme="darken"
|
|
||||||
>
|
|
||||||
{install.account.login}
|
{install.account.login}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import LinearProgress from "@mui/material/LinearProgress";
|
import LinearProgress from "@mui/material/LinearProgress";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import { styled, useTheme } from "@mui/material/styles";
|
import { styled } from "@mui/material/styles";
|
||||||
import { BoxProps } from "@mui/system";
|
import { BoxProps } from "@mui/system";
|
||||||
import { useQuery } from "react-query";
|
import { useQuery } from "react-query";
|
||||||
import {
|
import {
|
||||||
@ -20,7 +20,7 @@ import { colors } from "theme/colors";
|
|||||||
import { Helmet } from "react-helmet-async";
|
import { Helmet } from "react-helmet-async";
|
||||||
import { getTemplatePageTitle } from "../utils";
|
import { getTemplatePageTitle } from "../utils";
|
||||||
import { Loader } from "components/Loader/Loader";
|
import { Loader } from "components/Loader/Loader";
|
||||||
import {
|
import type {
|
||||||
Entitlements,
|
Entitlements,
|
||||||
Template,
|
Template,
|
||||||
TemplateAppUsage,
|
TemplateAppUsage,
|
||||||
@ -30,7 +30,8 @@ import {
|
|||||||
UserActivityInsightsResponse,
|
UserActivityInsightsResponse,
|
||||||
UserLatencyInsightsResponse,
|
UserLatencyInsightsResponse,
|
||||||
} from "api/typesGenerated";
|
} from "api/typesGenerated";
|
||||||
import { ComponentProps, ReactNode } from "react";
|
import { useTheme } from "@emotion/react";
|
||||||
|
import { type ComponentProps, type ReactNode } from "react";
|
||||||
import { subDays, addWeeks, format } from "date-fns";
|
import { subDays, addWeeks, format } from "date-fns";
|
||||||
import "react-date-range/dist/styles.css";
|
import "react-date-range/dist/styles.css";
|
||||||
import "react-date-range/dist/theme/default.css";
|
import "react-date-range/dist/theme/default.css";
|
||||||
|
@ -80,13 +80,13 @@ export const VersionRow: React.FC<VersionRowProps> = ({
|
|||||||
{isLatest && <Pill text="Newest" type="info" />}
|
{isLatest && <Pill text="Newest" type="info" />}
|
||||||
|
|
||||||
{jobStatus === "pending" && (
|
{jobStatus === "pending" && (
|
||||||
<Pill text={<>Pending…</>} type="warning" lightBorder />
|
<Pill text={<>Pending…</>} type="warning" />
|
||||||
)}
|
)}
|
||||||
{jobStatus === "running" && (
|
{jobStatus === "running" && (
|
||||||
<Pill text={<>Building…</>} type="warning" lightBorder />
|
<Pill text={<>Building…</>} type="warning" />
|
||||||
)}
|
)}
|
||||||
{(jobStatus === "canceling" || jobStatus === "canceled") && (
|
{(jobStatus === "canceling" || jobStatus === "canceled") && (
|
||||||
<Pill text="Canceled" type="neutral" lightBorder />
|
<Pill text="Canceled" type="neutral" />
|
||||||
)}
|
)}
|
||||||
{jobStatus === "failed" && <Pill text="Failed" type="error" />}
|
{jobStatus === "failed" && <Pill text="Failed" type="error" />}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { useTheme } from "@mui/styles";
|
import { useTheme } from "@emotion/react";
|
||||||
import Editor, { loader } from "@monaco-editor/react";
|
import Editor, { loader } from "@monaco-editor/react";
|
||||||
import * as monaco from "monaco-editor";
|
import * as monaco from "monaco-editor";
|
||||||
import { FC, useLayoutEffect, useMemo, useState } from "react";
|
import { FC, useLayoutEffect, useMemo, useState } from "react";
|
||||||
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
||||||
import { hslToHex } from "utils/colors";
|
|
||||||
import type { editor } from "monaco-editor";
|
import type { editor } from "monaco-editor";
|
||||||
|
|
||||||
loader.config({ monaco });
|
loader.config({ monaco });
|
||||||
@ -124,8 +123,8 @@ export const MonacoEditor: FC<{
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
colors: {
|
colors: {
|
||||||
"editor.foreground": hslToHex(theme.palette.text.primary),
|
"editor.foreground": theme.palette.text.primary,
|
||||||
"editor.background": hslToHex(theme.palette.background.default),
|
"editor.background": theme.palette.background.default,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
editor.updateOptions({
|
editor.updateOptions({
|
||||||
|
@ -39,9 +39,9 @@ export const getStatus = (
|
|||||||
};
|
};
|
||||||
case "pending":
|
case "pending":
|
||||||
return {
|
return {
|
||||||
|
type: "info",
|
||||||
text: "Pending",
|
text: "Pending",
|
||||||
icon: <LoadingIcon />,
|
icon: <LoadingIcon />,
|
||||||
type: "info",
|
|
||||||
};
|
};
|
||||||
case "canceling":
|
case "canceling":
|
||||||
return {
|
return {
|
||||||
|
@ -51,6 +51,7 @@ export function AccountUserGroups({
|
|||||||
{groups.map((group) => (
|
{groups.map((group) => (
|
||||||
<Grid item key={group.id} xs={1}>
|
<Grid item key={group.id} xs={1}>
|
||||||
<AvatarCard
|
<AvatarCard
|
||||||
|
background
|
||||||
imgUrl={group.avatar_url}
|
imgUrl={group.avatar_url}
|
||||||
altText={group.display_name || group.name}
|
altText={group.display_name || group.name}
|
||||||
header={group.display_name || group.name}
|
header={group.display_name || group.name}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { Region, WorkspaceProxy } from "api/typesGenerated";
|
import type { Region, WorkspaceProxy } from "api/typesGenerated";
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
import { Avatar } from "components/Avatar/Avatar";
|
||||||
import TableCell from "@mui/material/TableCell";
|
import TableCell from "@mui/material/TableCell";
|
||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
import {
|
import {
|
||||||
HealthyBadge,
|
HealthyBadge,
|
||||||
NotHealthyBadge,
|
NotHealthyBadge,
|
||||||
NotReachableBadge,
|
NotReachableBadge,
|
||||||
NotRegisteredBadge,
|
NotRegisteredBadge,
|
||||||
} from "components/DeploySettingsLayout/Badges";
|
} from "components/Badges/Badges";
|
||||||
import { ProxyLatencyReport } from "contexts/useProxyLatency";
|
import type { ProxyLatencyReport } from "contexts/useProxyLatency";
|
||||||
import { getLatencyColor } from "utils/latency";
|
import { getLatencyColor } from "utils/latency";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
TableLoaderSkeleton,
|
TableLoaderSkeleton,
|
||||||
TableRowSkeleton,
|
TableRowSkeleton,
|
||||||
} from "components/TableLoader/TableLoader";
|
} from "components/TableLoader/TableLoader";
|
||||||
import { EnterpriseBadge } from "components/DeploySettingsLayout/Badges";
|
import { EnterpriseBadge } from "components/Badges/Badges";
|
||||||
import HideSourceOutlined from "@mui/icons-material/HideSourceOutlined";
|
import HideSourceOutlined from "@mui/icons-material/HideSourceOutlined";
|
||||||
import KeyOutlined from "@mui/icons-material/KeyOutlined";
|
import KeyOutlined from "@mui/icons-material/KeyOutlined";
|
||||||
import GitHub from "@mui/icons-material/GitHub";
|
import GitHub from "@mui/icons-material/GitHub";
|
||||||
|
@ -8,12 +8,7 @@ import {
|
|||||||
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
||||||
import type { Workspace } from "api/typesGenerated";
|
import type { Workspace } from "api/typesGenerated";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import {
|
import { type FC, type PropsWithChildren, type ReactNode } from "react";
|
||||||
type FC,
|
|
||||||
type ComponentType,
|
|
||||||
type PropsWithChildren,
|
|
||||||
type ReactNode,
|
|
||||||
} from "react";
|
|
||||||
import { Link, NavLink } from "react-router-dom";
|
import { Link, NavLink } from "react-router-dom";
|
||||||
import { combineClasses } from "utils/combineClasses";
|
import { combineClasses } from "utils/combineClasses";
|
||||||
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
||||||
@ -74,13 +69,7 @@ const SidebarNavItem: FC<
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SidebarNavItemIcon: FC<{
|
export const Sidebar: FC<{ username: string; workspace: Workspace }> = ({
|
||||||
icon: ComponentType<{ className?: string }>;
|
|
||||||
}> = ({ icon: Icon }) => {
|
|
||||||
return <Icon css={{ width: 16, height: 16 }} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Sidebar: React.FC<{ username: string; workspace: Workspace }> = ({
|
|
||||||
username,
|
username,
|
||||||
workspace,
|
workspace,
|
||||||
}) => {
|
}) => {
|
||||||
@ -98,18 +87,21 @@ export const Sidebar: React.FC<{ username: string; workspace: Workspace }> = ({
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<SidebarNavItem href="" icon={<SidebarNavItemIcon icon={GeneralIcon} />}>
|
<SidebarNavItem
|
||||||
|
href=""
|
||||||
|
icon={<GeneralIcon css={styles.sidebarItemIcon} />}
|
||||||
|
>
|
||||||
General
|
General
|
||||||
</SidebarNavItem>
|
</SidebarNavItem>
|
||||||
<SidebarNavItem
|
<SidebarNavItem
|
||||||
href="parameters"
|
href="parameters"
|
||||||
icon={<SidebarNavItemIcon icon={ParameterIcon} />}
|
icon={<ParameterIcon css={styles.sidebarItemIcon} />}
|
||||||
>
|
>
|
||||||
Parameters
|
Parameters
|
||||||
</SidebarNavItem>
|
</SidebarNavItem>
|
||||||
<SidebarNavItem
|
<SidebarNavItem
|
||||||
href="schedule"
|
href="schedule"
|
||||||
icon={<SidebarNavItemIcon icon={ScheduleIcon} />}
|
icon={<ScheduleIcon css={styles.sidebarItemIcon} />}
|
||||||
>
|
>
|
||||||
Schedule
|
Schedule
|
||||||
</SidebarNavItem>
|
</SidebarNavItem>
|
||||||
@ -122,6 +114,10 @@ const styles = {
|
|||||||
width: 245,
|
width: 245,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
},
|
},
|
||||||
|
sidebarItemIcon: {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
},
|
||||||
workspaceInfo: (theme) => ({
|
workspaceInfo: (theme) => ({
|
||||||
...(theme.typography.body2 as CSSObject),
|
...(theme.typography.body2 as CSSObject),
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
|
@ -1,274 +1,62 @@
|
|||||||
// Based on https://codepen.io/hkfoster/pen/YzeYRwR
|
import tw from "./tailwind";
|
||||||
|
|
||||||
import { getMetadataAsJSON } from "utils/metadata";
|
|
||||||
|
|
||||||
// When in development mode the experiments meta tag won't exist,
|
|
||||||
// so you can just set this to true.
|
|
||||||
export const experimentalTheme =
|
|
||||||
typeof document !== "undefined" &&
|
|
||||||
(getMetadataAsJSON<string[]>("experiments")?.includes("dashboard_theme") ??
|
|
||||||
false);
|
|
||||||
|
|
||||||
export const colors = {
|
export const colors = {
|
||||||
white: "hsl(0, 0%, 100%)",
|
white: "#fff",
|
||||||
|
|
||||||
gray: experimentalTheme
|
gray: {
|
||||||
? {
|
17: tw.gray[950],
|
||||||
17: "hsl(0, 0%, 4%)",
|
16: tw.gray[900],
|
||||||
16: "hsl(0, 0%, 7%)",
|
14: tw.gray[800],
|
||||||
15: "hsl(0, 0%, 10%)",
|
13: tw.gray[700],
|
||||||
14: "hsl(0, 0%, 14%)",
|
12: tw.gray[600],
|
||||||
13: "hsl(0, 0%, 17%)",
|
11: tw.gray[500],
|
||||||
12: "hsl(0, 0%, 20%)",
|
9: tw.gray[400],
|
||||||
11: "hsl(0, 0%, 23%)",
|
6: tw.gray[300],
|
||||||
10: "hsl(0, 0%, 27%)",
|
4: tw.gray[200],
|
||||||
9: "hsl(0, 0%, 31%)",
|
2: tw.gray[100],
|
||||||
8: "hsl(0, 0%, 35%)",
|
1: tw.gray[50],
|
||||||
7: "hsl(0, 0%, 62%)",
|
},
|
||||||
6: "hsl(0, 0%, 69%)",
|
|
||||||
5: "hsl(0, 0%, 75%)",
|
|
||||||
4: "hsl(0, 0%, 82%)",
|
|
||||||
3: "hsl(0, 0%, 90%)",
|
|
||||||
2: "hsl(0, 0%, 93%)",
|
|
||||||
1: "hsl(0, 0%, 96%)",
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
17: "hsl(220, 50%, 3%)",
|
|
||||||
16: "hsl(223, 44%, 9%)",
|
|
||||||
15: "hsl(222, 38%, 14%)",
|
|
||||||
14: "hsl(222, 32%, 19%)",
|
|
||||||
13: "hsl(222, 31%, 25%)",
|
|
||||||
12: "hsl(222, 30%, 31%)",
|
|
||||||
11: "hsl(219, 29%, 38%)",
|
|
||||||
10: "hsl(219, 28%, 45%)",
|
|
||||||
9: "hsl(219, 28%, 52%)",
|
|
||||||
8: "hsl(218, 29%, 58%)",
|
|
||||||
7: "hsl(219, 30%, 64%)",
|
|
||||||
6: "hsl(219, 31%, 71%)",
|
|
||||||
5: "hsl(218, 32%, 77%)",
|
|
||||||
4: "hsl(223, 38%, 84%)",
|
|
||||||
3: "hsl(218, 44%, 92%)",
|
|
||||||
2: "hsl(220, 50%, 95%)",
|
|
||||||
1: "hsl(220, 55%, 98%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
red: experimentalTheme
|
red: {
|
||||||
? {
|
15: tw.red[950],
|
||||||
17: "hsl(355, 95%, 3%)",
|
12: tw.red[800],
|
||||||
16: "hsl(355, 88%, 8%)",
|
10: tw.red[700],
|
||||||
15: "hsl(355, 86%, 13%)",
|
9: tw.red[600],
|
||||||
14: "hsl(355, 84%, 18%)",
|
8: tw.red[500],
|
||||||
13: "hsl(355, 82%, 23%)",
|
6: tw.red[400],
|
||||||
12: "hsl(355, 74%, 28%)",
|
2: tw.red[50],
|
||||||
11: "hsl(355, 70%, 33%)",
|
},
|
||||||
10: "hsl(355, 66%, 38%)",
|
|
||||||
9: "hsl(355, 69%, 43%)",
|
|
||||||
8: "hsl(355, 73%, 48%)",
|
|
||||||
7: "hsl(355, 76%, 53%)",
|
|
||||||
6: "hsl(355, 78%, 58%)",
|
|
||||||
5: "hsl(355, 79%, 63%)",
|
|
||||||
4: "hsl(355, 85%, 68%)",
|
|
||||||
3: "hsl(355, 88%, 73%)",
|
|
||||||
2: "hsl(355, 95%, 78%)",
|
|
||||||
1: "hsl(355, 100%, 83%) ",
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
17: "hsl(355, 95%, 3%)",
|
|
||||||
16: "hsl(355, 88%, 9%)",
|
|
||||||
15: "hsl(355, 86%, 14%)",
|
|
||||||
14: "hsl(355, 84%, 19%)",
|
|
||||||
13: "hsl(355, 82%, 25%)",
|
|
||||||
12: "hsl(355, 74%, 31%)",
|
|
||||||
11: "hsl(355, 70%, 38%)",
|
|
||||||
10: "hsl(355, 66%, 45%)",
|
|
||||||
9: "hsl(355, 69%, 52%)",
|
|
||||||
8: "hsl(355, 73%, 58%)",
|
|
||||||
7: "hsl(355, 76%, 64%)",
|
|
||||||
6: "hsl(355, 78%, 71%)",
|
|
||||||
5: "hsl(355, 79%, 77%)",
|
|
||||||
4: "hsl(355, 85%, 84%)",
|
|
||||||
3: "hsl(355, 88%, 92%)",
|
|
||||||
2: "hsl(355, 95%, 96%)",
|
|
||||||
1: "hsl(355, 100%, 98%) ",
|
|
||||||
},
|
|
||||||
|
|
||||||
orange: {
|
orange: {
|
||||||
17: "hsl(20, 100%, 3%)",
|
15: tw.amber[950],
|
||||||
16: "hsl(20, 98%, 9%)",
|
14: tw.amber[900],
|
||||||
15: "hsl(20, 97%, 14%)",
|
12: tw.amber[800],
|
||||||
14: "hsl(20, 93%, 19%)",
|
11: tw.amber[700],
|
||||||
13: "hsl(20, 88%, 25%)",
|
10: tw.amber[600],
|
||||||
12: "hsl(20, 84%, 32%)",
|
9: tw.amber[500],
|
||||||
11: "hsl(20, 80%, 38%)",
|
7: tw.amber[400],
|
||||||
10: "hsl(20, 76%, 46%)",
|
|
||||||
9: "hsl(20, 79%, 53%)",
|
|
||||||
8: "hsl(20, 83%, 59%)",
|
|
||||||
7: "hsl(20, 86%, 65%)",
|
|
||||||
6: "hsl(20, 88%, 72%)",
|
|
||||||
5: "hsl(20, 93%, 78%)",
|
|
||||||
4: "hsl(20, 97%, 84%)",
|
|
||||||
3: "hsl(20, 98%, 91%)",
|
|
||||||
2: "hsl(20, 99%, 96%)",
|
|
||||||
1: "hsl(20, 100%, 98%)",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
yellow: {
|
yellow: {
|
||||||
17: "hsl(48, 100%, 3%)",
|
5: tw.yellow[300],
|
||||||
16: "hsl(48, 87%, 9%)",
|
|
||||||
15: "hsl(48, 83%, 14%)",
|
|
||||||
14: "hsl(48, 88%, 19%)",
|
|
||||||
13: "hsl(48, 82%, 25%)",
|
|
||||||
12: "hsl(48, 74%, 32%)",
|
|
||||||
11: "hsl(48, 70%, 38%)",
|
|
||||||
10: "hsl(48, 66%, 46%)",
|
|
||||||
9: "hsl(48, 69%, 53%)",
|
|
||||||
8: "hsl(48, 73%, 59%)",
|
|
||||||
7: "hsl(48, 76%, 65%)",
|
|
||||||
6: "hsl(48, 78%, 72%)",
|
|
||||||
5: "hsl(48, 79%, 78%)",
|
|
||||||
4: "hsl(48, 85%, 84%)",
|
|
||||||
3: "hsl(48, 90%, 89%)",
|
|
||||||
2: "hsl(46, 95%, 93%)",
|
|
||||||
1: "hsl(46, 100%, 97%)",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
green: {
|
green: {
|
||||||
17: "hsl(132, 98%, 3%)",
|
15: tw.green[950],
|
||||||
16: "hsl(140, 94%, 8%)",
|
13: tw.green[700],
|
||||||
15: "hsl(144, 93%, 12%)",
|
12: tw.green[600],
|
||||||
14: "hsl(145, 99%, 16%)",
|
11: tw.green[500],
|
||||||
13: "hsl(143, 83%, 22%)",
|
9: tw.green[400],
|
||||||
12: "hsl(143, 74%, 27%)",
|
8: tw.green[300],
|
||||||
11: "hsl(142, 64%, 34%)",
|
|
||||||
10: "hsl(141, 57%, 41%)",
|
|
||||||
9: "hsl(140, 50%, 49%)",
|
|
||||||
8: "hsl(140, 51%, 54%)",
|
|
||||||
7: "hsl(138, 54%, 61%)",
|
|
||||||
6: "hsl(137, 56%, 68%)",
|
|
||||||
5: "hsl(137, 55%, 75%)",
|
|
||||||
4: "hsl(137, 60%, 82%)",
|
|
||||||
3: "hsl(136, 74%, 91%)",
|
|
||||||
2: "hsl(136, 82%, 95%)",
|
|
||||||
1: "hsl(136, 100%, 97%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
turquoise: {
|
|
||||||
17: "hsl(162, 88%, 3%)",
|
|
||||||
16: "hsl(164, 84%, 8%)",
|
|
||||||
15: "hsl(165, 76%, 14%)",
|
|
||||||
14: "hsl(167, 85%, 18%)",
|
|
||||||
13: "hsl(166, 74%, 25%)",
|
|
||||||
12: "hsl(166, 65%, 32%)",
|
|
||||||
11: "hsl(165, 61%, 38%)",
|
|
||||||
10: "hsl(165, 56%, 46%)",
|
|
||||||
9: "hsl(165, 56%, 53%)",
|
|
||||||
8: "hsl(165, 60%, 57%)",
|
|
||||||
7: "hsl(164, 65%, 64%)",
|
|
||||||
6: "hsl(163, 66%, 70%)",
|
|
||||||
5: "hsl(163, 66%, 77%)",
|
|
||||||
4: "hsl(162, 74%, 83%)",
|
|
||||||
3: "hsl(162, 97%, 91%)",
|
|
||||||
2: "hsl(163, 93%, 94%)",
|
|
||||||
1: "hsl(163, 100%, 97%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
cyan: {
|
|
||||||
17: "hsl(186, 100%, 3%)",
|
|
||||||
16: "hsl(185, 86%, 8%)",
|
|
||||||
15: "hsl(186, 80%, 14%)",
|
|
||||||
14: "hsl(185, 83%, 18%)",
|
|
||||||
13: "hsl(185, 76%, 25%)",
|
|
||||||
12: "hsl(185, 68%, 31%)",
|
|
||||||
11: "hsl(185, 64%, 37%)",
|
|
||||||
10: "hsl(185, 59%, 45%)",
|
|
||||||
9: "hsl(185, 57%, 52%)",
|
|
||||||
8: "hsl(185, 61%, 57%)",
|
|
||||||
7: "hsl(185, 64%, 63%)",
|
|
||||||
6: "hsl(185, 66%, 70%)",
|
|
||||||
5: "hsl(185, 66%, 77%)",
|
|
||||||
4: "hsl(185, 72%, 83%)",
|
|
||||||
3: "hsl(185, 91%, 91%)",
|
|
||||||
2: "hsl(182, 96%, 94%)",
|
|
||||||
1: "hsl(182, 100%, 97%)",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
blue: {
|
blue: {
|
||||||
17: "hsl(215, 100%, 3%)",
|
14: tw.blue[950],
|
||||||
16: "hsl(215, 92%, 7%)",
|
9: tw.blue[600],
|
||||||
15: "hsl(215, 88%, 12%)",
|
8: tw.blue[500],
|
||||||
14: "hsl(215, 93%, 17%)",
|
7: tw.blue[400],
|
||||||
13: "hsl(215, 87%, 23%)",
|
6: tw.blue[300],
|
||||||
12: "hsl(215, 79%, 30%)",
|
3: tw.blue[200],
|
||||||
11: "hsl(215, 75%, 36%)",
|
1: tw.blue[50],
|
||||||
10: "hsl(215, 71%, 44%)",
|
|
||||||
9: "hsl(215, 74%, 51%)",
|
|
||||||
8: "hsl(215, 78%, 57%)",
|
|
||||||
7: "hsl(215, 81%, 63%)",
|
|
||||||
6: "hsl(215, 83%, 70%)",
|
|
||||||
5: "hsl(215, 84%, 76%)",
|
|
||||||
4: "hsl(215, 90%, 82%)",
|
|
||||||
3: "hsl(215, 93%, 89%)",
|
|
||||||
2: "hsl(215, 97%, 95%)",
|
|
||||||
1: "hsl(215, 100%, 98%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
indigo: {
|
|
||||||
17: "hsl(256, 100%, 3%)",
|
|
||||||
16: "hsl(254, 87%, 9%)",
|
|
||||||
15: "hsl(252, 83%, 14%)",
|
|
||||||
14: "hsl(250, 88%, 19%)",
|
|
||||||
13: "hsl(248, 82%, 25%)",
|
|
||||||
12: "hsl(246, 74%, 32%)",
|
|
||||||
11: "hsl(244, 70%, 38%)",
|
|
||||||
10: "hsl(242, 66%, 44%)",
|
|
||||||
9: "hsl(240, 67%, 53%)",
|
|
||||||
8: "hsl(238, 70%, 59%)",
|
|
||||||
7: "hsl(232, 74%, 63%)",
|
|
||||||
6: "hsl(236, 78%, 72%)",
|
|
||||||
5: "hsl(234, 79%, 78%)",
|
|
||||||
4: "hsl(232, 85%, 84%)",
|
|
||||||
3: "hsl(230, 90%, 91%)",
|
|
||||||
2: "hsl(228, 95%, 96%)",
|
|
||||||
1: "hsl(226, 100%, 98%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
violet: {
|
|
||||||
17: "hsl(264, 100%, 3%)",
|
|
||||||
16: "hsl(265, 87%, 9%)",
|
|
||||||
15: "hsl(265, 83%, 14%)",
|
|
||||||
14: "hsl(265, 88%, 19%)",
|
|
||||||
13: "hsl(265, 82%, 25%)",
|
|
||||||
12: "hsl(265, 74%, 32%)",
|
|
||||||
11: "hsl(265, 70%, 38%)",
|
|
||||||
10: "hsl(265, 66%, 46%)",
|
|
||||||
9: "hsl(265, 69%, 53%)",
|
|
||||||
8: "hsl(265, 73%, 59%)",
|
|
||||||
7: "hsl(265, 76%, 65%)",
|
|
||||||
6: "hsl(265, 78%, 72%)",
|
|
||||||
5: "hsl(265, 79%, 78%)",
|
|
||||||
4: "hsl(264, 85%, 84%)",
|
|
||||||
3: "hsl(265, 90%, 91%)",
|
|
||||||
2: "hsl(265, 95%, 96%)",
|
|
||||||
1: "hsl(265, 100%, 98%)",
|
|
||||||
},
|
|
||||||
|
|
||||||
magenta: {
|
|
||||||
17: "hsl(316, 100%, 3%)",
|
|
||||||
16: "hsl(316, 86%, 9%)",
|
|
||||||
15: "hsl(314, 83%, 14%)",
|
|
||||||
14: "hsl(315, 85%, 19%)",
|
|
||||||
13: "hsl(315, 80%, 25%)",
|
|
||||||
12: "hsl(315, 71%, 31%)",
|
|
||||||
11: "hsl(315, 68%, 38%)",
|
|
||||||
10: "hsl(315, 62%, 45%)",
|
|
||||||
9: "hsl(315, 63%, 52%)",
|
|
||||||
8: "hsl(315, 67%, 58%)",
|
|
||||||
7: "hsl(315, 70%, 64%)",
|
|
||||||
6: "hsl(315, 71%, 71%)",
|
|
||||||
5: "hsl(315, 72%, 77%)",
|
|
||||||
4: "hsl(315, 79%, 84%)",
|
|
||||||
3: "hsl(316, 88%, 92%)",
|
|
||||||
2: "hsl(315, 95%, 96%)",
|
|
||||||
1: "hsl(315, 100%, 98%)",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import colors from "./tailwind";
|
import colors from "./tailwind";
|
||||||
|
|
||||||
|
export type ThemeRole = keyof NewTheme["roles"];
|
||||||
|
|
||||||
export interface NewTheme {
|
export interface NewTheme {
|
||||||
l1: Role; // page background, things which sit at the "root level"
|
l1: Role; // page background, things which sit at the "root level"
|
||||||
l2: InteractiveRole; // sidebars, table headers, navigation
|
l2: InteractiveRole; // sidebars, table headers, navigation
|
||||||
@ -34,7 +36,7 @@ export const dark: NewTheme = {
|
|||||||
l1: {
|
l1: {
|
||||||
background: colors.gray[950],
|
background: colors.gray[950],
|
||||||
outline: colors.gray[700],
|
outline: colors.gray[700],
|
||||||
fill: "#f00",
|
fill: colors.gray[600],
|
||||||
text: colors.white,
|
text: colors.white,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ export const dark: NewTheme = {
|
|||||||
l3: {
|
l3: {
|
||||||
background: colors.gray[800],
|
background: colors.gray[800],
|
||||||
outline: colors.gray[700],
|
outline: colors.gray[700],
|
||||||
fill: "#f00",
|
fill: colors.gray[600],
|
||||||
text: colors.white,
|
text: colors.white,
|
||||||
disabled: {
|
disabled: {
|
||||||
background: "#f00",
|
background: "#f00",
|
||||||
@ -117,7 +119,7 @@ export const dark: NewTheme = {
|
|||||||
notice: {
|
notice: {
|
||||||
background: colors.yellow[950],
|
background: colors.yellow[950],
|
||||||
outline: colors.yellow[200],
|
outline: colors.yellow[200],
|
||||||
fill: "#f00",
|
fill: colors.yellow[500],
|
||||||
text: colors.yellow[50],
|
text: colors.yellow[50],
|
||||||
},
|
},
|
||||||
info: {
|
info: {
|
||||||
@ -147,7 +149,7 @@ export const dark: NewTheme = {
|
|||||||
active: {
|
active: {
|
||||||
background: colors.sky[950],
|
background: colors.sky[950],
|
||||||
outline: colors.sky[500],
|
outline: colors.sky[500],
|
||||||
fill: "#f00",
|
fill: colors.sky[600],
|
||||||
text: colors.sky[50],
|
text: colors.sky[50],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { colors, experimentalTheme } from "./colors";
|
import { colors } from "./colors";
|
||||||
import { createTheme, type ThemeOptions } from "@mui/material/styles";
|
import { createTheme, type ThemeOptions } from "@mui/material/styles";
|
||||||
import {
|
import {
|
||||||
BODY_FONT_FAMILY,
|
BODY_FONT_FAMILY,
|
||||||
@ -32,27 +32,27 @@ export let dark = createTheme({
|
|||||||
secondary: {
|
secondary: {
|
||||||
main: colors.gray[11],
|
main: colors.gray[11],
|
||||||
contrastText: colors.gray[4],
|
contrastText: colors.gray[4],
|
||||||
dark: colors.indigo[7],
|
dark: colors.gray[9],
|
||||||
},
|
},
|
||||||
background: {
|
background: {
|
||||||
default: colors.gray[17],
|
default: colors.gray[17],
|
||||||
paper: colors.gray[16],
|
paper: colors.gray[16],
|
||||||
paperLight: colors.gray[15],
|
paperLight: colors.gray[14],
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
primary: colors.gray[1],
|
primary: colors.gray[1],
|
||||||
secondary: colors.gray[5],
|
secondary: colors.gray[4],
|
||||||
disabled: colors.gray[7],
|
disabled: colors.gray[9],
|
||||||
},
|
},
|
||||||
divider: colors.gray[13],
|
divider: colors.gray[13],
|
||||||
warning: {
|
warning: {
|
||||||
light: experimentalTheme ? colors.orange[9] : colors.orange[7],
|
light: colors.orange[9],
|
||||||
main: experimentalTheme ? colors.orange[11] : colors.orange[9],
|
main: colors.orange[12],
|
||||||
dark: colors.orange[15],
|
dark: colors.orange[15],
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
main: colors.green[11],
|
main: colors.green[11],
|
||||||
dark: colors.green[15],
|
dark: colors.green[12],
|
||||||
},
|
},
|
||||||
info: {
|
info: {
|
||||||
light: colors.blue[7],
|
light: colors.blue[7],
|
||||||
@ -172,7 +172,7 @@ dark = createTheme(dark, {
|
|||||||
},
|
},
|
||||||
outlined: {
|
outlined: {
|
||||||
":hover": {
|
":hover": {
|
||||||
border: `1px solid ${colors.gray[10]}`,
|
border: `1px solid ${colors.gray[11]}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
outlinedNeutral: {
|
outlinedNeutral: {
|
||||||
@ -214,7 +214,7 @@ dark = createTheme(dark, {
|
|||||||
root: {
|
root: {
|
||||||
">button:hover+button": {
|
">button:hover+button": {
|
||||||
// The !important is unfortunate, but necessary for the border.
|
// The !important is unfortunate, but necessary for the border.
|
||||||
borderLeftColor: `${colors.gray[10]} !important`,
|
borderLeftColor: `${colors.gray[11]} !important`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -407,7 +407,7 @@ dark = createTheme(dark, {
|
|||||||
// The default outlined input color is white, which seemed jarring.
|
// The default outlined input color is white, which seemed jarring.
|
||||||
"&:hover:not(.Mui-error):not(.Mui-focused) .MuiOutlinedInput-notchedOutline":
|
"&:hover:not(.Mui-error):not(.Mui-focused) .MuiOutlinedInput-notchedOutline":
|
||||||
{
|
{
|
||||||
borderColor: colors.gray[10],
|
borderColor: colors.gray[11],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -173,43 +173,43 @@ export const getDisplayWorkspaceStatus = (
|
|||||||
} as const;
|
} as const;
|
||||||
case "starting":
|
case "starting":
|
||||||
return {
|
return {
|
||||||
type: "success",
|
type: "active",
|
||||||
text: "Starting",
|
text: "Starting",
|
||||||
icon: <LoadingIcon />,
|
icon: <LoadingIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "stopping":
|
case "stopping":
|
||||||
return {
|
return {
|
||||||
type: "warning",
|
type: "notice",
|
||||||
text: "Stopping",
|
text: "Stopping",
|
||||||
icon: <LoadingIcon />,
|
icon: <LoadingIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "stopped":
|
case "stopped":
|
||||||
return {
|
return {
|
||||||
type: "warning",
|
type: "notice",
|
||||||
text: "Stopped",
|
text: "Stopped",
|
||||||
icon: <StopIcon />,
|
icon: <StopIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "deleting":
|
case "deleting":
|
||||||
return {
|
return {
|
||||||
type: "warning",
|
type: "danger",
|
||||||
text: "Deleting",
|
text: "Deleting",
|
||||||
icon: <LoadingIcon />,
|
icon: <LoadingIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "deleted":
|
case "deleted":
|
||||||
return {
|
return {
|
||||||
type: "error",
|
type: "danger",
|
||||||
text: "Deleted",
|
text: "Deleted",
|
||||||
icon: <ErrorIcon />,
|
icon: <ErrorIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "canceling":
|
case "canceling":
|
||||||
return {
|
return {
|
||||||
type: "warning",
|
type: "notice",
|
||||||
text: "Canceling",
|
text: "Canceling",
|
||||||
icon: <LoadingIcon />,
|
icon: <LoadingIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
case "canceled":
|
case "canceled":
|
||||||
return {
|
return {
|
||||||
type: "warning",
|
type: "notice",
|
||||||
text: "Canceled",
|
text: "Canceled",
|
||||||
icon: <ErrorIcon />,
|
icon: <ErrorIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
@ -221,7 +221,7 @@ export const getDisplayWorkspaceStatus = (
|
|||||||
} as const;
|
} as const;
|
||||||
case "pending":
|
case "pending":
|
||||||
return {
|
return {
|
||||||
type: "info",
|
type: undefined,
|
||||||
text: getPendingWorkspaceStatusText(provisionerJob),
|
text: getPendingWorkspaceStatusText(provisionerJob),
|
||||||
icon: <QueuedIcon />,
|
icon: <QueuedIcon />,
|
||||||
} as const;
|
} as const;
|
||||||
|
Reference in New Issue
Block a user