Path: blob/main/components/dashboard/src/insights/WorkspaceSessionGroup.tsx
2500 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 { Timestamp } from "@bufbuild/protobuf";7import { WorkspaceSession, WorkspaceSpec_WorkspaceType } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";8import { AccordionContent, AccordionItem, AccordionTrigger } from "../components/accordion/Accordion";9import { ReactComponent as UsageIcon } from "../images/usage-default.svg";10import { toRemoteURL } from "../projects/render-utils";11import { DisplayName } from "../usage/UsageEntry";12import { WorkspaceSessionEntry } from "./WorkspaceSession";13import { displayWorkspaceType } from "./download/download-sessions";1415type Props = {16id: string;17sessions: WorkspaceSession[];18};19export const WorkspaceSessionGroup = ({ id, sessions }: Props) => {20if (!sessions?.length) {21return null;22}23const { workspace, owner } = sessions[0];2425return (26<AccordionItem key={id} value={id}>27<div className="w-full p-3 grid grid-cols-12 gap-x-3 justify-between transition ease-in-out rounded-xl">28<div className="flex flex-col col-span-2 my-auto">29<span className="text-pk-content-primary text-md font-medium capitalize">30{displayWorkspaceType(workspace?.spec?.type)}31</span>32<span className="text-sm text-pk-content-tertiary">33{workspace?.spec?.class ? <DisplayName workspaceClass={workspace?.spec?.class} /> : "n/a"}34</span>35</div>36<div className="flex flex-col col-span-5 my-auto">37<div className="flex">38<span className="truncate text-pk-content-primary text-md font-medium">{workspace?.id}</span>39</div>40<span className="text-sm truncate text-pk-content-secondary">41{workspace?.metadata?.originalContextUrl && toRemoteURL(workspace.metadata.originalContextUrl)}42</span>43</div>44<div className="flex flex-col col-span-3 my-auto">45<span className="text-right text-pk-content-secondary font-medium">46{workspace?.spec?.type === WorkspaceSpec_WorkspaceType.PREBUILD ? (47<div className="flex">48<UsageIcon className="my-auto w-4 h-4 mr-1" />49<span className="text-sm">Gitpod</span>50</div>51) : (52<div className="flex">53<img54className="my-auto rounded-full w-4 h-4 inline-block align-text-bottom mr-1 overflow-hidden"55src={owner?.avatarUrl ?? ""}56alt=""57/>58<span className="text-sm">{owner?.name}</span>59</div>60)}61</span>62</div>63<div className="flex flex-col col-span-2 my-auto">64<AccordionTrigger className="w-full">65<span className="text-pk-content-primary truncate font-medium">{sessions.length}</span>66</AccordionTrigger>67</div>68</div>69<AccordionContent>70<div className="px-3 py-2 space-y-2">71<h4 className="text-sm font-medium text-pk-content-primary">Workspace starts:</h4>72<ul className="space-y-1">73{sessions.map((session) => (74<WorkspaceSessionEntry key={session.id} session={session} />75))}76</ul>77</div>78</AccordionContent>79</AccordionItem>80);81};8283export const displayTime = (time: Timestamp) => {84const options: Intl.DateTimeFormatOptions = {85day: "numeric",86month: "short",87year: "numeric",88hour: "numeric",89minute: "numeric",90};9192return time.toDate().toLocaleDateString(undefined, options).replace("at ", "");93};949596