mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-31 01:35:15 +02:00
Add more descriptive error messages when in delete staff. (#892)
This commit is contained in:
parent
b73d6d534d
commit
994a39ad6d
@ -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() {
|
||||||
|
@ -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});
|
||||||
|
@ -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) {
|
||||||
|
@ -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';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user