311 lines
8.9 KiB
JavaScript
311 lines
8.9 KiB
JavaScript
import React, { Component, Fragment } from 'react'
|
|
import PropTypes from 'prop-types'
|
|
import autobind from 'autobind-decorator'
|
|
import { UserList } from './UserList'
|
|
import { UserForm } from './UserForm'
|
|
import { UserFormPlaceholder } from './UserFormPlaceholder'
|
|
import { api } from 'src/API'
|
|
import { Row, Column, Box } from 'ui'
|
|
import { YesNoMessageModal, MessageModal, ChangeEmailModal, WaitModal } from '../Modal'
|
|
import { sizeInfo, colorInfo } from 'ui/style'
|
|
|
|
export class Users extends Component {
|
|
static propTypes = {
|
|
changeTitle: PropTypes.func.isRequired,
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props)
|
|
this.state = {
|
|
modified: false,
|
|
selectedUser: null,
|
|
users: [],
|
|
yesNoModal: null,
|
|
messageModal: null,
|
|
waitModal: null,
|
|
changeEmailModal: null,
|
|
}
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.props.changeTitle('Users')
|
|
|
|
api.listUsers().then((list) => {
|
|
list.items.sort((userA, userB) => (userA.lastName.localeCompare(userB.lastName)))
|
|
this.setState({ users: list.items, selectedUser: list.items[0] }) // TODO: <- Remove
|
|
}).catch((error) => {
|
|
this.setState({
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to get the list of users.',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.props.changeTitle('')
|
|
}
|
|
|
|
removeUnfinishedNewUser() {
|
|
let users = this.state.users
|
|
|
|
if (users.length > 0 && !users[0]._id) {
|
|
this.setState({ users: this.state.users.slice(1) })
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleUserListClick(e, index) {
|
|
let user = this.state.users[index]
|
|
|
|
if (this.state.modified) {
|
|
this.nextSelectedUser = user
|
|
this.setState({
|
|
yesNoModal: {
|
|
question: 'This user has been modified. Are you sure you would like to navigate away?',
|
|
onDismiss: this.handleModifiedModalDismiss
|
|
}
|
|
})
|
|
} else {
|
|
this.setState({ selectedUser: user })
|
|
this.removeUnfinishedNewUser()
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleSave(user) {
|
|
if (user._id) {
|
|
this.setState({ waitModal: { message: 'Updating User' } })
|
|
api.updateUser(user).then((updatedUser) => {
|
|
this.setState({
|
|
waitModal: null,
|
|
users: this.state.users.map((user) => (user._id === updatedUser._id ? updatedUser : user)),
|
|
modified: false,
|
|
selectedUser: updatedUser
|
|
})
|
|
}).catch((error) => {
|
|
this.setState({
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to save the user changes',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
} else {
|
|
this.setState({ waitModal: { message: 'Creating User' } })
|
|
api.createUser(user).then((createdUser) => {
|
|
this.setState({
|
|
waitModal: false,
|
|
users: this.state.users.map((user) => (!user._id ? createdUser : user)).sort((a, b) => (
|
|
a.lastName < b.lastName ? -1 : a.lastName > b.lastName : 0
|
|
)),
|
|
modified: false,
|
|
selectedUser: createdUser
|
|
})
|
|
}).catch((error) => {
|
|
this.setState({
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to create the user.',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleChangeEmail() {
|
|
this.setState({ changeEmailModal: { oldEmail: this.state.selectedUser.email } })
|
|
}
|
|
|
|
@autobind
|
|
handleResendEmail() {
|
|
this.setState({
|
|
waitModal: { message: 'Resending Email...' }
|
|
})
|
|
api.sendConfirmEmail({ existingEmail: this.state.selectedUser.email }).then(() => {
|
|
this.setState({
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'thumb',
|
|
message: `An email has been sent to '${this.state.selectedUser.email}' with further instructions.`
|
|
}
|
|
})
|
|
}).catch((error) => {
|
|
this.setState({
|
|
error: true,
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to request email change.',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
@autobind
|
|
handleChangeEmailDismiss(newEmail) {
|
|
this.setState({ changeEmailModal: null })
|
|
if (!newEmail) {
|
|
return
|
|
}
|
|
this.setState({
|
|
waitModal: { message: 'Requesting Email Change...' }
|
|
})
|
|
if (this.state.selectedUser) {
|
|
api.sendConfirmEmail({ existingEmail: this.state.selectedUser.email, newEmail }).then(() => {
|
|
this.setState({
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: `An email has been sent to '${newEmail}' to confirm this email.`
|
|
}
|
|
})
|
|
}).catch((error) => {
|
|
this.setState({
|
|
error: true,
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to request email change.',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleRemove() {
|
|
this.setState({
|
|
yesNoModal: {
|
|
question: 'Are you sure you want to remove this user? This will also remove them from any teams they belong to.',
|
|
onDismiss: this.handleRemoveModalDismiss
|
|
}
|
|
})
|
|
}
|
|
|
|
@autobind
|
|
handleRemoveModalDismiss(yes) {
|
|
if (yes) {
|
|
const selectedUserId = this.state.selectedUser._id
|
|
const selectedIndex = this.state.users.findIndex((user) => (user._id === selectedUserId))
|
|
|
|
if (selectedIndex >= 0) {
|
|
this.setState({ waitModal: { message: 'Removing User' } })
|
|
api.deleteUser(selectedUserId).then(() => {
|
|
this.setState({
|
|
waitModal: null,
|
|
users: [...this.state.users.slice(0, selectedIndex), ...this.state.users.slice(selectedIndex + 1)],
|
|
selectedUser: null
|
|
})
|
|
}).catch((error) => {
|
|
this.setState({
|
|
waitModal: null,
|
|
messageModal: {
|
|
icon: 'hand',
|
|
message: 'Unable to remove the user.',
|
|
detail: error.message,
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
this.setState({
|
|
yesNoModal: null
|
|
})
|
|
}
|
|
|
|
@autobind
|
|
handleModifiedModalDismiss(yes) {
|
|
if (yes) {
|
|
this.setState({
|
|
selectedUser: this.nextSelectedUser,
|
|
modified: false
|
|
})
|
|
this.removeUnfinishedNewUser()
|
|
delete this.nextSelectedUser
|
|
}
|
|
|
|
this.setState({
|
|
yesNoModal: null
|
|
})
|
|
}
|
|
|
|
@autobind
|
|
handleMessageModalDismiss() {
|
|
this.setState({ messageModal: null })
|
|
}
|
|
|
|
@autobind
|
|
handleModifiedChanged(modified) {
|
|
this.setState({ modified: modified })
|
|
}
|
|
|
|
@autobind
|
|
handleAddNewUser() {
|
|
let newUser = {}
|
|
let newUsers = [newUser].concat(this.state.users)
|
|
this.setState({ users: newUsers, selectedUser: newUser })
|
|
}
|
|
|
|
render() {
|
|
const { messageModal, yesNoModal, changeEmailModal } = this.state
|
|
|
|
return (
|
|
<Fragment>
|
|
<Column.Item height={sizeInfo.formColumnSpacing} />
|
|
<Column.Item grow>
|
|
<Row fillParent>
|
|
<Row.Item width={sizeInfo.formRowSpacing} />
|
|
<Row.Item width='25vw'>
|
|
<UserList users={this.state.users} selectedUser={this.state.selectedUser}
|
|
selectionModified={this.state.modified} onUserListClick={this.handleUserListClick}
|
|
onAddNewUser={this.handleAddNewUser} />
|
|
</Row.Item>
|
|
<Row.Item width={sizeInfo.formRowSpacing} />
|
|
<Row.Item grow>
|
|
<Box border={{ width: sizeInfo.headerBorderWidth, color: colorInfo.headerBorder }} radius={sizeInfo.formBoxRadius}>
|
|
{
|
|
this.state.selectedUser
|
|
? <UserForm user={this.state.selectedUser} onSave={this.handleSave}
|
|
onRemove={this.handleRemove} onModifiedChanged={this.handleModifiedChanged}
|
|
onChangeEmail={this.handleChangeEmail} onResendEmail={this.handleResendEmail} />
|
|
: <UserFormPlaceholder />
|
|
}
|
|
</Box>
|
|
</Row.Item>
|
|
<Row.Item width={sizeInfo.formRowSpacing} />
|
|
</Row>
|
|
</Column.Item>
|
|
<Column.Item height={sizeInfo.formColumnSpacing}>
|
|
<ChangeEmailModal open={!!changeEmailModal}
|
|
oldEmail={changeEmailModal && changeEmailModal.oldEmail}
|
|
onDismiss={this.handleChangeEmailDismiss} />
|
|
|
|
<YesNoMessageModal open={!!yesNoModal}
|
|
question={yesNoModal ? yesNoModal.question : ''}
|
|
onDismiss={yesNoModal && yesNoModal.onDismiss} />
|
|
|
|
<MessageModal
|
|
open={!!messageModal}
|
|
icon={messageModal ? messageModal.icon : ''}
|
|
message={messageModal ? messageModal.message : ''}
|
|
detail={messageModal && messageModal.detail}
|
|
onDismiss={this.handleMessageModalDismiss} />
|
|
|
|
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
|
|
</Column.Item>
|
|
</Fragment>
|
|
)
|
|
}
|
|
}
|