mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): remove Stack component (#24503)
## Summary Remove the deprecated `Stack` component and replace all usages with Tailwind flex utility classes. - Replaced `<Stack>` → `<div className="flex flex-col gap-4">` (and variants per props) - Updated `StackLabel` and `FormFields` to no longer depend on `Stack` - Deleted `Stack.tsx` and `Stack.stories.tsx` 74 files changed, -226 lines net. > 🤖 Generated by Coder Agents --------- Co-authored-by: Jake Howell <jacob@coder.com>
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
||||
Sidebar as BaseSidebar,
|
||||
SettingsSidebarNavItem as SidebarNavItem,
|
||||
} from "#/components/Sidebar/Sidebar";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import type { Permissions } from "#/modules/permissions";
|
||||
import { getPrereleaseFlag } from "#/utils/buildInfo";
|
||||
|
||||
@@ -86,9 +85,9 @@ export const DeploymentSidebarView: FC<DeploymentSidebarViewProps> = ({
|
||||
)}
|
||||
{permissions.viewAnyGroup && (
|
||||
<SidebarNavItem href="/deployment/groups">
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<div className="flex flex-row items-center gap-1">
|
||||
Groups {showOrganizations && <ArrowUpRightIcon size={16} />}
|
||||
</Stack>
|
||||
</div>
|
||||
</SidebarNavItem>
|
||||
)}
|
||||
{permissions.viewOrganizationIDPSyncSettings && (
|
||||
@@ -108,9 +107,9 @@ export const DeploymentSidebarView: FC<DeploymentSidebarViewProps> = ({
|
||||
)}
|
||||
{permissions.editDeploymentConfig && (
|
||||
<SidebarNavItem href="/agents/settings/agents">
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<div className="flex flex-row items-center gap-1">
|
||||
Manage Coder Agents <ArrowUpRightIcon size={16} />
|
||||
</Stack>
|
||||
</div>
|
||||
</SidebarNavItem>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,6 @@ import type {
|
||||
WorkspaceAgentMetadata,
|
||||
} from "#/api/typesGenerated";
|
||||
import { Skeleton } from "#/components/Skeleton/Skeleton";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -139,7 +138,7 @@ export const AgentMetadata: FC<AgentMetadataProps> = ({
|
||||
|
||||
const AgentMetadataSkeleton: FC = () => {
|
||||
return (
|
||||
<Stack alignItems="baseline" direction="row" spacing={6}>
|
||||
<div className="flex flex-row items-baseline gap-12">
|
||||
<div className="leading-relaxed flex flex-col overflow-visible flex-shrink-0">
|
||||
<Skeleton width={40} height={6} variant="text" />
|
||||
<Skeleton width={65} height={8} variant="text" />
|
||||
@@ -154,7 +153,7 @@ const AgentMetadataSkeleton: FC = () => {
|
||||
<Skeleton width={40} height={6} variant="text" />
|
||||
<Skeleton width={65} height={8} variant="text" />
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
HelpPopoverTitle,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { agentVersionStatus } from "../../utils/workspace";
|
||||
|
||||
type AgentOutdatedTooltipProps = {
|
||||
@@ -46,25 +45,25 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
</span>
|
||||
</HelpPopoverTrigger>
|
||||
<HelpPopoverContent>
|
||||
<Stack spacing={1}>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div>
|
||||
<HelpPopoverTitle>{title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{text}</HelpPopoverText>
|
||||
</div>
|
||||
|
||||
<Stack spacing={0.5}>
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="font-semibold text-content-primary">
|
||||
Agent version
|
||||
</span>
|
||||
<span>{agent.version}</span>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Stack spacing={0.5}>
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="font-semibold text-content-primary">
|
||||
Server version
|
||||
</span>
|
||||
<span>{serverVersion}</span>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverAction
|
||||
@@ -78,7 +77,7 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
Update workspace
|
||||
</HelpPopoverAction>
|
||||
</HelpPopoverLinksGroup>
|
||||
</Stack>
|
||||
</div>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { FC } from "react";
|
||||
import type { WorkspaceAgent } from "#/api/typesGenerated";
|
||||
import { TerminalIcon } from "#/components/Icons/TerminalIcon";
|
||||
import { VSCodeIcon } from "#/components/Icons/VSCodeIcon";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { DisplayAppNameMap } from "./AppLink/AppLink";
|
||||
import { AppPreview } from "./AppLink/AppPreview";
|
||||
import { BaseIcon } from "./AppLink/BaseIcon";
|
||||
@@ -22,27 +21,21 @@ export const AgentRowPreview: FC<AgentRowPreviewProps> = ({
|
||||
alignValues,
|
||||
}) => {
|
||||
return (
|
||||
<Stack
|
||||
<div
|
||||
key={agent.id}
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
className="flex flex-row items-center justify-between gap-4"
|
||||
css={styles.agentRow}
|
||||
>
|
||||
<Stack direction="row" alignItems="baseline">
|
||||
<div className="flex flex-row items-baseline gap-4">
|
||||
<div css={styles.agentStatusWrapper}>
|
||||
<div css={styles.agentStatusPreview} />
|
||||
</div>
|
||||
<Stack
|
||||
alignItems="baseline"
|
||||
direction="row"
|
||||
spacing={4}
|
||||
<div
|
||||
className="flex flex-row items-baseline gap-8"
|
||||
css={styles.agentData}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="baseline"
|
||||
spacing={1}
|
||||
<div
|
||||
className="flex flex-row items-baseline gap-2"
|
||||
css={[
|
||||
styles.noShrink,
|
||||
styles.agentDataItem,
|
||||
@@ -55,12 +48,10 @@ export const AgentRowPreview: FC<AgentRowPreviewProps> = ({
|
||||
>
|
||||
<span>Agent:</span>
|
||||
<span css={styles.agentDataValue}>{agent.name}</span>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="baseline"
|
||||
spacing={1}
|
||||
<div
|
||||
className="flex flex-row items-baseline gap-2"
|
||||
css={[
|
||||
styles.noShrink,
|
||||
styles.agentDataItem,
|
||||
@@ -75,21 +66,14 @@ export const AgentRowPreview: FC<AgentRowPreviewProps> = ({
|
||||
<span css={[styles.agentDataValue, styles.agentOS]}>
|
||||
{agent.operating_system}
|
||||
</span>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
spacing={1}
|
||||
<div
|
||||
className="flex flex-row items-center gap-2"
|
||||
css={styles.agentDataItem}
|
||||
>
|
||||
<span>Apps:</span>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
spacing={0.5}
|
||||
wrap="wrap"
|
||||
>
|
||||
<div className="flex flex-row items-center gap-1 flex-wrap">
|
||||
{/* We display all modules returned in agent.apps */}
|
||||
{agent.apps.map((app) => (
|
||||
<AppPreview key={app.slug}>
|
||||
@@ -130,11 +114,11 @@ export const AgentRowPreview: FC<AgentRowPreviewProps> = ({
|
||||
{agent.apps.length === 0 && agent.display_apps.length === 0 && (
|
||||
<span css={styles.agentDataValue}>None</span>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import type { FC, PropsWithChildren } from "react";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
export const AppPreview: FC<PropsWithChildren> = ({ children }) => {
|
||||
return (
|
||||
<Stack
|
||||
className="flex items-center h-8 px-3 rounded-full border border-solid border-surface-quaternary text-content-primary bg-surface-secondary flex-shrink-0 w-fit text-xs [&>svg]:w-[13px] [&>img]:w-[13px]"
|
||||
alignItems="center"
|
||||
direction="row"
|
||||
spacing={1}
|
||||
>
|
||||
<div className="flex flex-row items-center gap-2 h-8 px-3 rounded-full border border-solid border-surface-quaternary text-content-primary bg-surface-secondary flex-shrink-0 w-fit text-xs [&>svg]:w-[13px] [&>img]:w-[13px]">
|
||||
{children}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import { CopyableValue } from "#/components/CopyableValue/CopyableValue";
|
||||
import { MemoizedInlineMarkdown } from "#/components/Markdown/InlineMarkdown";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -97,13 +96,11 @@ export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
|
||||
|
||||
return (
|
||||
<div key={resource.id} css={styles.resourceCard} className="resource-card">
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="flex-start"
|
||||
<div
|
||||
className="flex flex-row items-start gap-20"
|
||||
css={styles.resourceCardHeader}
|
||||
spacing={10}
|
||||
>
|
||||
<Stack direction="row" spacing={1} css={styles.resourceCardProfile}>
|
||||
<div className="flex flex-row gap-2" css={styles.resourceCardProfile}>
|
||||
<div>
|
||||
<ResourceAvatar resource={resource} />
|
||||
</div>
|
||||
@@ -111,7 +108,7 @@ export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
|
||||
<div css={styles.metadataLabel}>{resource.type}</div>
|
||||
<div css={styles.metadataValue}>{resource.name}</div>
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="grow-[2] grid gap-x-10 gap-y-6"
|
||||
@@ -180,7 +177,7 @@ export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
{resource.agents && resource.agents.length > 0 && (
|
||||
<div>{resource.agents.map(agentRow)}</div>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { type FC, type JSX, useState } from "react";
|
||||
import type { WorkspaceAgent, WorkspaceResource } from "#/api/typesGenerated";
|
||||
import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { ResourceCard } from "./ResourceCard";
|
||||
|
||||
const countAgents = (resource: WorkspaceResource) => {
|
||||
@@ -26,7 +25,7 @@ export const Resources: FC<ResourcesProps> = ({ resources, agentRow }) => {
|
||||
const hasHideResources = resources.some((r) => r.hide);
|
||||
|
||||
return (
|
||||
<Stack direction="column" spacing={0} className="bg-surface-primary">
|
||||
<div className="flex flex-col bg-surface-primary">
|
||||
{displayResources.map((resource) => (
|
||||
<ResourceCard
|
||||
key={resource.id}
|
||||
@@ -50,6 +49,6 @@ export const Resources: FC<ResourcesProps> = ({ resources, agentRow }) => {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "#/components/Popover/Popover";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
interface AgentSSHButtonProps {
|
||||
@@ -49,7 +48,7 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
|
||||
</HelpPopoverText>
|
||||
|
||||
<ol style={{ margin: 0, padding: 0 }}>
|
||||
<Stack spacing={0.5} className="mt-3">
|
||||
<div className="flex flex-col gap-1 mt-3">
|
||||
<SSHStep
|
||||
helpText="Configure SSH hosts on machine:"
|
||||
codeExample="coder config-ssh"
|
||||
@@ -58,7 +57,7 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
|
||||
helpText="Connect to the agent:"
|
||||
codeExample={`ssh ${agentName}.${workspaceName}.${workspaceOwnerUsername}.${sshSuffix}`}
|
||||
/>
|
||||
</Stack>
|
||||
</div>
|
||||
</ol>
|
||||
|
||||
<HelpPopoverLinksGroup>
|
||||
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
SelectValue,
|
||||
} from "#/components/Select/Select";
|
||||
import { Slider } from "#/components/Slider/Slider";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { Switch } from "#/components/Switch/Switch";
|
||||
import { TagInput } from "#/components/TagInput/TagInput";
|
||||
import { Textarea } from "#/components/Textarea/Textarea";
|
||||
@@ -505,7 +504,7 @@ const MaskableInput: FC<MaskableInputProps> = ({
|
||||
const [showMaskedInput, setShowMaskedInput] = useState(false);
|
||||
|
||||
return (
|
||||
<Stack direction="row" spacing={0} alignItems="center">
|
||||
<div className="flex flex-row items-center">
|
||||
<Input
|
||||
id={id}
|
||||
type={masked && showMaskedInput ? "text" : type}
|
||||
@@ -535,7 +534,7 @@ const MaskableInput: FC<MaskableInputProps> = ({
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -552,7 +551,7 @@ const MaskableTextArea: FC<MaskableInputProps> = ({
|
||||
const [showMaskedInput, setShowMaskedInput] = useState(false);
|
||||
|
||||
return (
|
||||
<Stack direction="row" spacing={0} alignItems="center">
|
||||
<div className="flex flex-row items-center">
|
||||
<Textarea
|
||||
ref={textareaRef}
|
||||
id={id}
|
||||
@@ -589,7 +588,7 @@ const MaskableTextArea: FC<MaskableInputProps> = ({
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import type { DialogProps } from "#/components/Dialogs/Dialog";
|
||||
import { FormFields } from "#/components/Form/Form";
|
||||
import { Loader } from "#/components/Loader/Loader";
|
||||
import { Pill } from "#/components/Pill/Pill";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { TemplateUpdateMessage } from "#/modules/templates/TemplateUpdateMessage";
|
||||
import { createDayString } from "#/utils/createDayString";
|
||||
|
||||
@@ -55,7 +54,7 @@ export const ChangeWorkspaceVersionDialog: FC<
|
||||
confirmText="Change"
|
||||
title="Change version"
|
||||
description={
|
||||
<Stack>
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>You are about to change the version of this workspace.</p>
|
||||
{validVersions ? (
|
||||
<>
|
||||
@@ -90,16 +89,8 @@ export const ChangeWorkspaceVersionDialog: FC<
|
||||
/>
|
||||
}
|
||||
title={
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
spacing={1}
|
||||
>
|
||||
<div className="flex flex-row justify-between gap-4 w-full">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
{option.name}
|
||||
{option.message && (
|
||||
<InfoIcon
|
||||
@@ -107,10 +98,10 @@ export const ChangeWorkspaceVersionDialog: FC<
|
||||
className="size-icon-xs"
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
{workspace.template_active_version_id ===
|
||||
option.id && <Pill type="success">Active</Pill>}
|
||||
</Stack>
|
||||
</div>
|
||||
}
|
||||
subtitle={createDayString(option.created_at)}
|
||||
/>
|
||||
@@ -155,7 +146,7 @@ export const ChangeWorkspaceVersionDialog: FC<
|
||||
) : (
|
||||
<Loader />
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
type ConfirmDialogProps,
|
||||
} from "#/components/Dialogs/ConfirmDialog/ConfirmDialog";
|
||||
import { Skeleton } from "#/components/Skeleton/Skeleton";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { cn } from "#/utils/cn";
|
||||
|
||||
type DownloadLogsDialogProps = Pick<
|
||||
@@ -140,7 +139,7 @@ export const DownloadLogsDialog: FC<DownloadLogsDialogProps> = ({
|
||||
}
|
||||
}}
|
||||
description={
|
||||
<Stack className="pb-4">
|
||||
<div className="flex flex-col gap-4 pb-4">
|
||||
<p>
|
||||
Downloading logs will create a zip file containing all logs from all
|
||||
jobs in this workspace. This may take a while.
|
||||
@@ -162,7 +161,7 @@ export const DownloadLogsDialog: FC<DownloadLogsDialogProps> = ({
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</Stack>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user