import { css, cx } from '@emotion/css';
import React from 'react';
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 (
Name |
Expires |
Created |
Last used at |
|
|
{tokens.map((key) => {
return (
{key.name} |
|
{formatDate(timeZone, key.created)} |
{formatLastUsedAtDate(timeZone, key.lastUsedAt)} |
{key.isRevoked && Revoked}
|
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}`;
}
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`
margin-left: ${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`
margin-bottom: ${theme.spacing(4)};
`,
});