2022-04-22 08:33:13 -05:00
|
|
|
import { css } from '@emotion/css';
|
2021-03-04 06:20:38 -06:00
|
|
|
import React, { FC } from 'react';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2021-12-16 05:46:09 -06:00
|
|
|
import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data';
|
2022-09-06 03:15:36 -05:00
|
|
|
import { Button, DeleteButton, HorizontalGroup, Icon, Tooltip, useTheme2 } from '@grafana/ui';
|
2022-04-29 08:30:24 -05:00
|
|
|
import { contextSrv } from 'app/core/core';
|
|
|
|
import { AccessControlAction } from 'app/types';
|
2021-03-04 06:20:38 -06:00
|
|
|
|
|
|
|
import { ApiKey } from '../../types';
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
apiKeys: ApiKey[];
|
|
|
|
timeZone: TimeZone;
|
|
|
|
onDelete: (apiKey: ApiKey) => void;
|
2022-06-15 07:59:40 -05:00
|
|
|
onMigrate: (apiKey: ApiKey) => void;
|
2021-03-04 06:20:38 -06:00
|
|
|
}
|
|
|
|
|
2022-06-15 07:59:40 -05:00
|
|
|
export const ApiKeysTable: FC<Props> = ({ apiKeys, timeZone, onDelete, onMigrate }) => {
|
2021-12-16 05:46:09 -06:00
|
|
|
const theme = useTheme2();
|
|
|
|
const styles = getStyles(theme);
|
|
|
|
|
2021-03-04 06:20:38 -06:00
|
|
|
return (
|
|
|
|
<table className="filter-table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>Role</th>
|
|
|
|
<th>Expires</th>
|
|
|
|
<th style={{ width: '34px' }} />
|
|
|
|
</tr>
|
|
|
|
</thead>
|
2022-04-29 08:30:24 -05:00
|
|
|
{apiKeys.length > 0 ? (
|
2021-03-04 06:20:38 -06:00
|
|
|
<tbody>
|
|
|
|
{apiKeys.map((key) => {
|
2021-12-16 05:46:09 -06:00
|
|
|
const isExpired = Boolean(key.expiration && Date.now() > new Date(key.expiration).getTime());
|
2021-03-04 06:20:38 -06:00
|
|
|
return (
|
2021-12-16 05:46:09 -06:00
|
|
|
<tr key={key.id} className={styles.tableRow(isExpired)}>
|
2021-03-04 06:20:38 -06:00
|
|
|
<td>{key.name}</td>
|
|
|
|
<td>{key.role}</td>
|
2021-12-16 05:46:09 -06:00
|
|
|
<td>
|
|
|
|
{formatDate(key.expiration, timeZone)}
|
|
|
|
{isExpired && (
|
|
|
|
<span className={styles.tooltipContainer}>
|
|
|
|
<Tooltip content="This API key has expired.">
|
2022-09-06 03:15:36 -05:00
|
|
|
<Icon name="exclamation-triangle" />
|
2021-12-16 05:46:09 -06:00
|
|
|
</Tooltip>
|
|
|
|
</span>
|
|
|
|
)}
|
|
|
|
</td>
|
2021-03-04 06:20:38 -06:00
|
|
|
<td>
|
2022-06-15 07:59:40 -05:00
|
|
|
<HorizontalGroup justify="flex-end">
|
2022-07-11 10:24:10 -05:00
|
|
|
<Button size="sm" onClick={() => onMigrate(key)}>
|
2022-07-21 11:56:20 -05:00
|
|
|
Migrate to service account
|
2022-07-11 10:24:10 -05:00
|
|
|
</Button>
|
2022-06-15 07:59:40 -05:00
|
|
|
<DeleteButton
|
|
|
|
aria-label="Delete API key"
|
|
|
|
size="sm"
|
|
|
|
onConfirm={() => onDelete(key)}
|
|
|
|
disabled={!contextSrv.hasPermissionInMetadata(AccessControlAction.ActionAPIKeysDelete, key)}
|
|
|
|
/>
|
|
|
|
</HorizontalGroup>
|
2021-03-04 06:20:38 -06:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</tbody>
|
|
|
|
) : null}
|
|
|
|
</table>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
function formatDate(expiration: string | undefined, timeZone: TimeZone): string {
|
|
|
|
if (!expiration) {
|
|
|
|
return 'No expiration date';
|
|
|
|
}
|
|
|
|
return dateTimeFormat(expiration, { timeZone });
|
|
|
|
}
|
2021-12-16 05:46:09 -06:00
|
|
|
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
|
|
tableRow: (isExpired: boolean) => css`
|
|
|
|
color: ${isExpired ? theme.colors.text.secondary : theme.colors.text.primary};
|
|
|
|
`,
|
|
|
|
tooltipContainer: css`
|
|
|
|
margin-left: ${theme.spacing(1)};
|
|
|
|
`,
|
|
|
|
});
|