Add staff dropdown for assignment

This commit is contained in:
Ivan Diaz 2018-07-27 20:36:35 -03:00
parent 99ea7e0f8a
commit dda8e28e93
6 changed files with 131 additions and 48 deletions

View File

@ -1,7 +1,7 @@
import API from 'lib-app/api-call';
export default {
retrieveCustomResponses() {
return {
type: 'CUSTOM_RESPONSES',
@ -42,6 +42,16 @@ export default {
};
},
retrieveStaffMembers() {
return {
type: 'STAFF_MEMBERS',
payload: API.call({
path: '/staff/get-all',
data: {}
})
};
},
searchTickets(query, page = 1) {
return {
type: 'ALL_TICKETS',
@ -51,4 +61,4 @@ export default {
})
};
}
};
};

View File

@ -2,6 +2,8 @@ import React from 'react';
import _ from 'lodash';
import {connect} from 'react-redux';
import AdminDataActions from 'actions/admin-data-actions';
import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
import SessionStore from 'lib-app/session-store';
@ -24,7 +26,9 @@ class TicketViewer extends React.Component {
onChange: React.PropTypes.func,
editable: React.PropTypes.bool,
customResponses: React.PropTypes.array,
assignmentAllowed: React.PropTypes.bool
assignmentAllowed: React.PropTypes.bool,
staffMembers: React.PropTypes.array,
staffMembersLoaded: React.PropTypes.bool,
};
static defaultProps = {
@ -42,6 +46,12 @@ class TicketViewer extends React.Component {
commentEdited: false
};
componentDidMount() {
if(!this.props.staffMembersLoaded && this.props.editable) {
this.props.dispatch(AdminDataActions.retrieveStaffMembers());
}
}
render() {
const ticket = this.props.ticket;
@ -84,7 +94,7 @@ class TicketViewer extends React.Component {
<div className="ticket-viewer__headers">
<div className="ticket-viewer__info-row-header row">
<div className="col-md-4">{i18n('DEPARTMENT')}</div>
<div className=" col-md-4">{i18n('AUTHOR')}</div>
<div className="col-md-4">{i18n('AUTHOR')}</div>
<div className="col-md-4">{i18n('DATE')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
@ -165,11 +175,7 @@ class TicketViewer extends React.Component {
let {ticket, userId} = this.props;
if (_.isEmpty(ticket.owner) || ticket.owner.id == userId) {
ownerNode = (
<Button type={(ticket.owner) ? 'primary' : 'secondary'} size="extra-small" onClick={this.onAssignClick.bind(this)}>
{i18n(ticket.owner ? 'UN_ASSIGN' : 'ASSIGN_TO_ME')}
</Button>
);
ownerNode = this.renderAssignStaffList();
} else {
ownerNode = (this.props.ticket.owner) ? this.props.ticket.owner.name : i18n('NONE')
}
@ -193,6 +199,18 @@ class TicketViewer extends React.Component {
return ownerNode;
}
renderAssignStaffList() {
const items = this.getStaffAssignmentItems();
const ownerId = this.props.ticket.owner && this.props.ticket.owner.id;
return (
<DropDown
className="ticket-viewer__editable-dropdown" items={items}
selectedIndex={ownerId && _.findIndex(items, {id: ownerId})}
onChange={this.onAssignmentChange.bind(this)}
/>
);
}
renderTicketEvent(options, index) {
return (
<TicketEvent {...options} author={(!_.isEmpty(options.author)) ? options.author : this.props.ticket.author} key={index} />
@ -265,6 +283,23 @@ class TicketViewer extends React.Component {
};
}
getStaffAssignmentItems() {
const {staffMembers, userId} = this.props;
let staffAssignmentItems = [
{content: 'None', id: 0},
{content: 'Assign to me', id: userId}
];
staffAssignmentItems = staffAssignmentItems.concat(
_.map(
_.filter(staffMembers, ({id}) => (id != userId)),
({id, name}) => ({content: name, id})
)
);
return staffAssignmentItems;
}
onDepartmentDropdownChanged(event) {
AreYouSure.openModal(null, this.changeDepartment.bind(this, event.index));
}
@ -273,12 +308,17 @@ class TicketViewer extends React.Component {
AreYouSure.openModal(null, this.changePriority.bind(this, event.index));
}
onAssignClick() {
onAssignmentChange(event) {
AreYouSure.openModal(null, this.assingTo.bind(this, event.index));
}
assingTo(index) {
const id = this.getStaffAssignmentItems()[index].id;
const {ticketNumber} = this.props.ticket;
API.call({
path: (this.props.ticket.owner) ? '/staff/un-assign-ticket' : '/staff/assign-ticket',
data: {
ticketNumber: this.props.ticket.ticketNumber
}
path: (index == 0) ? '/staff/un-assign-ticket' : '/staff/assign-ticket',
data: { ticketNumber, staffId: id }
}).then(this.onTicketModification.bind(this));
}
@ -387,6 +427,8 @@ class TicketViewer extends React.Component {
export default connect((store) => {
return {
userId: store.session.userId,
staffMembers: store.adminData.staffMembers,
staffMembersLoaded: store.adminData.staffMembersLoaded,
allowAttachments: store.config['allow-attachments'],
userSystemEnabled: store.config['user-system-enabled']
};

View File

@ -1,6 +1,9 @@
import React from 'react';
import {Link} from 'react-router';
import _ from 'lodash';
import {connect} from 'react-redux';
import AdminDataActions from 'actions/admin-data-actions';
import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
@ -18,15 +21,23 @@ import Loading from 'core-components/loading';
class AdminPanelStaffMembers extends React.Component {
state = {
selectedDepartment: 0,
static propTypes = {
staffList: React.PropTypes.array,
loading: React.PropTypes.boolean,
}
static defaultProps = {
staffList: [],
loading: true,
};
state = {
selectedDepartment: 0,
page: 1
};
componentDidMount() {
this.retrieveStaffMembers();
this.props.dispatch(AdminDataActions.retrieveStaffMembers());
}
render() {
@ -39,7 +50,7 @@ class AdminPanelStaffMembers extends React.Component {
<Icon name="user-plus" className=""/> {i18n('ADD_NEW_STAFF')}
</Button>
</div>
{(this.state.loading) ? <Loading backgrounded /> : <PeopleList list={this.getStaffList()} page={this.state.page} onPageSelect={(index) => this.setState({page: index+1})} />}
{(this.props.loading) ? <Loading backgrounded /> : <PeopleList list={this.getStaffList()} page={this.state.page} onPageSelect={(index) => this.setState({page: index+1})} />}
</div>
);
}
@ -66,9 +77,9 @@ class AdminPanelStaffMembers extends React.Component {
let staffList;
if(!this.state.selectedDepartment) {
staffList = this.state.staffList;
staffList = this.props.staffList;
} else {
staffList = _.filter(this.state.staffList, (staff) => {
staffList = _.filter(this.props.staffList, (staff) => {
return _.findIndex(staff.departments, {id: this.state.selectedDepartment}) !== -1;
});
}
@ -96,22 +107,12 @@ class AdminPanelStaffMembers extends React.Component {
return departments;
}
retrieveStaffMembers() {
API.call({
path: '/staff/get-all',
data: {}
}).then(this.onStaffRetrieved.bind(this));
}
onStaffRetrieved(result) {
if(result.status == 'success'){
this.setState({
loading: false,
staffList: result.data
});
}
}
}
export default AdminPanelStaffMembers;
export default connect((store) => {
return {
staffList: store.adminData.staffMembers,
loading: !store.adminData.staffMembersLoaded,
error: store.adminData.staffMembersError
};
})(AdminPanelStaffMembers);

View File

@ -99,7 +99,7 @@ module.exports = [
title: 'Lorem ipsum door',
content: 'I had a problem with the installation of the php server',
department: {
id: 1,
id: '1',
name: 'Sales Support'
},
date: '201604151155',
@ -110,12 +110,12 @@ module.exports = [
closed: false,
priority: 'medium',
author: {
id: 3,
id: '3',
name: 'Haskell Curry',
email: 'haskell@lambda.com'
},
owner: {
id: 1,
id: '12',
name: 'Steve Jobs'
},
events: [

View File

@ -9,6 +9,7 @@ class AdminDataReducer extends Reducer {
return {
customResponses: [],
customResponsesLoaded: false,
myTickets: [],
myTicketsLoaded: false,
myTicketsError: false,
@ -19,7 +20,11 @@ class AdminDataReducer extends Reducer {
allTickets: [],
allTicketsLoaded: false,
allTicketsError: false
allTicketsError: false,
staffMembers: [],
staffMembersLoaded: false,
staffMembersError: false,
};
}
@ -37,7 +42,11 @@ class AdminDataReducer extends Reducer {
'ALL_TICKETS_FULFILLED': this.onAllTicketsRetrieved,
'ALL_TICKETS_REJECTED': this.onAllTicketsRejected,
'ALL_TICKETS_PENDING': this.onAllTicketsPending
'ALL_TICKETS_PENDING': this.onAllTicketsPending,
'STAFF_MEMBERS_FULFILLED': this.onStaffMembersRetrieved,
'STAFF_MEMBERS_REJECTED': this.onStaffMembersRejected,
'STAFF_MEMBERS_PENDING': this.onStaffMembersPending
};
}
@ -102,7 +111,7 @@ class AdminDataReducer extends Reducer {
onAllTicketsRejected(state) {
return _.extend({}, state, {
allTicketsError: false,
allTicketsError: true,
allTicketsLoaded: false
});
}
@ -113,6 +122,27 @@ class AdminDataReducer extends Reducer {
allTicketsLoaded: false
});
}
onStaffMembersRetrieved(state, payload) {
return _.extend({}, state, {
staffMembers: payload.data,
staffMembersLoaded: true
});
}
onStaffMembersRejected(state) {
return _.extend({}, state, {
staffMembersError: true,
staffMembersLoaded: false
});
}
onStaffMembersPending(state) {
return _.extend({}, state, {
staffMembersError: false,
staffMembersLoaded: false
});
}
}
export default AdminDataReducer.getInstance();
export default AdminDataReducer.getInstance();

View File

@ -12,7 +12,7 @@ use Respect\Validation\Validator as DataValidator;
* @apiDescription This path retrieves information about all the staff member.
*
* @apiPermission staff3
*
*
* @apiUse NO_PERMISSION
*
* @apiSuccess {[Staff](#api-Data_Structures-ObjectStaff)[]} data Array of staff members.
@ -25,7 +25,7 @@ class GetAllStaffController extends Controller {
public function validations() {
return [
'permission' => 'staff_3',
'permission' => 'staff_1',
'requestData' => []
];
}
@ -58,6 +58,6 @@ class GetAllStaffController extends Controller {
}
Response::respondSuccess($staffArray);
}
}
}