row.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {
  4. addErrorMessage,
  5. addLoadingMessage,
  6. clearIndicators,
  7. } from 'sentry/actionCreators/indicator';
  8. import {Button} from 'sentry/components/button';
  9. import Link from 'sentry/components/links/link';
  10. import PanelItem from 'sentry/components/panels/panelItem';
  11. import {IconDelete} from 'sentry/icons';
  12. import {t} from 'sentry/locale';
  13. import {space} from 'sentry/styles/space';
  14. import type {ApiApplication} from 'sentry/types/user';
  15. import getDynamicText from 'sentry/utils/getDynamicText';
  16. import useApi from 'sentry/utils/useApi';
  17. const ROUTE_PREFIX = '/settings/account/api/';
  18. type Props = {
  19. app: ApiApplication;
  20. onRemove: (app: ApiApplication) => void;
  21. };
  22. function Row({app, onRemove}: Props) {
  23. const api = useApi();
  24. const [isLoading, setLoading] = useState(false);
  25. async function handleRemove() {
  26. if (isLoading) {
  27. return;
  28. }
  29. setLoading(true);
  30. addLoadingMessage();
  31. try {
  32. await api.requestPromise(`/api-applications/${app.id}/`, {
  33. method: 'DELETE',
  34. });
  35. clearIndicators();
  36. onRemove(app);
  37. } catch (_err) {
  38. addErrorMessage(t('Unable to remove application. Please try again.'));
  39. }
  40. }
  41. return (
  42. <StyledPanelItem>
  43. <ApplicationNameWrapper>
  44. <ApplicationName to={`${ROUTE_PREFIX}applications/${app.id}/`}>
  45. {getDynamicText({value: app.name, fixed: 'CI_APPLICATION_NAME'})}
  46. </ApplicationName>
  47. <ClientId>
  48. {getDynamicText({value: app.clientID, fixed: 'CI_CLIENT_ID'})}
  49. </ClientId>
  50. </ApplicationNameWrapper>
  51. <Button
  52. aria-label={t('Remove')}
  53. onClick={handleRemove}
  54. disabled={isLoading}
  55. size="sm"
  56. icon={<IconDelete size="sm" />}
  57. />
  58. </StyledPanelItem>
  59. );
  60. }
  61. const StyledPanelItem = styled(PanelItem)`
  62. padding: ${space(2)};
  63. align-items: center;
  64. `;
  65. const ApplicationNameWrapper = styled('div')`
  66. display: flex;
  67. flex-direction: column;
  68. flex: 1;
  69. margin-right: ${space(1)};
  70. `;
  71. const ApplicationName = styled(Link)`
  72. margin-bottom: ${space(1)};
  73. `;
  74. const ClientId = styled('div')`
  75. color: ${p => p.theme.subText};
  76. font-size: ${p => p.theme.fontSizeSmall};
  77. `;
  78. export default Row;