Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/prebuilds/detail/PrebuildTaskTab.tsx
2501 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 type { Prebuild } from "@gitpod/public-api/lib/gitpod/v1/prebuild_pb";
8
import { Suspense, memo, useEffect } from "react";
9
import { usePrebuildLogsEmitter } from "../../data/prebuilds/prebuild-logs-emitter";
10
import React from "react";
11
import { useToast } from "../../components/toasts/Toasts";
12
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
13
import { TabsContent } from "@podkit/tabs/Tabs";
14
import { PrebuildTaskErrorTab } from "./PrebuildTaskErrorTab";
15
import type { PlainMessage } from "@bufbuild/protobuf";
16
import { useHistory } from "react-router";
17
import { LoadingState } from "@podkit/loading/LoadingState";
18
19
const WorkspaceLogs = React.lazy(() => import("../../components/WorkspaceLogs"));
20
21
type Props = {
22
taskId: string;
23
prebuild: PlainMessage<Prebuild>;
24
};
25
export const PrebuildTaskTab = memo(({ taskId, prebuild }: Props) => {
26
const { emitter: logEmitter } = usePrebuildLogsEmitter(prebuild, taskId);
27
const [error, setError] = React.useState<ApplicationError | undefined>();
28
const { toast, dismissToast } = useToast();
29
const [activeToasts, setActiveToasts] = React.useState<Set<string>>(new Set());
30
const history = useHistory();
31
32
useEffect(() => {
33
const logErrorListener = async (err: ApplicationError) => {
34
if (err.code === ErrorCodes.NOT_FOUND) {
35
setError(err);
36
return;
37
}
38
39
const digest = await crypto.subtle.digest("sha256", new TextEncoder().encode(err.message + ":" + err.code));
40
const toastId = new TextDecoder().decode(digest);
41
toast("Fetching logs failed: " + err.message, { autoHide: false, id: toastId });
42
setActiveToasts((prev) => new Set(prev).add(toastId));
43
};
44
45
logEmitter.on("logs-error", logErrorListener);
46
47
return () => {
48
logEmitter.removeListener("logs-error", logErrorListener);
49
setError(undefined);
50
};
51
}, [logEmitter, taskId, toast]);
52
53
useEffect(() => {
54
// When navigating away from the page, dismiss all toasts
55
history.listen(() => {
56
activeToasts.forEach((toastId) => {
57
dismissToast(toastId);
58
});
59
});
60
// eslint-disable-next-line react-hooks/exhaustive-deps
61
}, []);
62
63
if (error) {
64
if (error.code === ErrorCodes.NOT_FOUND && taskId === "image-build") {
65
return (
66
<PrebuildTaskErrorTab taskId={taskId}>
67
<span className="flex justify-center items-center gap-2">
68
Pulling container image <LoadingState delay={false} size={16} />
69
</span>
70
</PrebuildTaskErrorTab>
71
);
72
}
73
74
return (
75
<PrebuildTaskErrorTab taskId={taskId}>
76
Logs of this prebuild task are inaccessible. Use <code>gp validate --prebuild --headless</code> in a
77
workspace to see logs and debug prebuild issues.{" "}
78
<a
79
href="https://www.gitpod.io/docs/configure/workspaces#validate-your-gitpod-configuration"
80
target="_blank"
81
rel="noreferrer noopener"
82
className="gp-link"
83
>
84
Learn more
85
</a>
86
.
87
</PrebuildTaskErrorTab>
88
);
89
}
90
91
return (
92
<TabsContent value={taskId} className="h-112 mt-0 border-pk-border-base">
93
<Suspense fallback={<div />}>
94
<WorkspaceLogs
95
key={prebuild.id + taskId}
96
classes="w-full h-full"
97
xtermClasses="absolute top-0 left-0 bottom-0 right-0 ml-6 my-0 mt-4"
98
taskId={taskId}
99
logsEmitter={logEmitter}
100
/>
101
</Suspense>
102
</TabsContent>
103
);
104
});
105
106