Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/projects/prebuild-utils.tsx
2500 views
1
/**
2
* Copyright (c) 2024 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { Prebuild, PrebuildPhase_Phase } from "@gitpod/public-api/lib/gitpod/v1/prebuild_pb";
8
import { PauseCircle, LucideProps, Clock, CheckCircle2, XCircle, Loader2Icon } from "lucide-react";
9
import type { ForwardRefExoticComponent } from "react";
10
import { cn } from "@podkit/lib/cn";
11
12
import StatusDone from "../icons/StatusDone.svg";
13
import StatusFailed from "../icons/StatusFailed.svg";
14
import StatusCanceled from "../icons/StatusCanceled.svg";
15
import StatusPaused from "../icons/StatusPaused.svg";
16
import StatusRunning from "../icons/StatusRunning.svg";
17
18
export function PrebuildStatus(p: { prebuild: Prebuild | undefined; classname?: string }) {
19
const prebuild = p.prebuild;
20
21
const { className: iconColorClass, label } = prebuildDisplayProps(prebuild);
22
const PrebuildStatusIcon = prebuildStatusIconComponent(prebuild);
23
return (
24
<div className="flex flex-row gap-1.5 items-center capitalize">
25
<PrebuildStatusIcon className={cn(p.classname, iconColorClass)} />
26
<span>{label}</span>
27
</div>
28
);
29
}
30
31
export function PrebuildStatusOld(props: { prebuild: Prebuild | undefined }) {
32
const prebuild = props.prebuild;
33
34
return (
35
<div className="flex flex-col space-y-1 justify-center text-sm font-semibold">
36
<div>
37
<div className="flex space-x-1 items-center">
38
{prebuildStatusIcon(prebuild)}
39
{prebuildStatusLabel(prebuild)}
40
</div>
41
</div>
42
<div className="flex space-x-1 items-center text-gray-400">
43
<span className="text-left">{getPrebuildStatusDescription(prebuild)}</span>
44
</div>
45
</div>
46
);
47
}
48
49
const prebuildDisplayProps = (prebuild: Prebuild | undefined): { className: string; label: string } => {
50
switch (prebuild?.status?.phase?.name) {
51
case undefined: // Fall through
52
case PrebuildPhase_Phase.UNSPECIFIED: // Fall through
53
case PrebuildPhase_Phase.QUEUED:
54
return { className: "text-orange-500", label: "pending" };
55
case PrebuildPhase_Phase.BUILDING:
56
return { className: "text-blue-500", label: "running" };
57
case PrebuildPhase_Phase.ABORTED:
58
return { className: "text-gray-500", label: "cancelled" };
59
case PrebuildPhase_Phase.FAILED:
60
return { className: "text-red-500", label: "error" };
61
case PrebuildPhase_Phase.TIMEOUT:
62
return { className: "text-red-500", label: "timeout" };
63
case PrebuildPhase_Phase.AVAILABLE:
64
if (prebuild.status?.message) {
65
return { className: "text-red-500", label: "failed" };
66
}
67
return { className: "text-green-500", label: "ready" };
68
}
69
70
return { className: "", label: "" };
71
};
72
73
export const prebuildStatusLabel = (prebuild: Prebuild | undefined): JSX.Element => {
74
const { className, label } = prebuildDisplayProps(prebuild);
75
return <span className={`font-medium ${className} uppercase`}>{label}</span>;
76
};
77
78
const prebuildStatusIconComponent = (prebuild: Prebuild | undefined): ForwardRefExoticComponent<LucideProps> => {
79
switch (prebuild?.status?.phase?.name) {
80
case PrebuildPhase_Phase.UNSPECIFIED: // Fall through
81
case PrebuildPhase_Phase.QUEUED:
82
return PauseCircle;
83
case PrebuildPhase_Phase.BUILDING:
84
return Clock;
85
case PrebuildPhase_Phase.ABORTED:
86
case PrebuildPhase_Phase.TIMEOUT:
87
case PrebuildPhase_Phase.FAILED:
88
return XCircle;
89
case PrebuildPhase_Phase.AVAILABLE:
90
if (prebuild?.status?.message) {
91
return XCircle;
92
}
93
return CheckCircle2;
94
}
95
96
return XCircle;
97
};
98
99
export const prebuildStatusIcon = (prebuild?: Prebuild) => {
100
if (!prebuild) {
101
return <Loader2Icon size={20} className="text-gray-500 animate-spin" />;
102
}
103
104
switch (prebuild?.status?.phase?.name) {
105
case PrebuildPhase_Phase.UNSPECIFIED: // Fall through
106
case PrebuildPhase_Phase.QUEUED:
107
return <img alt="" className="h-4 w-4" src={StatusPaused} />;
108
case PrebuildPhase_Phase.BUILDING:
109
return <img alt="" className="h-4 w-4" src={StatusRunning} />;
110
case PrebuildPhase_Phase.ABORTED:
111
return <img alt="" className="h-4 w-4" src={StatusCanceled} />;
112
case PrebuildPhase_Phase.FAILED:
113
return <img alt="" className="h-4 w-4" src={StatusFailed} />;
114
case PrebuildPhase_Phase.TIMEOUT:
115
return <img alt="" className="h-4 w-4" src={StatusFailed} />;
116
case PrebuildPhase_Phase.AVAILABLE:
117
if (prebuild?.status?.message) {
118
return <img alt="" className="h-4 w-4" src={StatusFailed} />;
119
}
120
return <img alt="" className="h-4 w-4" src={StatusDone} />;
121
}
122
};
123
124
const getPrebuildStatusDescription = (prebuild: Prebuild | undefined): string => {
125
switch (prebuild?.status?.phase?.name) {
126
case PrebuildPhase_Phase.QUEUED:
127
return `Prebuild is queued and will be processed when there is execution capacity.`;
128
case PrebuildPhase_Phase.BUILDING:
129
return `Prebuild is currently in progress.`;
130
case PrebuildPhase_Phase.ABORTED:
131
return `Prebuild has been cancelled. Either a newer commit was pushed to the same branch, a user cancelled it manually, or the prebuild rate limit has been exceeded. ${
132
prebuild.status?.message || ""
133
}`;
134
case PrebuildPhase_Phase.FAILED:
135
return `Prebuild failed for system reasons. Please contact support. ${prebuild.status?.message || ""}`;
136
case PrebuildPhase_Phase.TIMEOUT:
137
return `Prebuild timed out. Either the image, or the prebuild tasks took too long. ${
138
prebuild.status?.message || ""
139
}`;
140
case PrebuildPhase_Phase.AVAILABLE:
141
if (prebuild.status?.message) {
142
return `The tasks executed in the prebuild returned a non-zero exit code. ${prebuild.status.message}`;
143
}
144
return `Prebuild completed successfully.`;
145
default:
146
return `Unknown prebuild status.`;
147
}
148
};
149
150