import {Component, Fragment} from 'react'; import styled from '@emotion/styled'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import type {ModalRenderProps} from 'sentry/actionCreators/modal'; import {openModal} from 'sentry/actionCreators/modal'; import {Button} from 'sentry/components/button'; import RadioGroup from 'sentry/components/forms/controls/radioGroup'; import Form from 'sentry/components/forms/form'; import JsonForm from 'sentry/components/forms/jsonForm'; import FormModel from 'sentry/components/forms/model'; import type {JsonFormObject} from 'sentry/components/forms/types'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {RouteComponentProps} from 'sentry/types/legacyReactRouter'; import type {User} from 'sentry/types/user'; import {browserHistory} from 'sentry/utils/browserHistory'; import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView'; const userEditForm: JsonFormObject = { title: 'User details', fields: [ { name: 'name', type: 'string', required: true, label: t('Name'), }, { name: 'username', type: 'string', required: true, label: t('Username'), help: t('The username is the unique id of the user in the system'), }, { name: 'email', type: 'string', required: true, label: t('Email'), help: t('The users primary email address'), }, { name: 'isActive', type: 'boolean', required: true, label: t('Active'), help: t( 'Designates whether this user should be treated as active. Unselect this instead of deleting accounts.' ), }, { name: 'isStaff', type: 'boolean', required: true, label: t('Admin'), help: t('Designates whether this user can perform administrative functions.'), }, { name: 'isSuperuser', type: 'boolean', required: true, label: t('Superuser'), help: t( 'Designates whether this user has all permissions without explicitly assigning them.' ), }, ], }; const REMOVE_BUTTON_LABEL = { disable: t('Disable User'), delete: t('Permanently Delete User'), }; type DeleteType = 'disable' | 'delete'; type RemoveModalProps = ModalRenderProps & { onRemove: (type: DeleteType) => void; user: User; }; type RemoveModalState = { deleteType: DeleteType; }; class RemoveUserModal extends Component { state: RemoveModalState = { deleteType: 'disable', }; onRemove = () => { this.props.onRemove(this.state.deleteType); this.props.closeModal(); }; render() { const {user} = this.props; const {deleteType} = this.state; return ( this.setState({deleteType: type})} choices={[ ['disable', t('Disable the account.')], ['delete', t('Permanently remove the user and their data.')], ]} /> ); } } type Props = DeprecatedAsyncView['props'] & RouteComponentProps<{id: string}, {}>; type State = DeprecatedAsyncView['state'] & { user: User | null; }; class AdminUserEdit extends DeprecatedAsyncView { get userEndpoint() { const {params} = this.props; return `/users/${params.id}/`; } getEndpoints(): ReturnType { return [['user', this.userEndpoint]]; } async deleteUser() { await this.api.requestPromise(this.userEndpoint, { method: 'DELETE', data: {hardDelete: true, organizations: []}, }); addSuccessMessage(t("%s's account has been deleted.", this.state.user?.email)); browserHistory.replace('/manage/users/'); } async deactivateUser() { const response = await this.api.requestPromise(this.userEndpoint, { method: 'PUT', data: {isActive: false}, }); this.setState({user: response}); this.formModel.setInitialData(response); addSuccessMessage(t("%s's account has been deactivated.", response.email)); } removeUser = (actionTypes: DeleteType) => actionTypes === 'delete' ? this.deleteUser() : this.deactivateUser(); formModel = new FormModel(); renderBody() { const {user} = this.state; if (user === null) { return null; } const openDeleteModal = () => openModal(opts => ( )); return (

{t('Users')}

{t('Editing user: %s', user.email)}

{ addErrorMessage(err?.responseJSON?.detail); }} onSubmitSuccess={data => { this.setState({user: data}); addSuccessMessage(t('User account updated.')); }} extraButton={ } >
); } } const ModalFooter = styled('div')` display: grid; grid-auto-flow: column; gap: ${space(1)}; justify-content: end; padding: 20px 30px; margin: 20px -30px -30px; border-top: 1px solid ${p => p.theme.border}; `; export default AdminUserEdit;