123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- import {Fragment} from 'react';
- import styled from '@emotion/styled';
- import {Button} from 'sentry/components/button';
- import Confirm from 'sentry/components/confirm';
- import Link from 'sentry/components/links/link';
- import LoadingIndicator from 'sentry/components/loadingIndicator';
- import Placeholder from 'sentry/components/placeholder';
- import TimeSince from 'sentry/components/timeSince';
- import {Tooltip} from 'sentry/components/tooltip';
- import {IconSubtract} from 'sentry/icons';
- import {t, tct} from 'sentry/locale';
- import {space} from 'sentry/styles/space';
- import type {Organization, OrgAuthToken, Project} from 'sentry/types';
- import getDynamicText from 'sentry/utils/getDynamicText';
- import {tokenPreview} from 'sentry/views/settings/organizationAuthTokens';
- function LastUsed({
- organization,
- dateLastUsed,
- projectLastUsed,
- }: {
- organization: Organization;
- dateLastUsed?: Date;
- projectLastUsed?: Project;
- }) {
- if (dateLastUsed && projectLastUsed) {
- return (
- <Fragment>
- {tct('[date] in project [project]', {
- date: (
- <TimeSince
- date={getDynamicText({
- value: dateLastUsed,
- fixed: new Date(1508208080000), // National Pasta Day
- })}
- />
- ),
- project: (
- <Link to={`/settings/${organization.slug}/${projectLastUsed.slug}/`}>
- {projectLastUsed.name}
- </Link>
- ),
- })}
- </Fragment>
- );
- }
- if (dateLastUsed) {
- return (
- <Fragment>
- <TimeSince
- date={getDynamicText({
- value: dateLastUsed,
- fixed: new Date(1508208080000), // National Pasta Day
- })}
- />
- </Fragment>
- );
- }
- if (projectLastUsed) {
- return (
- <Fragment>
- {tct('in project [project]', {
- project: (
- <Link to={`/settings/${organization.slug}/${projectLastUsed.slug}/`}>
- {projectLastUsed.name}
- </Link>
- ),
- })}
- </Fragment>
- );
- }
- return <NeverUsed>{t('never used')}</NeverUsed>;
- }
- export function OrganizationAuthTokensAuthTokenRow({
- organization,
- isRevoking,
- token,
- revokeToken,
- projectLastUsed,
- isProjectLoading,
- }: {
- isRevoking: boolean;
- organization: Organization;
- token: OrgAuthToken;
- isProjectLoading?: boolean;
- projectLastUsed?: Project;
- revokeToken?: (token: OrgAuthToken) => void;
- }) {
- return (
- <Fragment>
- <div>
- <Label>
- <Link to={`/settings/${organization.slug}/auth-tokens/${token.id}/`}>
- {token.name}
- </Link>
- </Label>
- {token.tokenLastCharacters && (
- <TokenPreview aria-label={t('Token preview')}>
- {tokenPreview(
- getDynamicText({
- value: token.tokenLastCharacters,
- fixed: 'ABCD',
- }),
- 'sntrys_'
- )}
- </TokenPreview>
- )}
- </div>
- <DateTime>
- {isProjectLoading ? (
- <Placeholder height="1.25em" />
- ) : (
- <Fragment>
- <TimeSince
- date={getDynamicText({
- value: token.dateCreated,
- fixed: new Date(1508208080000), // National Pasta Day
- })}
- />
- </Fragment>
- )}
- </DateTime>
- <DateTime>
- {isProjectLoading ? (
- <Placeholder height="1.25em" />
- ) : (
- <LastUsed
- dateLastUsed={token.dateLastUsed}
- projectLastUsed={projectLastUsed}
- organization={organization}
- />
- )}
- </DateTime>
- <Actions>
- <Tooltip
- title={t(
- 'You must be an organization owner, manager or admin to revoke a token.'
- )}
- disabled={!!revokeToken}
- >
- <Confirm
- disabled={!revokeToken || isRevoking}
- onConfirm={revokeToken ? () => revokeToken(token) : undefined}
- message={t(
- 'Are you sure you want to revoke this token? The token will not be usable anymore, and this cannot be undone.'
- )}
- >
- <Button
- size="sm"
- disabled={isRevoking || !revokeToken}
- aria-label={t('Revoke %s', token.name)}
- icon={
- isRevoking ? (
- <LoadingIndicator mini />
- ) : (
- <IconSubtract isCircled size="xs" />
- )
- }
- >
- {t('Revoke')}
- </Button>
- </Confirm>
- </Tooltip>
- </Actions>
- </Fragment>
- );
- }
- const Label = styled('div')``;
- const Actions = styled('div')`
- display: flex;
- justify-content: flex-end;
- `;
- const DateTime = styled('div')`
- display: flex;
- align-items: center;
- gap: ${space(0.5)};
- `;
- const NeverUsed = styled('div')`
- color: ${p => p.theme.gray300};
- `;
- const TokenPreview = styled('div')`
- color: ${p => p.theme.gray300};
- `;
|