mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-27 07:44:29 +02:00
First mock for an 'invite user' button in the list-user view
This commit is contained in:
parent
a477941b18
commit
f558e64afc
@ -13,6 +13,7 @@ import Message from 'core-components/message';
|
|||||||
import Icon from 'core-components/icon';
|
import Icon from 'core-components/icon';
|
||||||
import ModalContainer from 'app-components/modal-container';
|
import ModalContainer from 'app-components/modal-container';
|
||||||
import MainSignUpWidget from 'app/main/main-signup/main-signup-widget';
|
import MainSignUpWidget from 'app/main/main-signup/main-signup-widget';
|
||||||
|
import InviteUserWidget from 'app/admin/panel/users/invite-user-widget';
|
||||||
|
|
||||||
class AdminPanelListUsers extends React.Component {
|
class AdminPanelListUsers extends React.Component {
|
||||||
|
|
||||||
@ -45,6 +46,9 @@ class AdminPanelListUsers extends React.Component {
|
|||||||
<Button onClick={this.onCreateUser.bind(this)} type="secondary" size="medium">
|
<Button onClick={this.onCreateUser.bind(this)} type="secondary" size="medium">
|
||||||
<Icon size="sm" name="plus"/> {i18n('ADD_USER')}
|
<Icon size="sm" name="plus"/> {i18n('ADD_USER')}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button onClick={this.onInviteUser.bind(this)} type="secondary" size="medium">
|
||||||
|
<Icon size="sm" name="plus"/> {i18n('INVITE_USER')}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -181,6 +185,20 @@ class AdminPanelListUsers extends React.Component {
|
|||||||
ModalContainer.closeModal();
|
ModalContainer.closeModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onInviteUser(user) {
|
||||||
|
ModalContainer.openModal(
|
||||||
|
<div className="admin-panel-list-users__invite-user-form">
|
||||||
|
<InviteUserWidget onSuccess={this.onInviteUserSuccess.bind(this)} />
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<Button onClick={ModalContainer.closeModal} type="link">{i18n('CLOSE')}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
onInviteUserSuccess() {
|
||||||
|
ModalContainer.closeModal();
|
||||||
|
}
|
||||||
|
|
||||||
onUsersRetrieved(result) {
|
onUsersRetrieved(result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
page: result.data.page * 1,
|
page: result.data.page * 1,
|
||||||
|
165
client/src/app/admin/panel/users/invite-user-widget.js
Normal file
165
client/src/app/admin/panel/users/invite-user-widget.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import i18n from 'lib-app/i18n';
|
||||||
|
import API from 'lib-app/api-call';
|
||||||
|
|
||||||
|
import Captcha from 'app/main/captcha';
|
||||||
|
import SubmitButton from 'core-components/submit-button';
|
||||||
|
import Message from 'core-components/message';
|
||||||
|
import Form from 'core-components/form';
|
||||||
|
import FormField from 'core-components/form-field';
|
||||||
|
import Widget from 'core-components/widget';
|
||||||
|
import Header from 'core-components/header';
|
||||||
|
|
||||||
|
class InviteUserWidget extends React.Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
onSuccess: React.PropTypes.func,
|
||||||
|
className: React.PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
email: null,
|
||||||
|
customFields: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
API.call({
|
||||||
|
path: '/system/get-custom-fields',
|
||||||
|
data: {}
|
||||||
|
})
|
||||||
|
.then(result => this.setState({customFields: result.data}));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Widget className={this.getClass()}>
|
||||||
|
<Header title={i18n('INVITE_USER')} description={i18n('INVITE_USER_VIEW_DESCRIPTION')} />
|
||||||
|
<Form {...this.getFormProps()}>
|
||||||
|
<div className="invite-user-widget__inputs">
|
||||||
|
<FormField {...this.getInputProps()} label={i18n('FULL_NAME')} name="name" validation="NAME" required/>
|
||||||
|
<FormField {...this.getInputProps()} label={i18n('EMAIL')} name="email" validation="EMAIL" required/>
|
||||||
|
{this.state.customFields.map(this.renderCustomField.bind(this))}
|
||||||
|
</div>
|
||||||
|
<div className="invite-user-widget__captcha">
|
||||||
|
<Captcha ref="captcha"/>
|
||||||
|
</div>
|
||||||
|
<SubmitButton type="primary">{i18n('INVITE_USER')}</SubmitButton>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
{this.renderMessage()}
|
||||||
|
</Widget>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCustomField(customField, key) {
|
||||||
|
if(customField.type === 'text') {
|
||||||
|
return (
|
||||||
|
<FormField {...this.getInputProps()}
|
||||||
|
name={`customfield_${customField.name}`}
|
||||||
|
key={key}
|
||||||
|
label={customField.name}
|
||||||
|
infoMessage={customField.description}
|
||||||
|
field="input"/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const items = customField.options.map(option => ({content: option.name, value: option.name}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
name={`customfield_${customField.name}`}
|
||||||
|
key={key}
|
||||||
|
label={customField.name}
|
||||||
|
infoMessage={customField.description}
|
||||||
|
field="select"
|
||||||
|
fieldProps={{size:'medium', items}}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMessage() {
|
||||||
|
switch (this.state.message) {
|
||||||
|
case 'success':
|
||||||
|
return <Message type="success">{i18n('INVITE_USER_SUCCESS')}</Message>;
|
||||||
|
case 'fail':
|
||||||
|
return <Message type="error">{i18n('EMAIL_EXISTS')}</Message>;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getClass() {
|
||||||
|
let classes = {
|
||||||
|
'invite-user-widget': true,
|
||||||
|
[this.props.className]: this.props.className
|
||||||
|
};
|
||||||
|
return classNames(classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormProps() {
|
||||||
|
return {
|
||||||
|
loading: this.state.loading,
|
||||||
|
className: 'invite-user-widget__form',
|
||||||
|
onSubmit: this.onInviteUserFormSubmit.bind(this)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputProps(password) {
|
||||||
|
return {
|
||||||
|
className: 'invite-user-widget__input',
|
||||||
|
fieldProps: {
|
||||||
|
size: 'medium',
|
||||||
|
password: password
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onInviteUserFormSubmit(formState) {
|
||||||
|
const captcha = this.refs.captcha.getWrappedInstance();
|
||||||
|
|
||||||
|
if (!captcha.getValue()) {
|
||||||
|
captcha.focus();
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = _.clone(formState);
|
||||||
|
|
||||||
|
this.state.customFields.forEach(customField => {
|
||||||
|
if(customField.type === 'select') {
|
||||||
|
form[`customfield_${customField.name}`] = customField.options[form[`customfield_${customField.name}`]].name;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
API.call({
|
||||||
|
path: '/user/invite',
|
||||||
|
data: _.extend({captcha: captcha.getValue()}, form)
|
||||||
|
}).then(this.onInviteUserSuccess.bind(this)).catch(this.onInviteUserFail.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInviteUserSuccess() {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
message: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onInviteUserFail() {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
message: 'fail'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InviteUserWidget;
|
19
client/src/app/admin/panel/users/invite-user-widget.scss
Normal file
19
client/src/app/admin/panel/users/invite-user-widget.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.invite-user-widget {
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&__form {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__inputs {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__captcha {
|
||||||
|
margin: 10px auto 20px;
|
||||||
|
height: 78px;
|
||||||
|
width: 304px;
|
||||||
|
}
|
||||||
|
}
|
@ -193,6 +193,7 @@ export default {
|
|||||||
'NEVER': 'Never',
|
'NEVER': 'Never',
|
||||||
'HIMSELF': 'himself',
|
'HIMSELF': 'himself',
|
||||||
'ADD_USER': 'Add user',
|
'ADD_USER': 'Add user',
|
||||||
|
'INVITE_USER': 'Invite user',
|
||||||
'UPLOAD_FILE': 'Upload file',
|
'UPLOAD_FILE': 'Upload file',
|
||||||
'PRIVATE': 'Private',
|
'PRIVATE': 'Private',
|
||||||
'ENABLE_USER': 'Enable User',
|
'ENABLE_USER': 'Enable User',
|
||||||
@ -336,6 +337,7 @@ export default {
|
|||||||
'IMAP_POLLING_DESCRIPTION': 'Inbox checking will not be done automatically by OpenSupports. You have to make POST requests periodically to this url to process the emails: {url}',
|
'IMAP_POLLING_DESCRIPTION': 'Inbox checking will not be done automatically by OpenSupports. You have to make POST requests periodically to this url to process the emails: {url}',
|
||||||
'NEW_CUSTOM_FIELD_DESCRIPTION': 'Here you can create a custom field for an user, it can be a blank text box or a fixed set of options.',
|
'NEW_CUSTOM_FIELD_DESCRIPTION': 'Here you can create a custom field for an user, it can be a blank text box or a fixed set of options.',
|
||||||
'CUSTOM_FIELDS_DESCRIPTION': 'Custom fields are defined additional fields the users are able to fill to provide more information about them.',
|
'CUSTOM_FIELDS_DESCRIPTION': 'Custom fields are defined additional fields the users are able to fill to provide more information about them.',
|
||||||
|
'INVITE_USER_VIEW_DESCRIPTION': 'Here you can invite an user to join our support system, he will just need to provide his password to create a new user.',
|
||||||
|
|
||||||
//ERRORS
|
//ERRORS
|
||||||
'EMAIL_OR_PASSWORD': 'Email or password invalid',
|
'EMAIL_OR_PASSWORD': 'Email or password invalid',
|
||||||
@ -372,6 +374,7 @@ export default {
|
|||||||
|
|
||||||
//MESSAGES
|
//MESSAGES
|
||||||
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
||||||
|
'INVITE_USER_SUCCESS': 'You have invited a new user successfully in our support system',
|
||||||
'TICKET_SENT': 'Ticket has been created successfully.',
|
'TICKET_SENT': 'Ticket has been created successfully.',
|
||||||
'VALID_RECOVER': 'Password recovered successfully',
|
'VALID_RECOVER': 'Password recovered successfully',
|
||||||
'EMAIL_EXISTS': 'Email already exists',
|
'EMAIL_EXISTS': 'Email already exists',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user