import { css, cx } from '@emotion/css'; import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data'; import { DeleteButton, Icon, Tooltip, useStyles2, useTheme2 } from '@grafana/ui'; import { ApiKey } from 'app/types'; interface Props { tokens: ApiKey[]; timeZone: TimeZone; tokenActionsDisabled?: boolean; onDelete: (token: ApiKey) => void; } export const ServiceAccountTokensTable = ({ tokens, timeZone, tokenActionsDisabled, onDelete }: Props): JSX.Element => { const theme = useTheme2(); const styles = getStyles(theme); return ( {tokens.map((key) => { return ( ); })}
Name Expires Created Last used at
{key.name} {formatDate(timeZone, key.created)} {formatLastUsedAtDate(timeZone, key.lastUsedAt)} {key.isRevoked && } onDelete(key)} disabled={tokenActionsDisabled} />
); }; function formatLastUsedAtDate(timeZone: TimeZone, lastUsedAt?: string): string { if (!lastUsedAt) { return 'Never'; } return dateTimeFormat(lastUsedAt, { timeZone }); } function formatDate(timeZone: TimeZone, expiration?: string): string { if (!expiration) { return 'No expiration date'; } return dateTimeFormat(expiration, { timeZone }); } function formatSecondsLeftUntilExpiration(secondsUntilExpiration: number): string { const days = Math.ceil(secondsUntilExpiration / (3600 * 24)); const daysFormat = days > 1 ? `${days} days` : `${days} day`; return `Expires in ${daysFormat}`; } const TokenRevoked = () => { const styles = useStyles2(getStyles); return ( Revoked ); }; interface TokenExpirationProps { timeZone: TimeZone; token: ApiKey; } const TokenExpiration = ({ timeZone, token }: TokenExpirationProps) => { const styles = useStyles2(getStyles); if (!token.expiration) { return Never; } if (token.secondsUntilExpiration) { return ( {formatSecondsLeftUntilExpiration(token.secondsUntilExpiration)} ); } if (token.hasExpired) { return ( Expired ); } return {formatDate(timeZone, token.expiration)}; }; const getStyles = (theme: GrafanaTheme2) => ({ tableRow: (hasExpired: boolean | undefined) => css({ color: hasExpired ? theme.colors.text.secondary : theme.colors.text.primary, }), tooltipContainer: css({ marginLeft: theme.spacing(1), }), toolTipIcon: css({ color: theme.colors.error.text, }), secondsUntilExpiration: css({ color: theme.colors.warning.text, }), hasExpired: css({ color: theme.colors.error.text, }), neverExpire: css({ color: theme.colors.text.secondary, }), section: css({ marginBottom: theme.spacing(4), }), });