Add more descriptive error messages when in delete staff. (#892)

This commit is contained in:
LautaroCesso 2020-09-30 17:35:32 -03:00 committed by GitHub
parent b73d6d534d
commit 994a39ad6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 43 deletions

View File

@ -33,6 +33,10 @@ class AdminPanelViewStaff extends React.Component {
getProps() { getProps() {
const { userData } = this.state; const { userData } = this.state;
const {
userId,
params
} = this.props;
const userDataWithNumericLevel = { const userDataWithNumericLevel = {
...userData, ...userData,
level: userData.level*1, level: userData.level*1,
@ -41,7 +45,8 @@ class AdminPanelViewStaff extends React.Component {
}; };
return _.extend({}, userDataWithNumericLevel, { return _.extend({}, userDataWithNumericLevel, {
staffId: this.props.params.staffId * 1, userId: userId*1,
staffId: params.staffId*1,
onDelete: this.onDelete.bind(this), onDelete: this.onDelete.bind(this),
onChange: this.retrieveStaff.bind(this) onChange: this.retrieveStaff.bind(this)
}); });
@ -57,14 +62,17 @@ class AdminPanelViewStaff extends React.Component {
} }
onStaffRetrieved(result) { onStaffRetrieved(result) {
const {
userId,
params,
dispatch
} = this.props;
this.setState({ this.setState({
loading: false, loading: false,
userData: result.data userData: result.data
}); });
if(this.props.userId == this.props.params.staffId) { if(userId == params.staffId) dispatch(SessionActions.getUserData(null, null, true));
this.props.dispatch(SessionActions.getUserData(null, null, true))
}
} }
onDelete() { onDelete() {

View File

@ -24,6 +24,7 @@ class StaffEditor extends React.Component {
static propTypes = { static propTypes = {
myAccount: React.PropTypes.bool, myAccount: React.PropTypes.bool,
staffId: React.PropTypes.number, staffId: React.PropTypes.number,
userId: React.PropTypes.number,
email: React.PropTypes.string.isRequired, email: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired, name: React.PropTypes.string.isRequired,
profilePic: React.PropTypes.string.isRequired, profilePic: React.PropTypes.string.isRequired,
@ -49,32 +50,46 @@ class StaffEditor extends React.Component {
}; };
render() { render() {
const {
name,
level,
tickets,
profilePic,
myAccount,
staffId,
userId
} = this.props;
const {
message,
loadingPicture,
email
} = this.state;
return ( return (
<div className="staff-editor"> <div className="staff-editor">
{(this.state.message) ? this.renderMessage() : null} {message ? this.renderMessage() : null}
<div className="row"> <div className="row">
<div className="col-md-4"> <div className="col-md-4">
<div className="staff-editor__card"> <div className="staff-editor__card">
<div className="staff-editor__card-data"> <div className="staff-editor__card-data">
<div className="staff-editor__card-name"> <div className="staff-editor__card-name">
{this.props.name} {name}
</div> </div>
<div className="staff-editor__card-info"> <div className="staff-editor__card-info">
<div className="staff-editor__card-badge"> <div className="staff-editor__card-badge">
<span className="staff-editor__card-badge-blue"> <span className="staff-editor__card-badge-blue">
{this.props.level} {level}
</span> </span>
<span className="staff-editor__card-badge-text">{i18n('STAFF_LEVEL')}</span> <span className="staff-editor__card-badge-text">{i18n('STAFF_LEVEL')}</span>
</div> </div>
<div className="staff-editor__card-badge"> <div className="staff-editor__card-badge">
<span className="staff-editor__card-badge-green"> <span className="staff-editor__card-badge-green">
{_.filter(this.props.tickets, {closed: false}).length} {_.filter(tickets, {closed: false}).length}
</span> </span>
<span className="staff-editor__card-badge-text">{i18n('ASSIGNED')}</span> <span className="staff-editor__card-badge-text">{i18n('ASSIGNED')}</span>
</div> </div>
<div className="staff-editor__card-badge"> <div className="staff-editor__card-badge">
<span className="staff-editor__card-badge-red"> <span className="staff-editor__card-badge-red">
{_.filter(this.props.tickets, {closed: true}).length} {_.filter(tickets, {closed: true}).length}
</span> </span>
<span className="staff-editor__card-badge-text">{i18n('CLOSED')}</span> <span className="staff-editor__card-badge-text">{i18n('CLOSED')}</span>
</div> </div>
@ -82,15 +97,15 @@ class StaffEditor extends React.Component {
</div> </div>
<label className={this.getPictureWrapperClass()}> <label className={this.getPictureWrapperClass()}>
<div className="staff-editor__card-pic-background"></div> <div className="staff-editor__card-pic-background"></div>
<img className="staff-editor__card-pic" src={(this.props.profilePic) ? API.getFileLink(this.props.profilePic) : (API.getURL() + '/images/profile.png')} /> <img className="staff-editor__card-pic" src={(profilePic) ? API.getFileLink(profilePic) : (API.getURL() + '/images/profile.png')} />
{(this.state.loadingPicture) ? <Loading className="staff-editor__card-pic-loading" size="large"/> : <Icon className="staff-editor__card-pic-icon" name="upload" size="4x"/>} {(loadingPicture) ? <Loading className="staff-editor__card-pic-loading" size="large"/> : <Icon className="staff-editor__card-pic-icon" name="upload" size="4x"/>}
<input className="staff-editor__image-uploader" type="file" multiple={false} accept="image/x-png,image/gif,image/jpeg" onChange={this.onProfilePicChange.bind(this)}/> <input className="staff-editor__image-uploader" type="file" multiple={false} accept="image/x-png,image/gif,image/jpeg" onChange={this.onProfilePicChange.bind(this)}/>
</label> </label>
</div> </div>
</div> </div>
<div className="col-md-8"> <div className="col-md-8">
<div className="staff-editor__form"> <div className="staff-editor__form">
<Form className="staff-editor__update-email" values={{email: this.state.email}} onChange={form => this.setState({email: form.email})} onSubmit={this.onSubmit.bind(this, 'EMAIL')}> <Form className="staff-editor__update-email" values={{email: email}} onChange={form => this.setState({email: form.email})} onSubmit={this.onSubmit.bind(this, 'EMAIL')}>
<FormField name="email" validation="EMAIL" required label={i18n('EMAIL')} fieldProps={{size: 'large'}}/> <FormField name="email" validation="EMAIL" required label={i18n('EMAIL')} fieldProps={{size: 'large'}}/>
<SubmitButton size="medium" className="staff-editor__submit-button">{i18n('UPDATE_EMAIL')}</SubmitButton> <SubmitButton size="medium" className="staff-editor__submit-button">{i18n('UPDATE_EMAIL')}</SubmitButton>
</Form> </Form>
@ -100,7 +115,7 @@ class StaffEditor extends React.Component {
<FormField name="rpassword" validation="REPEAT_PASSWORD" required label={i18n('REPEAT_PASSWORD')} fieldProps={{size: 'large', password: true}}/> <FormField name="rpassword" validation="REPEAT_PASSWORD" required label={i18n('REPEAT_PASSWORD')} fieldProps={{size: 'large', password: true}}/>
<SubmitButton size="medium" className="staff-editor__submit-button">{i18n('UPDATE_PASSWORD')}</SubmitButton> <SubmitButton size="medium" className="staff-editor__submit-button">{i18n('UPDATE_PASSWORD')}</SubmitButton>
</Form> </Form>
{(this.props.myAccount) ? this.renderSendEmailOnNewTicketForm() : this.renderLevelForm()} {(myAccount) ? this.renderSendEmailOnNewTicketForm() : this.renderLevelForm()}
<span className="separator staff-editor__separator" /> <span className="separator staff-editor__separator" />
</div> </div>
</div> </div>
@ -109,7 +124,7 @@ class StaffEditor extends React.Component {
<div className="col-md-4"> <div className="col-md-4">
<div className="staff-editor__departments"> <div className="staff-editor__departments">
<div className="staff-editor__departments-title">{i18n('DEPARTMENTS')}</div> <div className="staff-editor__departments-title">{i18n('DEPARTMENTS')}</div>
{(this.props.myAccount && this.props.level !== 3) ? this.renderDepartmentsInfo() : this.renderDepartmentsForm()} {(myAccount && (level !== 3)) ? this.renderDepartmentsInfo() : this.renderDepartmentsForm()}
</div> </div>
</div> </div>
<div className="col-md-8"> <div className="col-md-8">
@ -119,38 +134,39 @@ class StaffEditor extends React.Component {
</div> </div>
</div> </div>
</div> </div>
{(this.props.tickets) ? this.renderTickets() : null} {(tickets) ? this.renderTickets() : null}
{(!this.props.myAccount) ? this.renderDelete() : null} {((!myAccount) && (userId !== staffId)) ? this.renderDelete() : null}
</div> </div>
); );
} }
renderMessage() { renderMessage() {
let messageType = (this.state.message === 'FAIL') ? 'error' : 'success'; const { message } = this.state;
let message = null; let messageType = (message === 'FAIL') ? 'error' : 'success';
let _message = null;
switch (this.state.message) { switch (message) {
case 'EMAIL': case 'EMAIL':
message = 'EMAIL_CHANGED'; _message = 'EMAIL_CHANGED';
break; break;
case 'PASSWORD': case 'PASSWORD':
message = 'PASSWORD_CHANGED'; _message = 'PASSWORD_CHANGED';
break; break;
case 'LEVEL': case 'LEVEL':
message = 'LEVEL_UPDATED'; _message = 'LEVEL_UPDATED';
break; break;
case 'DEPARTMENTS': case 'DEPARTMENTS':
message = 'DEPARTMENTS_UPDATED'; _message = 'DEPARTMENTS_UPDATED';
break; break;
case 'SEND_EMAIL_ON_NEW_TICKET': case 'SEND_EMAIL_ON_NEW_TICKET':
message = 'STAFF_UPDATED'; _message = 'STAFF_UPDATED';
break; break;
case 'FAIL': case 'FAIL':
message = 'FAILED_EDIT_STAFF'; _message = 'FAILED_EDIT_STAFF';
break; break;
} }
return <Message className="staff-editor__message" type={messageType}>{i18n(message)}</Message>; return <Message className="staff-editor__message" type={messageType}>{i18n(_message)}</Message>;
} }
renderSendEmailOnNewTicketForm() { renderSendEmailOnNewTicketForm() {
@ -244,11 +260,16 @@ class StaffEditor extends React.Component {
} }
getTicketListProps() { getTicketListProps() {
const {
staffId,
tickets,
departments
} = this.props;
return { return {
type: 'secondary', type: 'secondary',
userId: this.props.staffId, userId: staffId,
tickets: this.props.tickets, tickets: tickets,
departments: this.props.departments, departments: departments,
ticketPath: '/admin/panel/tickets/view-ticket/' ticketPath: '/admin/panel/tickets/view-ticket/'
}; };
} }
@ -267,7 +288,7 @@ class StaffEditor extends React.Component {
getDepartments() { getDepartments() {
return SessionStore.getDepartments().map(department => { return SessionStore.getDepartments().map(department => {
if(department.private * 1){ if(department.private*1){
return <span> {department.name} <Icon name='user-secret'/> </span> return <span> {department.name} <Icon name='user-secret'/> </span>
} else { } else {
return department.name; return department.name;
@ -295,6 +316,11 @@ class StaffEditor extends React.Component {
} }
onSubmit(eventType, form) { onSubmit(eventType, form) {
const {
myAccount,
staffId,
onChange
} = this.props;
let departments; let departments;
if(form.departments) { if(form.departments) {
@ -306,11 +332,11 @@ class StaffEditor extends React.Component {
API.call({ API.call({
path: '/staff/edit', path: '/staff/edit',
data: { data: {
staffId: (!this.props.myAccount) ? this.props.staffId : null, staffId: (!myAccount) ? staffId : null,
sendEmailOnNewTicket: (eventType === 'SEND_EMAIL_ON_NEW_TICKET') ? form.sendEmailOnNewTicket * 1 : null, sendEmailOnNewTicket: (eventType === 'SEND_EMAIL_ON_NEW_TICKET') ? form.sendEmailOnNewTicket * 1 : null,
email: (eventType === 'EMAIL') ? form.email : null, email: (eventType === 'EMAIL') ? form.email : null,
password: (eventType === 'PASSWORD') ? form.password : null, password: (eventType === 'PASSWORD') ? form.password : null,
level: (form.level !== undefined && eventType == 'LEVEL') ? form.level + 1 : null, level: ((form.level !== undefined) && (eventType == 'LEVEL')) ? form.level + 1 : null,
departments: (eventType === 'DEPARTMENTS') ? (departments && JSON.stringify(departments)) : null, departments: (eventType === 'DEPARTMENTS') ? (departments && JSON.stringify(departments)) : null,
} }
}).then(() => { }).then(() => {
@ -318,9 +344,7 @@ class StaffEditor extends React.Component {
window.scrollTo(0,0); window.scrollTo(0,0);
this.setState({message: eventType}); this.setState({message: eventType});
if(this.props.onChange) { onChange && onChange();
this.props.onChange();
}
}).catch(() => { }).catch(() => {
window.scrollTo(0,0); window.scrollTo(0,0);
this.setState({message: 'FAIL'}); this.setState({message: 'FAIL'});
@ -328,18 +352,27 @@ class StaffEditor extends React.Component {
} }
onDeleteClick() { onDeleteClick() {
const {
staffId,
onDelete
} = this.props;
return API.call({ return API.call({
path: '/staff/delete', path: '/staff/delete',
data: { data: {
staffId: this.props.staffId staffId: staffId
} }
}).then(this.props.onDelete).catch(() => { }).then(onDelete).catch(() => {
window.scrollTo(0,0); window.scrollTo(0,0);
this.setState({message: 'FAIL'}); this.setState({message: 'FAIL'});
}); });
} }
onProfilePicChange(event) { onProfilePicChange(event) {
const {
myAcount,
staffId,
onChange
} = this.props;
this.setState({ this.setState({
loadingPicture: true loadingPicture: true
}); });
@ -348,7 +381,7 @@ class StaffEditor extends React.Component {
path: '/staff/edit', path: '/staff/edit',
dataAsForm: true, dataAsForm: true,
data: { data: {
staffId: (!this.props.myAcount) ? this.props.staffId : null, staffId: (!myAcount) ? staffId : null,
file: event.target.files[0] file: event.target.files[0]
} }
}).then(() => { }).then(() => {
@ -356,9 +389,7 @@ class StaffEditor extends React.Component {
loadingPicture: false loadingPicture: false
}); });
if(this.props.onChange) { onChange && onChange();
this.props.onChange();
}
}).catch(() => { }).catch(() => {
window.scrollTo(0,0); window.scrollTo(0,0);
this.setState({message: 'FAIL', loadingPicture: false}); this.setState({message: 'FAIL', loadingPicture: false});

View File

@ -46,8 +46,7 @@ class DeleteStaffController extends Controller {
$staff = Staff::getDataStore($staffId); $staff = Staff::getDataStore($staffId);
if($staffId === Controller::getLoggedUser()->id) { if($staffId === Controller::getLoggedUser()->id) {
throw new RequestException(ERRORS::INVALID_STAFF); throw new RequestException(ERRORS::YOU_CAN_NOT_DELETE_YOURSELF);
return;
} }
foreach($staff->sharedTicketList as $ticket) { foreach($staff->sharedTicketList as $ticket) {

View File

@ -369,6 +369,7 @@ class ERRORS {
const INVALID_LEVEL = 'INVALID_LEVEL'; const INVALID_LEVEL = 'INVALID_LEVEL';
const ALREADY_A_STAFF = 'ALREADY_A_STAFF'; const ALREADY_A_STAFF = 'ALREADY_A_STAFF';
const INVALID_STAFF = 'INVALID_STAFF'; const INVALID_STAFF = 'INVALID_STAFF';
const YOU_CAN_NOT_DELETE_YOURSELF = 'YOU_CAN_NOT_DELETE_YOURSELF';
const SAME_DEPARTMENT = 'SAME_DEPARTMENT'; const SAME_DEPARTMENT = 'SAME_DEPARTMENT';
const INVALID_TOKEN = 'INVALID_TOKEN'; const INVALID_TOKEN = 'INVALID_TOKEN';
const UNVERIFIED_USER = 'UNVERIFIED_USER'; const UNVERIFIED_USER = 'UNVERIFIED_USER';