Path: blob/main/components/dashboard/src/user-settings/TokenEntry.tsx
2500 views
/**1* Copyright (c) 2022 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 { PersonalAccessToken } from "@gitpod/public-api/lib/gitpod/experimental/v1/tokens_pb";7import dayjs from "dayjs";8import { ContextMenuEntry } from "../components/ContextMenu";9import { ItemFieldContextMenu } from "../components/ItemsList";10import Tooltip from "../components/Tooltip";11import { ReactComponent as ExclamationIcon } from "../images/exclamation.svg";12import { ReactComponent as WarningIcon } from "../images/exclamation2.svg";13import { AllPermissions, isNeverExpired } from "./PersonalAccessTokens";14import { useMemo } from "react";1516interface TokenEntryProps {17token: PersonalAccessToken;18menuEntries: ContextMenuEntry[];19}2021function TokenEntry(props: TokenEntryProps) {22const expiredInfo = useMemo(() => {23const expiration = props.token.expirationTime!.toDate();24if (isNeverExpired(expiration)) {25return {26expired: false,27content: "Never expires!",28tooltip: {29content: "The token will never expire!",30icon: <WarningIcon className="h-4 w-4" />,31},32};33}34const expirationTime = dayjs(expiration);35const expired = expirationTime.isBefore(dayjs());36return {37expired,38content: expirationTime.format("MMM D, YYYY"),39tooltip: expired40? {41content: expirationTime.format("MMM D, YYYY, hh:mm A"),42icon: <ExclamationIcon fill="#D97706" className="h-4 w-4" />,43}44: undefined,45};46}, [props.token.expirationTime]);4748const getScopes = () => {49if (!props.token.scopes) {50return "";51}52const permissions = AllPermissions.filter((e) => e.scopes.every((v) => props.token.scopes.includes(v)));53if (permissions.length > 0) {54return permissions.map((e) => e.name).join("\n");55} else {56return "No access";57}58};5960return (61<div className="rounded-xl whitespace-nowrap flex space-x-2 py-4 px-4 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-kumquat-light group">62<div className="flex items-center pr-3 w-4/12">63<span className="truncate">{props.token.name || ""}</span>64</div>65<div className="flex items-center w-4/12 text-gray-400 font-medium">66<span className="truncate whitespace-pre-line">{getScopes()}</span>67</div>68<div className="flex items-center w-3/12 text-gray-400">69<span className={"flex items-center gap-2 truncate" + (expiredInfo.expired ? " text-orange-600" : "")}>70{expiredInfo.tooltip && (71<Tooltip content={expiredInfo.tooltip.content}>{expiredInfo.tooltip.icon}</Tooltip>72)}73<span>{expiredInfo.content}</span>74</span>75</div>76<div className="flex items-center justify-end w-1/12">77<ItemFieldContextMenu menuEntries={props.menuEntries} />78</div>79</div>80);81}8283export default TokenEntry;848586