Skip to content

Commit 0ab23ab

Browse files
authored
refactor(site): convert workspace batch delete dialog to Tailwind CSS (#20946)
Converts from Emotion to Tailwind CSS, based on the tasks batch delete dialog implementation. Also propagates simplifications back to the tasks dialog: - Use `border-border` instead of hardcoded color variants - Use `max-h-48` instead of specific `max-h-[184px]` - Add cancel button to workspaces dialog Refs #20905
1 parent c4bf5a2 commit 0ab23ab

File tree

3 files changed

+38
-110
lines changed

3 files changed

+38
-110
lines changed

site/src/pages/TasksPage/BatchDeleteConfirmation.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ const Tasks: FC<TasksStageProps> = ({ tasks }) => {
113113

114114
return (
115115
<>
116-
<ul className="list-none p-0 border border-solid border-zinc-200 dark:border-zinc-700 rounded-lg overflow-x-hidden overflow-y-auto max-h-[184px]">
116+
<ul className="list-none p-0 border border-solid border-border rounded-lg overflow-x-hidden overflow-y-auto max-h-48">
117117
{tasks.map((task) => (
118118
<li
119119
key={task.id}
120-
className="py-2 px-4 border-solid border-0 border-b border-zinc-200 dark:border-zinc-700 last:border-b-0"
120+
className="py-2 px-4 border-solid border-0 border-b border-border last:border-b-0"
121121
>
122122
<div className="flex items-center justify-between gap-6">
123123
<span className="font-medium text-content-primary max-w-[400px] overflow-hidden text-ellipsis whitespace-nowrap">

site/src/pages/WorkspacesPage/BatchDeleteConfirmation.tsx

Lines changed: 35 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
2-
import { visuallyHidden } from "@mui/utils";
31
import type { Workspace } from "api/typesGenerated";
42
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
53
import { ExternalImage } from "components/ExternalImage/ExternalImage";
6-
import { Stack } from "components/Stack/Stack";
74
import dayjs from "dayjs";
85
import relativeTime from "dayjs/plugin/relativeTime";
96
import { ClockIcon, UserIcon } from "lucide-react";
@@ -67,7 +64,7 @@ export const BatchDeleteConfirmation: FC<BatchDeleteConfirmationProps> = ({
6764
);
6865
}
6966

70-
// The flicker of these icons is quit noticeable if they aren't loaded in advance,
67+
// The flicker of these icons is quite noticeable if they aren't loaded in advance,
7168
// so we insert them into the document without actually displaying them yet.
7269
const resourceIconPreloads = [
7370
...new Set(
@@ -78,7 +75,7 @@ export const BatchDeleteConfirmation: FC<BatchDeleteConfirmationProps> = ({
7875
),
7976
),
8077
].map((url) => (
81-
<img key={url} alt="" aria-hidden css={{ ...visuallyHidden }} src={url} />
78+
<img key={url} alt="" aria-hidden className="sr-only" src={url} />
8279
));
8380

8481
return (
@@ -90,7 +87,6 @@ export const BatchDeleteConfirmation: FC<BatchDeleteConfirmationProps> = ({
9087
onClose();
9188
}}
9289
title={`Delete ${workspaceCount}`}
93-
hideCancel
9490
confirmLoading={isLoading}
9591
confirmText={confirmText}
9692
onConfirm={onProceed}
@@ -118,7 +114,7 @@ const Consequences: FC = () => {
118114
return (
119115
<>
120116
<p>Deleting workspaces is irreversible!</p>
121-
<ul css={styles.consequences}>
117+
<ul className="flex flex-col gap-2 pl-4 mb-0">
122118
<li>
123119
Terraform resources belonging to deleted workspaces will be destroyed.
124120
</li>
@@ -129,8 +125,6 @@ const Consequences: FC = () => {
129125
};
130126

131127
const Workspaces: FC<StageProps> = ({ workspaces }) => {
132-
const theme = useTheme();
133-
134128
const mostRecent = workspaces.reduce(
135129
(latestSoFar, against) => {
136130
if (!latestSoFar) {
@@ -150,69 +144,47 @@ const Workspaces: FC<StageProps> = ({ workspaces }) => {
150144

151145
return (
152146
<>
153-
<ul css={styles.workspacesList}>
147+
<ul className="list-none p-0 border border-solid border-border rounded-lg overflow-x-hidden overflow-y-auto max-h-48">
154148
{workspaces.map((workspace) => (
155-
<li key={workspace.id} css={styles.workspace}>
156-
<Stack
157-
direction="row"
158-
alignItems="center"
159-
justifyContent="space-between"
160-
spacing={3}
161-
>
162-
<span
163-
css={{ fontWeight: 500, color: theme.experimental.l1.text }}
164-
>
149+
<li
150+
key={workspace.id}
151+
className="py-2 px-4 border-solid border-0 border-b border-border last:border-b-0"
152+
>
153+
<div className="flex items-center justify-between gap-6">
154+
<span className="font-medium text-content-primary max-w-[400px] overflow-hidden text-ellipsis whitespace-nowrap">
165155
{workspace.name}
166156
</span>
167-
<Stack css={{ gap: 0, fontSize: 14 }} justifyContent="flex-end">
168-
<Stack
169-
direction="row"
170-
alignItems="center"
171-
justifyContent="flex-end"
172-
spacing={1}
173-
>
174-
<span
175-
css={{ whiteSpace: "nowrap", textOverflow: "ellipsis" }}
176-
>
157+
158+
<div className="flex flex-col text-sm items-end">
159+
<div className="flex items-center gap-2">
160+
<span className="whitespace-nowrap">
177161
{workspace.owner_name}
178162
</span>
179-
<PersonIcon />
180-
</Stack>
181-
<Stack
182-
direction="row"
183-
alignItems="center"
184-
spacing={1}
185-
justifyContent="flex-end"
186-
>
187-
<span
188-
css={{ whiteSpace: "nowrap", textOverflow: "ellipsis" }}
189-
>
163+
<UserIcon className="size-icon-sm -m-px" />
164+
</div>
165+
<div className="flex items-center gap-2">
166+
<span className="whitespace-nowrap">
190167
{dayjs(workspace.last_used_at).fromNow()}
191168
</span>
192169
<ClockIcon className="size-icon-xs" />
193-
</Stack>
194-
</Stack>
195-
</Stack>
170+
</div>
171+
</div>
172+
</div>
196173
</li>
197174
))}
198175
</ul>
199-
<Stack
200-
justifyContent="center"
201-
direction="row"
202-
wrap="wrap"
203-
css={{ gap: "6px 20px", fontSize: 14 }}
204-
>
205-
<Stack direction="row" alignItems="center" spacing={1}>
206-
<PersonIcon />
176+
<div className="flex flex-wrap justify-center gap-x-5 gap-y-1.5 text-sm">
177+
<div className="flex items-center gap-2">
178+
<UserIcon className="size-icon-sm -m-px" />
207179
<span>{ownersCount}</span>
208-
</Stack>
180+
</div>
209181
{mostRecent && (
210-
<Stack direction="row" alignItems="center" spacing={1}>
182+
<div className="flex items-center gap-2">
211183
<ClockIcon className="size-icon-xs" />
212184
<span>Last used {dayjs(mostRecent.last_used_at).fromNow()}</span>
213-
</Stack>
185+
</div>
214186
)}
215-
</Stack>
187+
</div>
216188
</>
217189
);
218190
};
@@ -233,66 +205,22 @@ const Resources: FC<StageProps> = ({ workspaces }) => {
233205
}
234206

235207
return (
236-
<Stack>
208+
<div className="flex flex-col gap-4">
237209
<p>
238210
Deleting{" "}
239211
{workspaces.length === 1 ? "this workspace" : "these workspaces"} will
240212
also permanently destroy&hellip;
241213
</p>
242-
<Stack
243-
direction="row"
244-
justifyContent="center"
245-
wrap="wrap"
246-
css={{ gap: "6px 20px", fontSize: 14 }}
247-
>
214+
<div className="flex flex-wrap justify-center gap-x-5 gap-y-1.5 text-sm">
248215
{Object.entries(resources).map(([type, summary]) => (
249-
<Stack key={type} direction="row" alignItems="center" spacing={1}>
250-
<ExternalImage
251-
src={summary.icon}
252-
width={styles.summaryIcon.width}
253-
height={styles.summaryIcon.height}
254-
/>
216+
<div key={type} className="flex items-center gap-2">
217+
<ExternalImage src={summary.icon} width={16} height={16} />
255218
<span>
256219
{summary.count} <code>{type}</code>
257220
</span>
258-
</Stack>
221+
</div>
259222
))}
260-
</Stack>
261-
</Stack>
223+
</div>
224+
</div>
262225
);
263226
};
264-
265-
const PersonIcon: FC = () => {
266-
// Using the Lucide icon with appropriate size class
267-
return <UserIcon className="size-icon-sm" css={{ margin: -1 }} />;
268-
};
269-
270-
const styles = {
271-
summaryIcon: { width: 16, height: 16 },
272-
273-
consequences: {
274-
display: "flex",
275-
flexDirection: "column",
276-
gap: 8,
277-
paddingLeft: 16,
278-
marginBottom: 0,
279-
},
280-
281-
workspacesList: (theme) => ({
282-
listStyleType: "none",
283-
padding: 0,
284-
border: `1px solid ${theme.palette.divider}`,
285-
borderRadius: 8,
286-
overflow: "hidden auto",
287-
maxHeight: 184,
288-
}),
289-
290-
workspace: (theme) => ({
291-
padding: "8px 16px",
292-
borderBottom: `1px solid ${theme.palette.divider}`,
293-
294-
"&:last-child": {
295-
border: "none",
296-
},
297-
}),
298-
} satisfies Record<string, Interpolation<Theme>>;

site/src/pages/WorkspacesPage/WorkspacesPageView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export const WorkspacesPageView: FC<WorkspacesPageViewProps> = ({
146146
disabled={isRunningBatchAction}
147147
variant="outline"
148148
size="sm"
149-
css={{ borderRadius: 9999, marginLeft: "auto" }}
149+
className="ml-auto"
150150
>
151151
Bulk actions
152152
<Spinner loading={isRunningBatchAction}>

0 commit comments

Comments
 (0)