UserSessions.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { t, Trans } from '@lingui/macro';
  2. import { withI18n, withI18nProps } from '@lingui/react';
  3. import React, { PureComponent } from 'react';
  4. import { selectors } from '@grafana/e2e-selectors';
  5. import { Button, Icon, LoadingPlaceholder } from '@grafana/ui';
  6. import { UserSession } from 'app/types';
  7. interface Props extends withI18nProps {
  8. sessions: UserSession[];
  9. isLoading: boolean;
  10. revokeUserSession: (tokenId: number) => void;
  11. }
  12. class UserSessions extends PureComponent<Props> {
  13. render() {
  14. const { isLoading, sessions, revokeUserSession, i18n } = this.props;
  15. if (isLoading) {
  16. return <LoadingPlaceholder text={<Trans id="user-sessions.loading">Loading sessions...</Trans>} />;
  17. }
  18. return (
  19. <div>
  20. {sessions.length > 0 && (
  21. <>
  22. <h3 className="page-sub-heading">Sessions</h3>
  23. <div className="gf-form-group">
  24. <table className="filter-table form-inline" data-testid={selectors.components.UserProfile.sessionsTable}>
  25. <thead>
  26. <tr>
  27. <th>
  28. <Trans id="user-session.seen-at-column">Last seen</Trans>
  29. </th>
  30. <th>
  31. <Trans id="user-session.created-at-column">Logged on</Trans>
  32. </th>
  33. <th>
  34. <Trans id="user-session.ip-column">IP address</Trans>
  35. </th>
  36. <th>
  37. <Trans id="user-session.browser-column">Browser &amp; OS</Trans>
  38. </th>
  39. <th></th>
  40. </tr>
  41. </thead>
  42. <tbody>
  43. {sessions.map((session: UserSession, index) => (
  44. <tr key={index}>
  45. {session.isActive ? <td>Now</td> : <td>{session.seenAt}</td>}
  46. <td>{i18n.date(session.createdAt, { dateStyle: 'long' })}</td>
  47. <td>{session.clientIp}</td>
  48. <td>
  49. {session.browser} on {session.os} {session.osVersion}
  50. </td>
  51. <td>
  52. <Button
  53. size="sm"
  54. variant="destructive"
  55. onClick={() => revokeUserSession(session.id)}
  56. aria-label={t({ id: 'user-session.revoke', message: 'Revoke user session' })}
  57. >
  58. <Icon name="power" />
  59. </Button>
  60. </td>
  61. </tr>
  62. ))}
  63. </tbody>
  64. </table>
  65. </div>
  66. </>
  67. )}
  68. </div>
  69. );
  70. }
  71. }
  72. export default withI18n()(UserSessions);