|
@@ -1,177 +1,23 @@
|
|
|
-import {Component, Fragment} from 'react';
|
|
|
+import {useEffect} from 'react';
|
|
|
import {RouteComponentProps} from 'react-router';
|
|
|
|
|
|
import {switchOrganization} from 'app/actionCreators/organizations';
|
|
|
-import AlertActions from 'app/actions/alertActions';
|
|
|
-import {Client} from 'app/api';
|
|
|
-import Alert from 'app/components/alert';
|
|
|
-import Button from 'app/components/button';
|
|
|
-import ErrorBoundary from 'app/components/errorBoundary';
|
|
|
-import Footer from 'app/components/footer';
|
|
|
-import {Body, Main} from 'app/components/layouts/thirds';
|
|
|
-import {IconWarning} from 'app/icons';
|
|
|
-import {t, tct} from 'app/locale';
|
|
|
-import {Organization} from 'app/types';
|
|
|
-import withOrganization from 'app/utils/withOrganization';
|
|
|
import OrganizationContextContainer from 'app/views/organizationContext';
|
|
|
|
|
|
-type InProgressProps = {
|
|
|
- organization: Organization;
|
|
|
-};
|
|
|
+import Body from './body';
|
|
|
|
|
|
-function DeletionInProgress({organization}: InProgressProps) {
|
|
|
- return (
|
|
|
- <Body>
|
|
|
- <Main>
|
|
|
- <Alert type="warning" icon={<IconWarning />}>
|
|
|
- {tct(
|
|
|
- 'The [organization] organization is currently in the process of being deleted from Sentry.',
|
|
|
- {
|
|
|
- organization: <strong>{organization.slug}</strong>,
|
|
|
- }
|
|
|
- )}
|
|
|
- </Alert>
|
|
|
- </Main>
|
|
|
- </Body>
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-type PendingProps = {
|
|
|
- organization: Organization;
|
|
|
-};
|
|
|
-
|
|
|
-type PendingState = {
|
|
|
- submitInProgress: boolean;
|
|
|
-};
|
|
|
+type Props = RouteComponentProps<{orgId: string}, {}> &
|
|
|
+ Partial<React.ComponentProps<typeof OrganizationContextContainer>>;
|
|
|
|
|
|
-class DeletionPending extends Component<PendingProps, PendingState> {
|
|
|
- state: PendingState = {submitInProgress: false};
|
|
|
-
|
|
|
- componentWillUnmount() {
|
|
|
- this.api.clear();
|
|
|
- }
|
|
|
-
|
|
|
- api = new Client();
|
|
|
-
|
|
|
- onRestore = () => {
|
|
|
- if (this.state.submitInProgress) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.setState({submitInProgress: true});
|
|
|
- this.api.request(`/organizations/${this.props.organization.slug}/`, {
|
|
|
- method: 'PUT',
|
|
|
- data: {cancelDeletion: true},
|
|
|
- success: () => {
|
|
|
- window.location.reload();
|
|
|
- },
|
|
|
- error: () => {
|
|
|
- AlertActions.addAlert({
|
|
|
- message:
|
|
|
- 'We were unable to restore this organization. Please try again or contact support.',
|
|
|
- type: 'error',
|
|
|
- });
|
|
|
- this.setState({submitInProgress: false});
|
|
|
- },
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- render() {
|
|
|
- const {organization} = this.props;
|
|
|
- const access = new Set(organization.access);
|
|
|
- return (
|
|
|
- <Body>
|
|
|
- <Main>
|
|
|
- <h3>{t('Deletion Scheduled')}</h3>
|
|
|
- <p>
|
|
|
- {tct('The [organization] organization is currently scheduled for deletion.', {
|
|
|
- organization: <strong>{organization.slug}</strong>,
|
|
|
- })}
|
|
|
- </p>
|
|
|
-
|
|
|
- {access.has('org:admin') ? (
|
|
|
- <div>
|
|
|
- <p>
|
|
|
- {t(
|
|
|
- 'Would you like to cancel this process and restore the organization back to the original state?'
|
|
|
- )}
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- <Button
|
|
|
- priority="primary"
|
|
|
- onClick={this.onRestore}
|
|
|
- disabled={this.state.submitInProgress}
|
|
|
- >
|
|
|
- {t('Restore Organization')}
|
|
|
- </Button>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <p>
|
|
|
- {t(
|
|
|
- 'If this is a mistake, contact an organization owner and ask them to restore this organization.'
|
|
|
- )}
|
|
|
- </p>
|
|
|
- )}
|
|
|
- <p>
|
|
|
- <small>
|
|
|
- {t(
|
|
|
- "Note: Restoration is available until the process begins. Once it does, there's no recovering the data that has been removed."
|
|
|
- )}
|
|
|
- </small>
|
|
|
- </p>
|
|
|
- </Main>
|
|
|
- </Body>
|
|
|
- );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-type OrganizationDetailsProps = {
|
|
|
- organization?: Organization;
|
|
|
- children?: React.ReactNode;
|
|
|
-};
|
|
|
-
|
|
|
-const OrganizationDetailsBody = withOrganization(function OrganizationDetailsBody({
|
|
|
- children,
|
|
|
- organization,
|
|
|
-}: OrganizationDetailsProps) {
|
|
|
- const status = organization?.status?.id;
|
|
|
-
|
|
|
- if (organization && status === 'pending_deletion') {
|
|
|
- return <DeletionPending organization={organization} />;
|
|
|
- }
|
|
|
-
|
|
|
- if (organization && status === 'deletion_in_progress') {
|
|
|
- return <DeletionInProgress organization={organization} />;
|
|
|
- }
|
|
|
+function OrganizationDetails({children, ...props}: Props) {
|
|
|
+ // Switch organizations when the orgId changes
|
|
|
+ useEffect(() => void switchOrganization(), [props.params.orgId]);
|
|
|
|
|
|
return (
|
|
|
- <Fragment>
|
|
|
- <ErrorBoundary>{children}</ErrorBoundary>
|
|
|
- <Footer />
|
|
|
- </Fragment>
|
|
|
+ <OrganizationContextContainer includeSidebar useLastOrganization {...props}>
|
|
|
+ <Body>{children}</Body>
|
|
|
+ </OrganizationContextContainer>
|
|
|
);
|
|
|
-});
|
|
|
-
|
|
|
-type Props = RouteComponentProps<{orgId: string}, {}>;
|
|
|
-
|
|
|
-export default class OrganizationDetails extends Component<Props> {
|
|
|
- componentDidUpdate(prevProps: Props) {
|
|
|
- if (
|
|
|
- prevProps.params &&
|
|
|
- this.props.params &&
|
|
|
- prevProps.params.orgId !== this.props.params.orgId
|
|
|
- ) {
|
|
|
- switchOrganization();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- render() {
|
|
|
- return (
|
|
|
- <OrganizationContextContainer includeSidebar useLastOrganization {...this.props}>
|
|
|
- <OrganizationDetailsBody {...this.props}>
|
|
|
- {this.props.children}
|
|
|
- </OrganizationDetailsBody>
|
|
|
- </OrganizationContextContainer>
|
|
|
- );
|
|
|
- }
|
|
|
}
|
|
|
+
|
|
|
+export default OrganizationDetails;
|