Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5953960

Browse files
committed
Apply PR reviews
1 parent 0ff39e5 commit 5953960

File tree

9 files changed

+146
-120
lines changed

9 files changed

+146
-120
lines changed

site/src/api/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ class ApiMethods {
12381238
};
12391239

12401240
cancelTemplateVersionBuild = async (
1241-
templateVersionId: TypesGen.TemplateVersion["id"],
1241+
templateVersionId: string,
12421242
): Promise<TypesGen.Response> => {
12431243
const response = await this.axios.patch(
12441244
`/api/v2/templateversions/${templateVersionId}/cancel`,
@@ -1248,7 +1248,7 @@ class ApiMethods {
12481248
};
12491249

12501250
cancelTemplateVersionDryRun = async (
1251-
templateVersionId: TypesGen.TemplateVersion["id"],
1251+
templateVersionId: string,
12521252
jobId: string,
12531253
): Promise<TypesGen.Response> => {
12541254
const response = await this.axios.patch(

site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { ProvisionerJob } from "api/typesGenerated";
22
import { Button } from "components/Button/Button";
3-
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
43
import {
54
Tooltip,
65
TooltipContent,
@@ -9,22 +8,25 @@ import {
98
} from "components/Tooltip/Tooltip";
109
import { BanIcon } from "lucide-react";
1110
import { type FC, useState } from "react";
11+
import { CancelJobConfirmationDialog } from "./CancelJobConfirmationDialog";
12+
13+
const CANCELLABLE = ["pending", "running"];
1214

1315
type CancelJobButtonProps = {
1416
job: ProvisionerJob;
1517
};
1618

1719
export const CancelJobButton: FC<CancelJobButtonProps> = ({ job }) => {
1820
const [isDialogOpen, setIsDialogOpen] = useState(false);
19-
const cancellable = ["pending", "running"].includes(job.status);
21+
const isCancellable = CANCELLABLE.includes(job.status);
2022

2123
return (
2224
<>
2325
<TooltipProvider>
2426
<Tooltip>
2527
<TooltipTrigger asChild>
2628
<Button
27-
disabled={!cancellable}
29+
disabled={!isCancellable}
2830
aria-label="Cancel job"
2931
size="icon"
3032
variant="outline"
@@ -39,16 +41,12 @@ export const CancelJobButton: FC<CancelJobButtonProps> = ({ job }) => {
3941
</Tooltip>
4042
</TooltipProvider>
4143

42-
<ConfirmDialog
43-
type="delete"
44-
onClose={(): void => {
44+
<CancelJobConfirmationDialog
45+
open={isDialogOpen}
46+
job={job}
47+
onClose={() => {
4548
setIsDialogOpen(false);
4649
}}
47-
open={isDialogOpen}
48-
title="Cancel provisioner job"
49-
description={`Are you sure you want to cancel the provisioner job "${job.id}"? This operation will result in the associated workspaces not getting created.`}
50-
confirmText="Confirm"
51-
cancelText="Discard"
5250
/>
5351
</>
5452
);

site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,16 @@ import {
44
provisionerJobQueryKey,
55
} from "api/queries/organizations";
66
import type { ProvisionerJob } from "api/typesGenerated";
7-
import {
8-
ConfirmDialog,
9-
type ConfirmDialogProps,
10-
} from "components/Dialogs/ConfirmDialog/ConfirmDialog";
7+
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
118
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
129
import type { FC } from "react";
1310
import { useMutation, useQueryClient } from "react-query";
1411

15-
type CancelJobConfirmationDialogProps = Omit<
16-
ConfirmDialogProps,
17-
| "type"
18-
| "title"
19-
| "description"
20-
| "confirmText"
21-
| "cancelText"
22-
| "onConfirm"
23-
| "confirmLoading"
24-
> & {
12+
type CancelJobConfirmationDialogProps = {
13+
open: boolean;
14+
onClose: () => void;
2515
job: ProvisionerJob;
26-
cancelProvisionerJob: typeof API.cancelProvisionerJob;
16+
cancelProvisionerJob?: typeof API.cancelProvisionerJob;
2717
};
2818

2919
export const CancelJobConfirmationDialog: FC<
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import type { FC, HTMLProps } from "react";
22
import { cn } from "utils/cn";
33

4-
export const DataGrid: FC<HTMLProps<HTMLDivElement>> = ({
4+
export const DataGrid: FC<HTMLProps<HTMLDListElement>> = ({
55
className,
66
...props
77
}) => {
88
return (
9-
<div
9+
<dl
1010
{...props}
1111
className={cn([
12-
"grid grid-cols-[auto_1fr] gap-x-4 items-center",
13-
"[&_span:nth-of-type(even)]:text-content-primary [&_span:nth-of-type(even)]:font-mono",
14-
"[&_span:nth-of-type(even)]:leading-[22px]",
12+
"m-0 grid grid-cols-[auto_1fr] gap-x-4 items-center",
13+
"[&_dt]:text-content-primary [&_dt]:font-mono [&_dt]:leading-[22px]",
1514
className,
1615
])}
1716
/>
@@ -22,7 +21,5 @@ export const DataGridSpace: FC<HTMLProps<HTMLDivElement>> = ({
2221
className,
2322
...props
2423
}) => {
25-
return (
26-
<div aria-hidden {...props} className={cn(["h-6 col-span-2", className])} />
27-
);
24+
return <div {...props} className={cn(["h-6 col-span-2", className])} />;
2825
};

site/src/pages/OrganizationSettingsPage/ProvisionersPage/JobStatusIndicator.tsx

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,50 @@ import {
1111
import { TriangleAlertIcon } from "lucide-react";
1212
import type { FC } from "react";
1313

14+
const variantByStatus: Record<
15+
ProvisionerJobStatus,
16+
StatusIndicatorProps["variant"]
17+
> = {
18+
succeeded: "success",
19+
failed: "failed",
20+
pending: "pending",
21+
running: "pending",
22+
canceling: "pending",
23+
canceled: "inactive",
24+
unknown: "inactive",
25+
};
26+
1427
type JobStatusIndicatorProps = {
15-
job: ProvisionerJob | ProvisionerDaemonJob;
28+
job: ProvisionerJob;
1629
};
1730

1831
export const JobStatusIndicator: FC<JobStatusIndicatorProps> = ({ job }) => {
19-
const isProvisionerJob = "queue_position" in job;
2032
return (
21-
<StatusIndicator size="sm" variant={statusIndicatorVariant(job.status)}>
33+
<StatusIndicator size="sm" variant={variantByStatus[job.status]}>
2234
<StatusIndicatorDot />
2335
<span className="[&:first-letter]:uppercase">{job.status}</span>
2436
{job.status === "failed" && (
2537
<TriangleAlertIcon className="size-icon-xs p-[1px]" />
2638
)}
27-
{job.status === "pending" &&
28-
isProvisionerJob &&
29-
`(${job.queue_position}/${job.queue_size})`}
39+
{job.status === "pending" && `(${job.queue_position}/${job.queue_size})`}
3040
</StatusIndicator>
3141
);
3242
};
3343

34-
function statusIndicatorVariant(
35-
status: ProvisionerJobStatus,
36-
): StatusIndicatorProps["variant"] {
37-
switch (status) {
38-
case "succeeded":
39-
return "success";
40-
case "failed":
41-
return "failed";
42-
case "pending":
43-
case "running":
44-
case "canceling":
45-
return "pending";
46-
case "canceled":
47-
case "unknown":
48-
return "inactive";
49-
}
50-
}
44+
type DaemonJobStatusIndicatorProps = {
45+
job: ProvisionerDaemonJob;
46+
};
47+
48+
export const DaemonJobStatusIndicator: FC<DaemonJobStatusIndicatorProps> = ({
49+
job,
50+
}) => {
51+
return (
52+
<StatusIndicator size="sm" variant={variantByStatus[job.status]}>
53+
<StatusIndicatorDot />
54+
<span className="[&:first-letter]:uppercase">{job.status}</span>
55+
{job.status === "failed" && (
56+
<TriangleAlertIcon className="size-icon-xs p-[1px]" />
57+
)}
58+
</StatusIndicator>
59+
);
60+
};

site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerDaemonsPage.tsx

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,26 @@ import { cn } from "utils/cn";
2424
import { docs } from "utils/docs";
2525
import { relativeTime } from "utils/time";
2626
import { DataGrid, DataGridSpace } from "./DataGrid";
27-
import { JobStatusIndicator } from "./JobStatusIndicator";
28-
import { ShrinkTags, Tag, Tags } from "./Tags";
27+
import { DaemonJobStatusIndicator } from "./JobStatusIndicator";
28+
import { TruncateTags, Tag, Tags } from "./Tags";
29+
import { Button } from "components/Button/Button";
2930

3031
type ProvisionerDaemonsPageProps = {
31-
org: Organization;
32+
orgId: string;
3233
};
3334

3435
export const ProvisionerDaemonsPage: FC<ProvisionerDaemonsPageProps> = ({
35-
org,
36+
orgId,
3637
}) => {
37-
const { data: daemons, isLoadingError } = useQuery({
38-
...provisionerDaemons(org.id),
38+
const {
39+
data: daemons,
40+
isLoadingError,
41+
refetch,
42+
} = useQuery({
43+
...provisionerDaemons(orgId),
3944
select: (data) =>
4045
data.toSorted((a, b) => {
46+
if (!a.last_seen_at && !b.last_seen_at) return 0;
4147
if (!a.last_seen_at) return 1;
4248
if (!b.last_seen_at) return -1;
4349
return (
@@ -49,6 +55,7 @@ export const ProvisionerDaemonsPage: FC<ProvisionerDaemonsPageProps> = ({
4955

5056
return (
5157
<section className="flex flex-col gap-8">
58+
<h2 className="sr-only">Provisioner daemons</h2>
5259
<p className="text-sm text-content-secondary m-0 mt-2">
5360
Coder server runs provisioner daemons which execute terraform during
5461
workspace and template builds.{" "}
@@ -85,7 +92,10 @@ export const ProvisionerDaemonsPage: FC<ProvisionerDaemonsPageProps> = ({
8592
) : isLoadingError ? (
8693
<TableRow>
8794
<TableCell colSpan={999}>
88-
<EmptyState message="Error loading the provisioner daemons" />
95+
<EmptyState
96+
message="Error loading the provisioner daemons"
97+
cta={<Button onClick={() => refetch()}>Retry</Button>}
98+
/>
8999
</TableCell>
90100
</TableRow>
91101
) : (
@@ -128,6 +138,7 @@ const DaemonRow: FC<DaemonRowProps> = ({ daemon }) => {
128138
) : (
129139
<ChevronRightIcon className="size-icon-sm p-0.5" />
130140
)}
141+
<span className="sr-only">({isOpen ? "Hide" : "Show more"})</span>
131142
<span className="[&:first-letter]:uppercase">
132143
{relativeTime(
133144
new Date(daemon.last_seen_at ?? new Date().toISOString()),
@@ -159,7 +170,7 @@ const DaemonRow: FC<DaemonRowProps> = ({ daemon }) => {
159170
)}
160171
</TableCell>
161172
<TableCell>
162-
<ShrinkTags tags={daemon.tags} />
173+
<TruncateTags tags={daemon.tags} />
163174
</TableCell>
164175
<TableCell>
165176
<StatusIndicator size="sm" variant={statusIndicatorVariant(daemon)}>
@@ -175,49 +186,49 @@ const DaemonRow: FC<DaemonRowProps> = ({ daemon }) => {
175186
<TableRow>
176187
<TableCell colSpan={999} className="p-4 border-t-0">
177188
<DataGrid>
178-
<span>Last seen:</span>
179-
<span>{daemon.last_seen_at}</span>
189+
<dt>Last seen:</dt>
190+
<dd>{daemon.last_seen_at}</dd>
180191

181-
<span>Creation time:</span>
182-
<span>{daemon.created_at}</span>
192+
<dt>Creation time:</dt>
193+
<dd>{daemon.created_at}</dd>
183194

184-
<span>Version:</span>
185-
<span>{daemon.version}</span>
195+
<dt>Version:</dt>
196+
<dd>{daemon.version}</dd>
186197

187-
<span>Tags:</span>
188-
<span>
198+
<dt>Tags:</dt>
199+
<dd>
189200
<Tags>
190201
{Object.entries(daemon.tags).map(([key, value]) => (
191202
<Tag key={key} label={key} value={value} />
192203
))}
193204
</Tags>
194-
</span>
205+
</dd>
195206

196207
{daemon.current_job && (
197208
<>
198209
<DataGridSpace />
199210

200-
<span>Last job:</span>
201-
<span>{daemon.current_job.id}</span>
211+
<dt>Last job:</dt>
212+
<dd>{daemon.current_job.id}</dd>
202213

203-
<span>Last job state:</span>
204-
<span>
205-
<JobStatusIndicator job={daemon.current_job} />
206-
</span>
214+
<dt>Last job state:</dt>
215+
<dd>
216+
<DaemonJobStatusIndicator job={daemon.current_job} />
217+
</dd>
207218
</>
208219
)}
209220

210221
{daemon.previous_job && (
211222
<>
212223
<DataGridSpace />
213224

214-
<span>Previous job:</span>
215-
<span>{daemon.previous_job.id}</span>
225+
<dt>Previous job:</dt>
226+
<dd>{daemon.previous_job.id}</dd>
216227

217-
<span>Previous job state:</span>
218-
<span>
219-
<JobStatusIndicator job={daemon.previous_job} />
220-
</span>
228+
<dt>Previous job state:</dt>
229+
<dd>
230+
<DaemonJobStatusIndicator job={daemon.previous_job} />
231+
</dd>
221232
</>
222233
)}
223234
</DataGrid>
@@ -240,8 +251,7 @@ function statusIndicatorVariant(
240251
return "success";
241252
case "busy":
242253
return "pending";
243-
case "offline":
244-
case null:
254+
default:
245255
return "inactive";
246256
}
247257
}
@@ -258,7 +268,7 @@ function statusLabel(daemon: ProvisionerDaemon) {
258268
return "Busy...";
259269
case "offline":
260270
return "Disconnected";
261-
case null:
271+
default:
262272
return "Unknown";
263273
}
264274
}

0 commit comments

Comments
 (0)