Skip to content

Commit e4fe07a

Browse files
committed
Deployment instances section new statuses
1 parent a2fc78a commit e4fe07a

File tree

3 files changed

+80
-40
lines changed

3 files changed

+80
-40
lines changed

src/components/deployment/deployment-card.tsx

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ export default function DeploymentCard({
8989
deployment.status === "active" ||
9090
deployment.status === "removed";
9191

92+
const temporarilyHideInstances =
93+
showInstances &&
94+
(deployment?.status === "build-pending" || deployment?.status === "build-queued");
95+
9296
return (
9397
<div
9498
{...rest}
@@ -114,21 +118,25 @@ export default function DeploymentCard({
114118
className="group-data-placeholder/card:bg-foreground group-data-placeholder/card:animate-skeleton size-6 group-data-placeholder/card:rounded-full group-data-placeholder/card:text-transparent"
115119
/>
116120
</div>
117-
<div className="mt-1.5 flex min-w-0 flex-1 flex-col items-start gap-1.25 pr-2 pb-0.5 sm:mt-0 sm:pl-3">
118-
<div className="flex w-full flex-col items-start justify-start gap-0.5">
119-
<p
120-
data-no-title={titleNotFound ? true : undefined}
121-
className="data-no-title:bg-border data-no-title:text-muted-foreground group-data-placeholder/card:bg-foreground group-data-placeholder/card:animate-skeleton max-w-full min-w-0 shrink leading-tight group-data-placeholder/card:rounded-md group-data-placeholder/card:text-transparent data-no-title:-my-0.25 data-no-title:rounded data-no-title:px-1.5 data-no-title:py-0.25"
122-
>
123-
{title}
124-
</p>
121+
<div className="mt-1.5 flex min-w-0 flex-1 flex-col items-start gap-2 pr-2 pb-0.5 sm:mt-0 sm:pl-3">
122+
<div className="flex w-full flex-col gap-1 pb-0.5">
123+
<div className="flex w-full flex-col items-start justify-start">
124+
<p
125+
data-no-title={titleNotFound ? true : undefined}
126+
className="data-no-title:bg-border data-no-title:text-muted-foreground group-data-placeholder/card:bg-foreground group-data-placeholder/card:animate-skeleton max-w-full min-w-0 shrink leading-tight group-data-placeholder/card:rounded-md group-data-placeholder/card:text-transparent data-no-title:-my-0.25 data-no-title:rounded data-no-title:px-1.5 data-no-title:py-0.25"
127+
>
128+
{title}
129+
</p>
130+
</div>
131+
{isPlaceholder ? (
132+
<DeploymentInfo isPlaceholder={true} service={service} />
133+
) : (
134+
<DeploymentInfo deployment={deployment} service={service} />
135+
)}
125136
</div>
126-
{isPlaceholder ? (
127-
<DeploymentInfo isPlaceholder={true} service={service} />
128-
) : (
129-
<DeploymentInfo deployment={deployment} service={service} />
137+
{!temporarilyHideInstances && showInstances && (
138+
<DeploymentInstances isPending={isPlaceholder} />
130139
)}
131-
{showInstances && <DeploymentInstances className="mt-1" forcePending={isPlaceholder} />}
132140
</div>
133141
</button>
134142
<div className="absolute top-1 right-1 shrink-0 sm:top-1/2 sm:right-2 sm:-translate-y-1/2">
@@ -554,7 +562,7 @@ function DeploymentInfo({ deployment, service, isPlaceholder, className }: TDepl
554562
</p>
555563
<div className="flex max-w-full min-w-0 shrink gap-0.5 space-x-1.5">
556564
{deployment?.git_branch !== undefined && deployment.git_branch !== "" && (
557-
<span className="text-muted-more-foreground hidden leading-tight lg:inline-block">
565+
<span className="text-muted-more-foreground hidden leading-tight first:hidden lg:inline-block lg:first:inline-block">
558566
|
559567
</span>
560568
)}
@@ -565,7 +573,9 @@ function DeploymentInfo({ deployment, service, isPlaceholder, className }: TDepl
565573
</p>
566574
)}
567575
{deployment?.commit_sha !== undefined && deployment.commit_sha !== "" && (
568-
<span className="text-muted-more-foreground leading-tight">|</span>
576+
<span className="text-muted-more-foreground leading-tight first:hidden lg:first:inline-block">
577+
|
578+
</span>
569579
)}
570580
{deployment?.commit_sha !== undefined && deployment.commit_sha !== "" && (
571581
<p className="text-muted-foreground max-w-full min-w-0 shrink leading-tight">
@@ -574,10 +584,7 @@ function DeploymentInfo({ deployment, service, isPlaceholder, className }: TDepl
574584
</p>
575585
)}
576586
{durationStr !== undefined && durationStr !== "" && (
577-
<span
578-
data-has-prev={deployment?.commit_sha || deployment?.git_branch ? true : undefined}
579-
className="text-muted-more-foreground hidden leading-tight data-has-prev:inline-block lg:inline-block data-has-prev:lg:inline-block"
580-
>
587+
<span className="text-muted-more-foreground leading-tight first:hidden lg:inline-block lg:first:inline-block">
581588
|
582589
</span>
583590
)}

src/components/deployment/deployment-instances.tsx

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,43 @@ import {
1414

1515
type TProps = {
1616
className?: string;
17-
forcePending?: boolean;
17+
isPending?: boolean;
1818
};
1919

20-
export default function DeploymentInstances({ forcePending, className }: TProps) {
20+
export default function DeploymentInstances({ isPending: isPendingProp, className }: TProps) {
2121
const { data, isPending, error } = useInstanceHealth();
2222

23-
if (isPending || forcePending)
23+
if (isPending || isPendingProp) {
2424
return (
25-
<div className={cn("flex w-full flex-wrap gap-1", className)}>
26-
<div className="bg-background border-muted-foreground/12 relative z-0 flex overflow-hidden rounded-md border">
27-
<div className="p-1">
25+
<div className={cn("flex w-full flex-wrap gap-1.5", className)}>
26+
<div className="bg-background border-muted-foreground/16 relative z-0 flex overflow-hidden rounded-md border">
27+
<IconWrapper>
2828
<div className="bg-muted-foreground animate-skeleton size-3.5 rounded-full" />
29-
</div>
30-
<div className="bg-muted-foreground/12 w-px self-stretch" />
31-
<div className="bg-muted-foreground/6 p-1">
29+
</IconWrapper>
30+
<div className="bg-muted-foreground/16 w-px self-stretch" />
31+
<IconWrapper className="bg-muted-foreground/6">
3232
<div className="bg-muted-foreground animate-skeleton size-3.5 rounded-full" />
33-
</div>
33+
</IconWrapper>
3434
</div>
3535
</div>
3636
);
37+
}
38+
3739
if (data) {
40+
if (data.data.instances.length === 0) return null;
41+
const orderedInstances = data.data.instances.sort((a, b) => {
42+
return statusOrder.indexOf(a.status) - statusOrder.indexOf(b.status);
43+
});
44+
3845
return (
39-
<div className={cn("flex w-full flex-wrap gap-1", className)}>
40-
{data.data.instances.map((instance, i) => (
46+
<div className={cn("flex w-full flex-wrap gap-1.5", className)}>
47+
{orderedInstances.map((instance, i) => (
4148
<Instance key={i} instance={instance} />
4249
))}
4350
</div>
4451
);
4552
}
53+
4654
if (error) {
4755
return (
4856
<div className="flex w-full justify-start">
@@ -62,21 +70,25 @@ function Instance({ instance }: { instance: TInstanceFromHealth }) {
6270
return (
6371
<div
6472
data-status={instance?.status}
65-
className="bg-background data-[status=waiting]:border-warning/16 data-[status=starting]:border-process/16 data-[status=not_ready]:border-process/16 data-[status=running]:border-success/16 data-[status=crashing]:border-destructive/16 group/div relative z-0 flex overflow-hidden rounded-md border"
73+
className="bg-background data-[status=waiting]:border-warning/20 data-[status=starting]:border-process/20 data-[status=not_ready]:border-process/20 data-[status=running]:border-success/20 data-[status=crashing]:border-destructive/20 group/div relative z-0 flex overflow-hidden rounded-md border"
6674
>
67-
<div className="p-1">
75+
<IconWrapper>
6876
<ServerIcon className="text-muted-foreground size-3.5" />
69-
</div>
70-
<div className="bg-border group-data-[status=waiting]/div:bg-warning/16 group-data-[status=starting]/div:bg-process/16 group-data-[status=not_ready]/div:bg-process/16 group-data-[status=running]/div:bg-success/16 group-data-[status=crashing]/div:bg-destructive/16 w-px self-stretch" />
71-
<div className="group-data-[status=waiting]/div:bg-warning/8 group-data-[status=starting]/div:bg-process/8 group-data-[status=not_ready]/div:bg-process/8 group-data-[status=running]/div:bg-success/8 group-data-[status=crashing]/div:bg-destructive/8 p-1">
77+
</IconWrapper>
78+
<div className="bg-border group-data-[status=waiting]/div:bg-warning/20 group-data-[status=starting]/div:bg-process/20 group-data-[status=not_ready]/div:bg-process/20 group-data-[status=running]/div:bg-success/20 group-data-[status=crashing]/div:bg-destructive/20 w-px self-stretch" />
79+
<IconWrapper className="group-data-[status=waiting]/div:bg-warning/8 group-data-[status=starting]/div:bg-process/8 group-data-[status=not_ready]/div:bg-process/8 group-data-[status=running]/div:bg-success/8 group-data-[status=crashing]/div:bg-destructive/8">
7280
<div className="size-3.5 shrink-0">
7381
<Indicator instance={instance} />
7482
</div>
75-
</div>
83+
</IconWrapper>
7684
</div>
7785
);
7886
}
7987

88+
function IconWrapper({ className, children }: { className?: string; children: React.ReactNode }) {
89+
return <div className={cn("p-1.25", className)}>{children}</div>;
90+
}
91+
8092
function Indicator({ instance }: { instance: TInstanceFromHealth }) {
8193
if (instance.status === "waiting") {
8294
return <HourglassIcon className="text-warning animate-hourglass size-full" />;
@@ -90,8 +102,27 @@ function Indicator({ instance }: { instance: TInstanceFromHealth }) {
90102
if (instance.status === "crashing") {
91103
return <TriangleAlertIcon className="text-destructive size-full" />;
92104
}
105+
if (instance.status === "image_pull_error") {
106+
return <TriangleAlertIcon className="text-destructive size-full" />;
107+
}
108+
if (instance.status === "terminating") {
109+
return (
110+
<CircleSlashIcon className="text-muted-foreground size-full animate-spin duration-2000" />
111+
);
112+
}
93113
if (instance.status === "terminated") {
94114
return <CircleSlashIcon className="text-muted-foreground size-full" />;
95115
}
96-
return <CircleHelpIcon className="text-foreground size-full" />;
116+
return <CircleHelpIcon className="text-muted-foreground size-full" />;
97117
}
118+
119+
const statusOrder: TInstanceFromHealth["status"][] = [
120+
"crashing",
121+
"image_pull_error",
122+
"running",
123+
"starting",
124+
"not_ready",
125+
"waiting",
126+
"terminating",
127+
"terminated",
128+
];

src/server/go/client.gen.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ export const ContainerStateSchema = z.enum([
6767
'running',
6868
'waiting',
6969
'terminated',
70+
'terminating',
7071
'crashing',
7172
'not_ready',
72-
'oom_killed',
7373
'image_pull_error',
7474
'starting',
7575
]);
@@ -852,12 +852,13 @@ export const GetEnvironmentOutputBodySchema = z
852852
})
853853
.strip();
854854

855-
export const InstanceHealthSchema = z.enum(['pending', 'crashing', 'active']);
855+
export const InstanceHealthSchema = z.enum(['pending', 'crashing', 'active', 'terminating']);
856856

857857
export const SimpleInstanceStatusSchema = z
858858
.object({
859859
events: z.array(EventRecordSchema).optional(),
860860
kubernetes_name: z.string(),
861+
restart_count: z.number(),
861862
status: ContainerStateSchema,
862863
})
863864
.strip();
@@ -1444,6 +1445,7 @@ export const PodContainerStatusSchema = z
14441445
has_crashing_instances: z.boolean(),
14451446
instance_dependencies: z.array(InstanceStatusSchema),
14461447
instances: z.array(InstanceStatusSchema),
1448+
is_terminating: z.boolean(),
14471449
kubernetes_name: z.string(),
14481450
namespace: z.string(),
14491451
phase: PodPhaseSchema,

0 commit comments

Comments
 (0)