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