import type {RouteComponentProps} from 'react-router'; import styled from '@emotion/styled'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {Button} from 'sentry/components/button'; import EmptyMessage from 'sentry/components/emptyMessage'; import ExternalLink from 'sentry/components/links/externalLink'; import Link from 'sentry/components/links/link'; import Panel from 'sentry/components/panels/panel'; import PanelBody from 'sentry/components/panels/panelBody'; import PanelHeader from 'sentry/components/panels/panelHeader'; import PanelItem from 'sentry/components/panels/panelItem'; import {IconDelete} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {ApiApplication} from 'sentry/types'; import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView'; import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader'; type Authorization = { application: ApiApplication; homepageUrl: string; id: string; scopes: string[]; }; type Props = RouteComponentProps<{}, {}>; type State = { data: Authorization[]; } & DeprecatedAsyncView['state']; class AccountAuthorizations extends DeprecatedAsyncView { getEndpoints(): ReturnType { return [['data', '/api-authorizations/']]; } getTitle() { return 'Approved Applications'; } handleRevoke = authorization => { const oldData = this.state.data; this.setState( state => ({ data: state.data.filter(({id}) => id !== authorization.id), }), async () => { try { await this.api.requestPromise('/api-authorizations/', { method: 'DELETE', data: {authorization: authorization.id}, }); addSuccessMessage(t('Saved changes')); } catch (_err) { this.setState({ data: oldData, }); addErrorMessage(t('Unable to save changes, please try again')); } } ); }; renderBody() { const {data} = this.state; const isEmpty = data.length === 0; return (
{tct('You can manage your own applications via the [link:API dashboard].', { link: , })} {t('Approved Applications')} {isEmpty && ( {t("You haven't approved any third party applications.")} )} {!isEmpty && (
{data.map(authorization => ( {authorization.application.name} {authorization.homepageUrl && ( {authorization.homepageUrl} )} {authorization.scopes.join(', ')}
)}
); } } export default AccountAuthorizations; const Description = styled('p')` font-size: ${p => p.theme.fontSizeRelativeSmall}; margin-bottom: ${space(4)}; `; const PanelItemCenter = styled(PanelItem)` align-items: center; `; const ApplicationDetails = styled('div')` display: flex; flex: 1; flex-direction: column; `; const ApplicationName = styled('div')` font-weight: bold; margin-bottom: ${space(0.5)}; `; /** * Intentionally wrap so that it does not take up full width and cause * hit box issues */ const Url = styled('div')` margin-bottom: ${space(0.5)}; font-size: ${p => p.theme.fontSizeRelativeSmall}; `; const Scopes = styled('div')` color: ${p => p.theme.gray300}; font-size: ${p => p.theme.fontSizeRelativeSmall}; `;