index.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import {Fragment} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import {addSuccessMessage} from 'sentry/actionCreators/indicator';
  5. import Alert from 'sentry/components/alert';
  6. import {Button} from 'sentry/components/button';
  7. import ApiForm from 'sentry/components/forms/apiForm';
  8. import HiddenField from 'sentry/components/forms/fields/hiddenField';
  9. import LoadingIndicator from 'sentry/components/loadingIndicator';
  10. import NarrowLayout from 'sentry/components/narrowLayout';
  11. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  12. import {t, tct} from 'sentry/locale';
  13. import {space} from 'sentry/styles/space';
  14. import type {Organization} from 'sentry/types/organization';
  15. import {browserHistory} from 'sentry/utils/browserHistory';
  16. import {useApiQuery} from 'sentry/utils/queryClient';
  17. import normalizeUrl from 'sentry/utils/url/normalizeUrl';
  18. import {useParams} from 'sentry/utils/useParams';
  19. type Props = RouteComponentProps<{orgId: string}, {}>;
  20. function OrganizationRestore(_props: Props) {
  21. const params = useParams<{orgId: string}>();
  22. return (
  23. <SentryDocumentTitle title={t('Restore Organization')}>
  24. <NarrowLayout>
  25. <h3>{t('Deletion Scheduled')}</h3>
  26. <OrganizationRestoreBody orgSlug={params.orgId} />
  27. </NarrowLayout>
  28. </SentryDocumentTitle>
  29. );
  30. }
  31. type BodyProps = {
  32. orgSlug: string;
  33. };
  34. function OrganizationRestoreBody({orgSlug}: BodyProps) {
  35. const endpoint = `/organizations/${orgSlug}/`;
  36. const {isLoading, isError, data} = useApiQuery<Organization>([endpoint], {
  37. staleTime: 0,
  38. });
  39. if (isLoading) {
  40. return <LoadingIndicator />;
  41. }
  42. if (isError) {
  43. return (
  44. <Alert type="error">{t('There was an error loading your organization.')}</Alert>
  45. );
  46. }
  47. if (data.status.id === 'active') {
  48. browserHistory.replace(normalizeUrl(`/organizations/${orgSlug}/issues/`));
  49. return null;
  50. }
  51. if (data.status.id === 'pending_deletion') {
  52. return <RestoreForm organization={data} endpoint={endpoint} />;
  53. }
  54. return (
  55. <p>
  56. {t(
  57. 'Sorry, but this organization is currently in progress of being deleted. No turning back.'
  58. )}
  59. </p>
  60. );
  61. }
  62. type RestoreFormProps = {
  63. endpoint: string;
  64. organization: Organization;
  65. };
  66. function RestoreForm({endpoint, organization}: RestoreFormProps) {
  67. return (
  68. <Fragment>
  69. <ApiForm
  70. apiEndpoint={endpoint}
  71. apiMethod="PUT"
  72. submitLabel={t('Restore Organization')}
  73. onSubmitSuccess={() => {
  74. addSuccessMessage(t('Organization Restored'));
  75. // Use window.location to ensure page reloads
  76. window.location.assign(
  77. normalizeUrl(`/organizations/${organization.slug}/issues/`)
  78. );
  79. }}
  80. initialData={{cancelDeletion: 1}}
  81. hideFooter
  82. >
  83. <HiddenField name="cancelDeletion" />
  84. <p>
  85. {tct('The [name] organization is currently scheduled for deletion.', {
  86. name: <strong>{organization.slug}</strong>,
  87. })}
  88. </p>
  89. <p>
  90. {t(
  91. 'Would you like to cancel this process and restore the organization back to the original state?'
  92. )}
  93. </p>
  94. <ButtonWrapper>
  95. <Button data-test-id="form-submit" priority="primary" type="submit">
  96. {t('Restore Organization')}
  97. </Button>
  98. </ButtonWrapper>
  99. </ApiForm>
  100. <p>
  101. {t(
  102. 'Note: Restoration is available until deletion has started. Once it begins, there is no recovering the data that has been removed.'
  103. )}
  104. </p>
  105. </Fragment>
  106. );
  107. }
  108. const ButtonWrapper = styled('div')`
  109. margin-bottom: ${space(2)};
  110. `;
  111. export default OrganizationRestore;