mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore(site): decss the <WorkspaceBuild* /> pages (#24530)
This removes the CSS props of various components found in our workspaces pages. Eventually, we'd like to remove the MUI-specific components in here, but its a good start!
This commit is contained in:
@@ -29,25 +29,13 @@ export const SidebarItem: FC<SidebarItemProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
css={(theme) => ({
|
||||
background: active ? theme.experimental.l2.background : "none",
|
||||
border: "none",
|
||||
fontSize: 14,
|
||||
width: "100%",
|
||||
textAlign: "left",
|
||||
padding: "0 24px",
|
||||
cursor: "pointer",
|
||||
pointerEvents: active ? "none" : "auto",
|
||||
color: active
|
||||
? theme.palette.text.primary
|
||||
: theme.palette.text.secondary,
|
||||
"&:hover": {
|
||||
background: theme.palette.action.hover,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
})}
|
||||
className={cn(
|
||||
"py-2.5 px-6 border-0 text-sm w-full text-left cursor-pointer",
|
||||
"hover:bg-surface-tertiary hover:text-content-primary",
|
||||
active
|
||||
? "text-content-primary pointer-events-none bg-surface-secondary"
|
||||
: "text-content-secondary pointer-events-auto bg-transparent",
|
||||
)}
|
||||
{...attrs}
|
||||
>
|
||||
{children}
|
||||
@@ -57,18 +45,15 @@ export const SidebarItem: FC<SidebarItemProps> = ({
|
||||
|
||||
export const SidebarCaption: FC<HTMLAttributes<HTMLDivElement>> = ({
|
||||
children,
|
||||
className,
|
||||
...attrs
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
css={(theme) => ({
|
||||
fontSize: 10,
|
||||
textTransform: "uppercase",
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.secondary,
|
||||
padding: "12px 24px",
|
||||
letterSpacing: "0.5px",
|
||||
})}
|
||||
className={cn(
|
||||
"text-[10px] uppercase font-medium text-content-secondary",
|
||||
"px-6 py-3 tracking-[0.5px]",
|
||||
)}
|
||||
{...attrs}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import { Children, type FC, type HTMLAttributes } from "react";
|
||||
import type { WorkspaceResource } from "#/api/typesGenerated";
|
||||
import { CopyableValue } from "#/components/CopyableValue/CopyableValue";
|
||||
import { MemoizedInlineMarkdown } from "#/components/Markdown/InlineMarkdown";
|
||||
import { SensitiveValue } from "#/modules/resources/SensitiveValue";
|
||||
import { cn } from "#/utils/cn";
|
||||
|
||||
type ResourceMetadataProps = Omit<HTMLAttributes<HTMLElement>, "resource"> & {
|
||||
resource: WorkspaceResource;
|
||||
@@ -11,6 +11,7 @@ type ResourceMetadataProps = Omit<HTMLAttributes<HTMLElement>, "resource"> & {
|
||||
|
||||
export const ResourceMetadata: FC<ResourceMetadataProps> = ({
|
||||
resource,
|
||||
className,
|
||||
...headerProps
|
||||
}) => {
|
||||
const metadata = resource.metadata ? [...resource.metadata] : [];
|
||||
@@ -28,11 +29,17 @@ export const ResourceMetadata: FC<ResourceMetadataProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<header css={styles.root} {...headerProps}>
|
||||
<header
|
||||
className={cn(
|
||||
"p-6 flex flex-wrap gap-x-12 gap-y-6 mb-6 text-sm",
|
||||
className,
|
||||
)}
|
||||
{...headerProps}
|
||||
>
|
||||
{metadata.map((meta) => {
|
||||
return (
|
||||
<div css={styles.item} key={meta.key}>
|
||||
<div css={styles.value}>
|
||||
<div className="leading-normal" key={meta.key}>
|
||||
<div className="text-ellipsis font-normal">
|
||||
{meta.sensitive ? (
|
||||
<SensitiveValue value={meta.value} />
|
||||
) : (
|
||||
@@ -59,40 +66,12 @@ export const ResourceMetadata: FC<ResourceMetadataProps> = ({
|
||||
</MemoizedInlineMarkdown>
|
||||
)}
|
||||
</div>
|
||||
<div css={styles.label}>{meta.key}</div>
|
||||
<div className="font-normal leading-normal text-xs text-content-secondary truncate">
|
||||
{meta.key}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
root: () => ({
|
||||
padding: 24,
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: 48,
|
||||
rowGap: 24,
|
||||
marginBottom: 24,
|
||||
fontSize: 14,
|
||||
}),
|
||||
|
||||
item: {
|
||||
lineHeight: "1.5",
|
||||
},
|
||||
|
||||
label: (theme) => ({
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
whiteSpace: "nowrap",
|
||||
}),
|
||||
|
||||
value: {
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { type FC, type ReactNode, useState } from "react";
|
||||
import type { AlertProps } from "#/components/Alert/Alert";
|
||||
import { Button, type ButtonProps } from "#/components/Button/Button";
|
||||
@@ -37,7 +37,8 @@ export const Notifications: FC<NotificationsProps> = ({
|
||||
<Tooltip open={isOpen} onOpenChange={setIsOpen} delayDuration={0}>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
css={styles.pillContainer}
|
||||
// Adds some spacing from the Tooltip content
|
||||
className="py-2"
|
||||
data-testid={`${severity}-notifications`}
|
||||
>
|
||||
<NotificationPill
|
||||
@@ -94,10 +95,12 @@ interface NotificationItemProps {
|
||||
|
||||
const NotificationItem: FC<NotificationItemProps> = ({ notification }) => {
|
||||
return (
|
||||
<article css={styles.notificationItem}>
|
||||
<article className="p-5 leading-normal border-0 border-t border-solid first:border-t-0">
|
||||
<h4 className="m-0 font-medium">{notification.title}</h4>
|
||||
{notification.detail && (
|
||||
<p css={styles.notificationDetail}>{notification.detail}</p>
|
||||
<p className="m-0 text-content-secondary leading-relaxed block mt-2">
|
||||
{notification.detail}
|
||||
</p>
|
||||
)}
|
||||
<div className="mt-2 flex items-center gap-1">{notification.actions}</div>
|
||||
</article>
|
||||
@@ -107,26 +110,3 @@ const NotificationItem: FC<NotificationItemProps> = ({ notification }) => {
|
||||
export const NotificationActionButton: FC<ButtonProps> = (props) => {
|
||||
return <Button variant="default" size="sm" {...props} />;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
// Adds some spacing from the Tooltip content
|
||||
pillContainer: {
|
||||
padding: "8px 0",
|
||||
},
|
||||
notificationItem: (theme) => ({
|
||||
padding: 20,
|
||||
lineHeight: "1.5",
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
|
||||
"&:first-of-type": {
|
||||
borderTop: 0,
|
||||
},
|
||||
}),
|
||||
notificationDetail: (theme) => ({
|
||||
margin: 0,
|
||||
color: theme.palette.text.secondary,
|
||||
lineHeight: 1.6,
|
||||
display: "block",
|
||||
marginTop: 8,
|
||||
}),
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
import { InfoIcon, TriangleAlertIcon } from "lucide-react";
|
||||
@@ -239,7 +238,7 @@ export const WorkspaceNotifications: FC<WorkspaceNotificationsProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div css={styles.notificationsGroup}>
|
||||
<div className="flex items-center gap-3">
|
||||
{infoNotifications.length > 0 && (
|
||||
<Notifications
|
||||
items={infoNotifications}
|
||||
@@ -259,14 +258,6 @@ export const WorkspaceNotifications: FC<WorkspaceNotificationsProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
notificationsGroup: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
},
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
const findTroubleshootingURL = (
|
||||
workspaceBuild: WorkspaceBuild,
|
||||
): string | undefined => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import Link, { type LinkProps } from "@mui/material/Link";
|
||||
import dayjs, { type Dayjs } from "dayjs";
|
||||
import { ClockIcon, MinusIcon, PlusIcon } from "lucide-react";
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
} from "#/components/Tooltip/Tooltip";
|
||||
import { useTime } from "#/hooks/useTime";
|
||||
import { getWorkspaceActivityStatus } from "#/modules/workspaces/activity";
|
||||
import { cn } from "#/utils/cn";
|
||||
import {
|
||||
autostartDisplay,
|
||||
autostopDisplay,
|
||||
@@ -55,7 +55,10 @@ const WorkspaceScheduleContainer: FC<WorkspaceScheduleContainerProps> = ({
|
||||
type="button"
|
||||
data-testid="schedule-icon-button"
|
||||
onClick={onClickIcon}
|
||||
css={styles.scheduleIconButton}
|
||||
className={cn(
|
||||
"flex items-center bg-transparent border-0 p-0",
|
||||
"[font-size:inherit] leading-[inherit] cursor-pointer",
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
</button>
|
||||
@@ -86,7 +89,10 @@ export const WorkspaceScheduleControls: FC<WorkspaceScheduleControlsProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div css={styles.scheduleValue} data-testid="schedule-controls">
|
||||
<div
|
||||
className="flex items-center gap-3 [font-variant-numeric:tabular-nums]"
|
||||
data-testid="schedule-controls"
|
||||
>
|
||||
{isWorkspaceOn(workspace) ? (
|
||||
<AutostopDisplay
|
||||
workspace={workspace}
|
||||
@@ -198,19 +204,14 @@ const AutostopDisplay: FC<AutostopDisplayProps> = ({
|
||||
const display = (
|
||||
<ScheduleSettingsLink
|
||||
data-testid="schedule-controls-autostop"
|
||||
css={
|
||||
danger &&
|
||||
((theme) => ({
|
||||
color: `${theme.roles.danger.fill.outline} !important`,
|
||||
}))
|
||||
}
|
||||
className={cn(danger && "!text-content-destructive")}
|
||||
>
|
||||
{message}
|
||||
</ScheduleSettingsLink>
|
||||
);
|
||||
|
||||
const controls = canUpdateSchedule && canEditDeadline(workspace) && (
|
||||
<div css={styles.scheduleControls}>
|
||||
<div className="flex items-center gap-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
@@ -298,29 +299,3 @@ const shouldDisplayScheduleControls = (workspace: Workspace): boolean => {
|
||||
const willAutoStart = !isWorkspaceOn(workspace) && hasAutoStart(workspace);
|
||||
return willAutoStop || willAutoStart;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
scheduleIconButton: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
background: "transparent",
|
||||
border: 0,
|
||||
padding: 0,
|
||||
fontSize: "inherit",
|
||||
lineHeight: "inherit",
|
||||
cursor: "pointer",
|
||||
},
|
||||
|
||||
scheduleValue: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
fontVariantNumeric: "tabular-nums",
|
||||
},
|
||||
|
||||
scheduleControls: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
},
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import Link from "@mui/material/Link";
|
||||
import { ChevronLeftIcon, CircleDollarSignIcon, TrashIcon } from "lucide-react";
|
||||
import type { FC } from "react";
|
||||
@@ -30,6 +29,7 @@ import {
|
||||
import { useDashboard } from "#/modules/dashboard/useDashboard";
|
||||
import { linkToTemplate, useLinks } from "#/modules/navigation";
|
||||
import { WorkspaceStatusIndicator } from "#/modules/workspaces/WorkspaceStatusIndicator/WorkspaceStatusIndicator";
|
||||
import { cn } from "#/utils/cn";
|
||||
import { displayDormantDeletion } from "#/utils/dormant";
|
||||
import { formatDate } from "#/utils/time";
|
||||
import type { WorkspacePermissions } from "../../modules/workspaces/permissions";
|
||||
@@ -37,7 +37,13 @@ import { WorkspaceActions } from "./WorkspaceActions/WorkspaceActions";
|
||||
import { WorkspaceNotifications } from "./WorkspaceNotifications/WorkspaceNotifications";
|
||||
import { WorkspaceScheduleControls } from "./WorkspaceScheduleControls";
|
||||
|
||||
interface WorkspaceProps {
|
||||
const BREADCRUMB_SEGMENT_CLASS = cn(
|
||||
"flex items-center flex-row flex-nowrap gap-2",
|
||||
"max-w-40 whitespace-nowrap cursor-default",
|
||||
);
|
||||
const BREADCRUMB_TEXT_CLASS = "overflow-x-hidden text-ellipsis";
|
||||
|
||||
interface WorkspaceTopbarProps {
|
||||
isUpdating: boolean;
|
||||
isRestarting: boolean;
|
||||
workspace: TypesGen.Workspace;
|
||||
@@ -55,7 +61,7 @@ interface WorkspaceProps {
|
||||
handleToggleFavorite: () => void;
|
||||
}
|
||||
|
||||
export const WorkspaceTopbar: FC<WorkspaceProps> = ({
|
||||
export const WorkspaceTopbar: FC<WorkspaceTopbarProps> = ({
|
||||
workspace,
|
||||
template,
|
||||
latestVersion,
|
||||
@@ -263,9 +269,9 @@ const OwnerBreadcrumb: FC<OwnerBreadcrumbProps> = ({
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<span className={BREADCRUMB_SEGMENT_CLASS}>
|
||||
<Avatar size="sm" fallback={ownerName} src={ownerAvatarUrl} />
|
||||
<span css={styles.breadcrumbText}>{ownerName}</span>
|
||||
<span className={BREADCRUMB_TEXT_CLASS}>{ownerName}</span>
|
||||
</span>
|
||||
</HelpPopoverTrigger>
|
||||
|
||||
@@ -290,14 +296,14 @@ const OrganizationBreadcrumb: FC<OrganizationBreadcrumbProps> = ({
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<span className={BREADCRUMB_SEGMENT_CLASS}>
|
||||
<Avatar
|
||||
size="sm"
|
||||
variant="icon"
|
||||
src={orgIconUrl}
|
||||
fallback={orgName}
|
||||
/>
|
||||
<span css={styles.breadcrumbText}>{orgName}</span>
|
||||
<span className={BREADCRUMB_TEXT_CLASS}>{orgName}</span>
|
||||
</span>
|
||||
</HelpPopoverTrigger>
|
||||
|
||||
@@ -355,13 +361,13 @@ const WorkspaceBreadcrumb: FC<WorkspaceBreadcrumbProps> = ({
|
||||
<div className="flex items-center">
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<span className={BREADCRUMB_SEGMENT_CLASS}>
|
||||
<TopbarAvatar
|
||||
src={templateIconUrl}
|
||||
fallback={templateDisplayName}
|
||||
/>
|
||||
|
||||
<span css={[styles.breadcrumbText, { fontWeight: 500 }]}>
|
||||
<span className={cn(BREADCRUMB_TEXT_CLASS, "font-medium")}>
|
||||
{workspaceName}
|
||||
</span>
|
||||
</span>
|
||||
@@ -403,20 +409,3 @@ const WorkspaceBreadcrumb: FC<WorkspaceBreadcrumbProps> = ({
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
breadcrumbSegment: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexFlow: "row nowrap",
|
||||
gap: "8px",
|
||||
maxWidth: "160px",
|
||||
whiteSpace: "nowrap",
|
||||
cursor: "default",
|
||||
},
|
||||
|
||||
breadcrumbText: {
|
||||
overflowX: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
},
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
+1
-4
@@ -185,10 +185,7 @@ export const WorkspaceParametersPageView: FC<
|
||||
</a>
|
||||
</Button>
|
||||
}
|
||||
css={(theme) => ({
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 8,
|
||||
})}
|
||||
className="border border-solid rounded-lg"
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user