Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/prebuilds/list/PrebuildListItem.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 { FC, useMemo } from "react";
8
import { TextMuted } from "@podkit/typography/TextMuted";
9
import { Text } from "@podkit/typography/Text";
10
import { LinkButton } from "@podkit/buttons/LinkButton";
11
import { TableCell, TableRow } from "@podkit/tables/Table";
12
import type { Prebuild } from "@gitpod/public-api/lib/gitpod/v1/prebuild_pb";
13
import dayjs from "dayjs";
14
import { shortCommitMessage } from "../../projects/render-utils";
15
import { Link } from "react-router-dom";
16
import { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
17
import { PrebuildStatus } from "../../projects/prebuild-utils";
18
19
/**
20
* Formats a date. For today, it returns the time. For this year, it returns the month, day and time. Otherwise, it returns the full date (month, day, year).
21
*/
22
const formatDate = (date: dayjs.Dayjs): string => {
23
if (date.isSame(dayjs(), "day")) {
24
return date.format("[Today at] h:mm A");
25
}
26
27
if (date.isSame(dayjs(), "year")) {
28
return date.format("MMM D [at] h:mm A");
29
}
30
31
return date.format("MMM D, YYYY");
32
};
33
34
type Props = {
35
prebuild: Prebuild;
36
};
37
export const PrebuildListItem: FC<Props> = ({ prebuild }) => {
38
const triggeredDate = useMemo(() => dayjs(prebuild.status?.startTime?.toDate()), [prebuild.status?.startTime]);
39
const triggeredString = useMemo(() => formatDate(triggeredDate), [triggeredDate]);
40
41
return (
42
<TableRow>
43
<TableCell>
44
<div className="flex flex-col gap-1 w-52">
45
<Text className="text-sm text-pk-content-primary text-semibold break-words">
46
<ConfigurationField
47
configuration={{ id: prebuild.configurationId, name: prebuild.configurationName }}
48
/>
49
</Text>
50
<TextMuted className="text-xs break-words">{prebuild.ref}</TextMuted>
51
</div>
52
</TableCell>
53
54
<TableCell hideOnSmallScreen>
55
{prebuild.commit?.author && (
56
<div className="flex flex-col gap-1">
57
<Text className="text-sm text-pk-content-secondary">
58
{shortCommitMessage(prebuild.commit.message)}
59
</Text>
60
<div className="flex gap-1 items-center">
61
<img src={prebuild.commit.author.avatarUrl} className="w-5 h-5 rounded-full" alt="" />
62
<Text className="text-xs break-all text-pk-content-secondary">
63
{prebuild.commit.author.name}
64
</Text>
65
</div>
66
</div>
67
)}
68
</TableCell>
69
70
<TableCell hideOnSmallScreen>
71
<Text className="text-sm break-all text-pk-content-secondary">
72
<time
73
dateTime={prebuild.status?.startTime?.toDate().toISOString()}
74
title={triggeredDate.toString()}
75
>
76
{triggeredString}
77
</time>
78
</Text>
79
</TableCell>
80
81
<TableCell>
82
<PrebuildStatus prebuild={prebuild} classname="size-5" />
83
</TableCell>
84
85
<TableCell>
86
<LinkButton href={`/prebuilds/${prebuild.id}`} disabled variant="secondary">
87
View
88
</LinkButton>
89
</TableCell>
90
</TableRow>
91
);
92
};
93
94
type ConfigurationProps = {
95
configuration?: Pick<Configuration, "id" | "name">;
96
};
97
const ConfigurationField = ({ configuration }: ConfigurationProps) => {
98
if (!configuration?.name || !configuration.id) {
99
return <Text>Unknown repository</Text>;
100
}
101
102
return <Link to={`/repositories/${configuration.id}`}>{configuration.name}</Link>;
103
};
104
105