mirror of
https://github.com/grafana/grafana.git
synced 2025-01-16 03:32:37 -06:00
47f8717149
* update eslint, tsconfig + esbuild to handle new jsx transform * remove thing that breaks the new jsx transform * remove react imports * adjust grafana-icons build * is this the correct syntax? * try this * well this was much easier than expected... * change grafana-plugin-configs webpack config * fixes * fix lockfile * fix 2 more violations * use path.resolve instead of require.resolve * remove react import * fix react imports * more fixes * remove React import * remove import React from docs * remove another react import
87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import { t } from 'i18next';
|
|
import { PureComponent } from 'react';
|
|
|
|
import { selectors } from '@grafana/e2e-selectors';
|
|
import { Button, Icon, LoadingPlaceholder } from '@grafana/ui';
|
|
import { Trans } from 'app/core/internationalization';
|
|
import { formatDate } from 'app/core/internationalization/dates';
|
|
import { UserSession } from 'app/types';
|
|
|
|
interface Props {
|
|
sessions: UserSession[];
|
|
isLoading: boolean;
|
|
revokeUserSession: (tokenId: number) => void;
|
|
}
|
|
|
|
class UserSessions extends PureComponent<Props> {
|
|
render() {
|
|
const { isLoading, sessions, revokeUserSession } = this.props;
|
|
const styles = getStyles();
|
|
|
|
if (isLoading) {
|
|
return <LoadingPlaceholder text={<Trans i18nKey="user-sessions.loading">Loading sessions...</Trans>} />;
|
|
}
|
|
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
{sessions.length > 0 && (
|
|
<>
|
|
<h3 className="page-sub-heading">Sessions</h3>
|
|
<table className="filter-table form-inline" data-testid={selectors.components.UserProfile.sessionsTable}>
|
|
<thead>
|
|
<tr>
|
|
<th>
|
|
<Trans i18nKey="user-session.seen-at-column">Last seen</Trans>
|
|
</th>
|
|
<th>
|
|
<Trans i18nKey="user-session.created-at-column">Logged on</Trans>
|
|
</th>
|
|
<th>
|
|
<Trans i18nKey="user-session.ip-column">IP address</Trans>
|
|
</th>
|
|
<th>
|
|
<Trans i18nKey="user-session.browser-column">Browser & OS</Trans>
|
|
</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
{sessions.map((session: UserSession, index) => (
|
|
<tr key={index}>
|
|
{session.isActive ? <td>Now</td> : <td>{session.seenAt}</td>}
|
|
<td>{formatDate(session.createdAt, { dateStyle: 'long' })}</td>
|
|
<td>{session.clientIp}</td>
|
|
<td>
|
|
{session.browser} on {session.os} {session.osVersion}
|
|
</td>
|
|
<td>
|
|
<Button
|
|
size="sm"
|
|
variant="destructive"
|
|
onClick={() => revokeUserSession(session.id)}
|
|
aria-label={t('user-session.revoke', 'Revoke user session')}
|
|
>
|
|
<Icon name="power" />
|
|
</Button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
const getStyles = () => ({
|
|
wrapper: css({
|
|
maxWidth: '100%',
|
|
}),
|
|
});
|
|
|
|
export default UserSessions;
|