Path: blob/main/components/dashboard/src/prebuilds/list/PrebuildListItem.tsx
2501 views
/**1* Copyright (c) 2024 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { FC, useMemo } from "react";7import { TextMuted } from "@podkit/typography/TextMuted";8import { Text } from "@podkit/typography/Text";9import { LinkButton } from "@podkit/buttons/LinkButton";10import { TableCell, TableRow } from "@podkit/tables/Table";11import type { Prebuild } from "@gitpod/public-api/lib/gitpod/v1/prebuild_pb";12import dayjs from "dayjs";13import { shortCommitMessage } from "../../projects/render-utils";14import { Link } from "react-router-dom";15import { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";16import { PrebuildStatus } from "../../projects/prebuild-utils";1718/**19* 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).20*/21const formatDate = (date: dayjs.Dayjs): string => {22if (date.isSame(dayjs(), "day")) {23return date.format("[Today at] h:mm A");24}2526if (date.isSame(dayjs(), "year")) {27return date.format("MMM D [at] h:mm A");28}2930return date.format("MMM D, YYYY");31};3233type Props = {34prebuild: Prebuild;35};36export const PrebuildListItem: FC<Props> = ({ prebuild }) => {37const triggeredDate = useMemo(() => dayjs(prebuild.status?.startTime?.toDate()), [prebuild.status?.startTime]);38const triggeredString = useMemo(() => formatDate(triggeredDate), [triggeredDate]);3940return (41<TableRow>42<TableCell>43<div className="flex flex-col gap-1 w-52">44<Text className="text-sm text-pk-content-primary text-semibold break-words">45<ConfigurationField46configuration={{ id: prebuild.configurationId, name: prebuild.configurationName }}47/>48</Text>49<TextMuted className="text-xs break-words">{prebuild.ref}</TextMuted>50</div>51</TableCell>5253<TableCell hideOnSmallScreen>54{prebuild.commit?.author && (55<div className="flex flex-col gap-1">56<Text className="text-sm text-pk-content-secondary">57{shortCommitMessage(prebuild.commit.message)}58</Text>59<div className="flex gap-1 items-center">60<img src={prebuild.commit.author.avatarUrl} className="w-5 h-5 rounded-full" alt="" />61<Text className="text-xs break-all text-pk-content-secondary">62{prebuild.commit.author.name}63</Text>64</div>65</div>66)}67</TableCell>6869<TableCell hideOnSmallScreen>70<Text className="text-sm break-all text-pk-content-secondary">71<time72dateTime={prebuild.status?.startTime?.toDate().toISOString()}73title={triggeredDate.toString()}74>75{triggeredString}76</time>77</Text>78</TableCell>7980<TableCell>81<PrebuildStatus prebuild={prebuild} classname="size-5" />82</TableCell>8384<TableCell>85<LinkButton href={`/prebuilds/${prebuild.id}`} disabled variant="secondary">86View87</LinkButton>88</TableCell>89</TableRow>90);91};9293type ConfigurationProps = {94configuration?: Pick<Configuration, "id" | "name">;95};96const ConfigurationField = ({ configuration }: ConfigurationProps) => {97if (!configuration?.name || !configuration.id) {98return <Text>Unknown repository</Text>;99}100101return <Link to={`/repositories/${configuration.id}`}>{configuration.name}</Link>;102};103104105