mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-28 16:24:42 +02:00
Fix bug in ticket list in my account and view staff (#921)
* wip * Delete ticket of staff/get.php response * Move paginate functions to staff editor component * wip * fix assignedTickets and closedTickets values in staff/get-all * add show closed tickets checkbox in admin panel my account * WIP * Add initial api value * Fix staff/get-all test * WIP
This commit is contained in:
parent
9feb7d6cd4
commit
15f765cf85
@ -3,7 +3,6 @@ import {connect} from 'react-redux';
|
||||
import _ from 'lodash';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import API from 'lib-app/api-call';
|
||||
import SessionActions from 'actions/session-actions';
|
||||
|
||||
import StaffEditor from 'app/admin/panel/staff/staff-editor';
|
||||
|
@ -67,6 +67,7 @@ class AdminPanelViewStaff extends React.Component {
|
||||
params,
|
||||
dispatch
|
||||
} = this.props;
|
||||
|
||||
this.setState({
|
||||
loading: false,
|
||||
userData: result.data
|
||||
|
@ -20,6 +20,12 @@ import Button from 'core-components/button';
|
||||
import Icon from 'core-components/icon';
|
||||
import Loading from 'core-components/loading';
|
||||
|
||||
const INITIAL_API_VALUE = {
|
||||
page: 1,
|
||||
closed: 0,
|
||||
departments: undefined,
|
||||
};
|
||||
|
||||
class StaffEditor extends React.Component {
|
||||
static propTypes = {
|
||||
myAccount: React.PropTypes.bool,
|
||||
@ -29,41 +35,49 @@ class StaffEditor extends React.Component {
|
||||
name: React.PropTypes.string.isRequired,
|
||||
profilePic: React.PropTypes.string.isRequired,
|
||||
level: React.PropTypes.number.isRequired,
|
||||
tickets: React.PropTypes.array.isRequired,
|
||||
departments: React.PropTypes.array.isRequired,
|
||||
sendEmailOnNewTicket: React.PropTypes.bool,
|
||||
onChange: React.PropTypes.func,
|
||||
onDelete: React.PropTypes.func
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
tickets: []
|
||||
};
|
||||
|
||||
state = {
|
||||
email: this.props.email,
|
||||
level: this.props.level - 1,
|
||||
message: null,
|
||||
loadingPicture: false,
|
||||
tickets: [],
|
||||
page: 1,
|
||||
pages: 0,
|
||||
department: undefined,
|
||||
departments: this.getUserDepartments(),
|
||||
closedTicketsShown: false,
|
||||
sendEmailOnNewTicket: this.props.sendEmailOnNewTicket
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.retrieveStaffMembers();
|
||||
this.retrieveTicketsAssigned(INITIAL_API_VALUE);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
name,
|
||||
level,
|
||||
tickets,
|
||||
profilePic,
|
||||
myAccount,
|
||||
staffId,
|
||||
staffList,
|
||||
userId
|
||||
} = this.props;
|
||||
const {
|
||||
message,
|
||||
tickets,
|
||||
loadingPicture,
|
||||
email
|
||||
} = this.state;
|
||||
const myData = _.filter(staffList, {id: `${staffId}`})[0];
|
||||
|
||||
return (
|
||||
<div className="staff-editor">
|
||||
{message ? this.renderMessage() : null}
|
||||
@ -83,13 +97,13 @@ class StaffEditor extends React.Component {
|
||||
</div>
|
||||
<div className="staff-editor__card-badge">
|
||||
<span className="staff-editor__card-badge-green">
|
||||
{_.filter(tickets, {closed: false}).length}
|
||||
{myData.assignedTickets}
|
||||
</span>
|
||||
<span className="staff-editor__card-badge-text">{i18n('ASSIGNED')}</span>
|
||||
</div>
|
||||
<div className="staff-editor__card-badge">
|
||||
<span className="staff-editor__card-badge-red">
|
||||
{_.filter(tickets, {closed: true}).length}
|
||||
{myData.closedTickets}
|
||||
</span>
|
||||
<span className="staff-editor__card-badge-text">{i18n('CLOSED')}</span>
|
||||
</div>
|
||||
@ -227,7 +241,7 @@ class StaffEditor extends React.Component {
|
||||
<div>
|
||||
<span className="separator" />
|
||||
<div className="staff-editor__tickets">
|
||||
<div className="staff-editor__tickets-title">{i18n('TICKETS')}</div>
|
||||
<div className="staff-editor__tickets-title">{i18n('TICKETS_ASSIGNED')}</div>
|
||||
<TicketList {...this.getTicketListProps()} />
|
||||
</div>
|
||||
</div>
|
||||
@ -262,15 +276,27 @@ class StaffEditor extends React.Component {
|
||||
getTicketListProps() {
|
||||
const {
|
||||
staffId,
|
||||
tickets,
|
||||
departments
|
||||
} = this.props;
|
||||
const {
|
||||
tickets,
|
||||
page,
|
||||
pages,
|
||||
closedTicketsShown
|
||||
} = this.state;
|
||||
|
||||
return {
|
||||
type: 'secondary',
|
||||
userId: staffId,
|
||||
tickets: tickets,
|
||||
departments: departments,
|
||||
ticketPath: '/admin/panel/tickets/view-ticket/'
|
||||
tickets,
|
||||
departments,
|
||||
closedTicketsShown,
|
||||
ticketPath: '/admin/panel/tickets/view-ticket/',
|
||||
page,
|
||||
pages,
|
||||
onPageChange: this.onPageChange.bind(this),
|
||||
onDepartmentChange: this.onDepartmentChange.bind(this),
|
||||
onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this)
|
||||
};
|
||||
}
|
||||
|
||||
@ -337,7 +363,7 @@ class StaffEditor extends React.Component {
|
||||
email: (eventType === 'EMAIL') ? form.email : null,
|
||||
password: (eventType === 'PASSWORD') ? form.password : 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(() => {
|
||||
this.retrieveStaffMembers();
|
||||
@ -396,9 +422,78 @@ class StaffEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
retrieveTicketsAssigned({page, department, closed}) {
|
||||
API.call({
|
||||
path: '/ticket/search',
|
||||
data: {
|
||||
page,
|
||||
departments: department,
|
||||
closed,
|
||||
owners: `[${this.props.staffId}]`
|
||||
}
|
||||
}).then((result) => {
|
||||
const data = result.data;
|
||||
|
||||
this.setState({
|
||||
tickets: data.tickets,
|
||||
page: data.page,
|
||||
pages: data.pages
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onPageChange(event) {
|
||||
this.setState({
|
||||
page: event.target.value
|
||||
});
|
||||
|
||||
this.retrieveTicketsAssigned({page: event.target.value});
|
||||
}
|
||||
|
||||
onDepartmentChange(department) {
|
||||
const { closedTicketsShown } = this.state;
|
||||
|
||||
this.setState({
|
||||
department
|
||||
});
|
||||
|
||||
this.retrieveTicketsAssigned(this.prepareFiltersForAPI({
|
||||
newClosedFilter: closedTicketsShown,
|
||||
newDepartmentFilter: department
|
||||
}));
|
||||
}
|
||||
|
||||
onClosedTicketsShownChange() {
|
||||
const {
|
||||
department,
|
||||
closedTicketsShown
|
||||
} = this.state;
|
||||
const newClosedValue = !closedTicketsShown;
|
||||
|
||||
this.setState({
|
||||
closedTicketsShown: newClosedValue
|
||||
});
|
||||
|
||||
this.retrieveTicketsAssigned(this.prepareFiltersForAPI({
|
||||
newClosedFilter: newClosedValue,
|
||||
newDepartmentFilter: department
|
||||
}));
|
||||
}
|
||||
|
||||
retrieveStaffMembers() {
|
||||
this.props.dispatch(AdminDataActions.retrieveStaffMembers());
|
||||
}
|
||||
|
||||
prepareFiltersForAPI({newClosedFilter, newDepartmentFilter}) {
|
||||
return {
|
||||
closed: newClosedFilter ? undefined : 0,
|
||||
department: newDepartmentFilter ? `[${newDepartmentFilter}]` : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(StaffEditor);
|
||||
export default connect((store) => {
|
||||
return {
|
||||
staffList: store.adminData.staffMembers
|
||||
};
|
||||
})(StaffEditor);
|
||||
|
@ -121,6 +121,7 @@ export default {
|
||||
'DELETE_AND_BAN': 'Delete and ban',
|
||||
'STAFF_LEVEL': 'Staff Level',
|
||||
'ASSIGNED': 'Assigned',
|
||||
'TICKETS_ASSIGNED': 'Tickets assigned',
|
||||
'ASSIGNED_TICKETS': '{tickets} assigned tickets',
|
||||
'CLOSED_TICKETS': '{tickets} closed tickets',
|
||||
'LAST_LOGIN': 'Last login',
|
||||
|
@ -40,8 +40,8 @@ class GetAllStaffController extends Controller {
|
||||
$closedTickets = 0;
|
||||
|
||||
foreach ($staff->sharedTicketList as $ticket) {
|
||||
if($ticket->closed) $closedTickets++;
|
||||
else $assignedTickets++;
|
||||
if(($ticket->closed) && ($ticket->owner_id == $staff->id)) $closedTickets++;
|
||||
if($ticket->owner_id == $staff->id) $assignedTickets++;
|
||||
}
|
||||
|
||||
$staffArray[] = [
|
||||
|
@ -25,7 +25,6 @@ DataValidator::with('CustomValidations', true);
|
||||
* @apiSuccess {Number} data.level Level of staff member
|
||||
* @apiSuccess {Boolean} data.staff Indicates that it is a staff (always true)
|
||||
* @apiSuccess {[Department](#api-Data_Structures-ObjectDepartment)[]} data.departments Array of departments that has assigned.
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of tickets that has assigned.
|
||||
* @apiSuccess {Boolean} data.sendEmailOnNewTicket Indicates if this member receives a mail when a ticket is created.
|
||||
*
|
||||
*/
|
||||
@ -69,7 +68,6 @@ class GetStaffController extends Controller {
|
||||
'level' => $user->level,
|
||||
'staff' => true,
|
||||
'departments' => $parsedDepartmentList,
|
||||
'tickets' => $user->sharedTicketList->toArray(true),
|
||||
'sendEmailOnNewTicket' => $user->sendEmailOnNewTicket
|
||||
]);
|
||||
}
|
||||
|
@ -2,6 +2,25 @@ describe '/staff/assign-ticket' do
|
||||
request('/user/logout')
|
||||
Scripts.login($staff[:email], $staff[:password], true)
|
||||
|
||||
Scripts.createTicket('ticket_to_assing_1')
|
||||
Scripts.createTicket('ticket_to_assing_2')
|
||||
Scripts.createTicket('ticket_to_assing_3')
|
||||
Scripts.createTicket('ticket_to_assing_4')
|
||||
Scripts.createTicket('ticket_to_assing_5')
|
||||
Scripts.createTicket('ticket_to_assing_6')
|
||||
Scripts.createTicket('ticket_to_assing_7')
|
||||
Scripts.createTicket('ticket_to_assing_8')
|
||||
Scripts.createTicket('ticket_to_assing_9')
|
||||
Scripts.createTicket('ticket_to_assing_10')
|
||||
Scripts.createTicket('ticket_to_assing_11')
|
||||
Scripts.createTicket('ticket_to_assing_12')
|
||||
Scripts.createTicket('ticket_to_assing_13')
|
||||
Scripts.createTicket('ticket_to_assing_14')
|
||||
Scripts.createTicket('ticket_to_assing_15')
|
||||
Scripts.createTicket('ticket_to_assing_16')
|
||||
Scripts.createTicket('ticket_to_assing_17')
|
||||
Scripts.createTicket('ticket_to_assing_18')
|
||||
|
||||
#TODO: Create a staff without all department
|
||||
|
||||
#it 'should fail if staff is not in the same department'do
|
||||
@ -9,7 +28,49 @@ describe '/staff/assign-ticket' do
|
||||
#end
|
||||
|
||||
it 'should assign ticket if everything is okey' do
|
||||
ticket = $database.getRow('ticket', 1 , 'id')
|
||||
ticket1 = $database.getRow('ticket', 'ticket_to_assing_1', 'title')
|
||||
ticket2 = $database.getRow('ticket', 'ticket_to_assing_2', 'title')
|
||||
ticket3 = $database.getRow('ticket', 'ticket_to_assing_3', 'title')
|
||||
ticket4 = $database.getRow('ticket', 'ticket_to_assing_4', 'title')
|
||||
ticket5 = $database.getRow('ticket', 'ticket_to_assing_5', 'title')
|
||||
ticket6 = $database.getRow('ticket', 'ticket_to_assing_6', 'title')
|
||||
ticket7 = $database.getRow('ticket', 'ticket_to_assing_7', 'title')
|
||||
ticket8 = $database.getRow('ticket', 'ticket_to_assing_8', 'title')
|
||||
ticket9 = $database.getRow('ticket', 'ticket_to_assing_9', 'title')
|
||||
ticket10 = $database.getRow('ticket', 'ticket_to_assing_10', 'title')
|
||||
ticket11 = $database.getRow('ticket', 'ticket_to_assing_11', 'title')
|
||||
ticket12 = $database.getRow('ticket', 'ticket_to_assing_12', 'title')
|
||||
ticket13 = $database.getRow('ticket', 'ticket_to_assing_13', 'title')
|
||||
ticket14 = $database.getRow('ticket', 'ticket_to_assing_14', 'title')
|
||||
ticket15 = $database.getRow('ticket', 'ticket_to_assing_15', 'title')
|
||||
ticket16 = $database.getRow('ticket', 'ticket_to_assing_16', 'title')
|
||||
ticket17 = $database.getRow('ticket', 'ticket_to_assing_17', 'title')
|
||||
ticket18 = $database.getRow('ticket', 'ticket_to_assing_18', 'title')
|
||||
ticket_with_id_1 = $database.getRow('ticket', 1 , 'id')
|
||||
|
||||
tickets = [
|
||||
ticket1,
|
||||
ticket2,
|
||||
ticket3,
|
||||
ticket4,
|
||||
ticket5,
|
||||
ticket6,
|
||||
ticket7,
|
||||
ticket8,
|
||||
ticket9,
|
||||
ticket10,
|
||||
ticket11,
|
||||
ticket12,
|
||||
ticket13,
|
||||
ticket14,
|
||||
ticket15,
|
||||
ticket16,
|
||||
ticket17,
|
||||
ticket18,
|
||||
ticket_with_id_1
|
||||
]
|
||||
|
||||
for ticket in tickets
|
||||
result = request('/staff/assign-ticket', {
|
||||
ticketNumber: ticket['ticket_number'],
|
||||
csrf_userid: $csrf_userid,
|
||||
@ -18,17 +79,15 @@ describe '/staff/assign-ticket' do
|
||||
|
||||
(result['status']).should.equal('success')
|
||||
|
||||
ticket = $database.getRow('ticket', 1 , 'id')
|
||||
ticket = $database.getRow('ticket', ticket['ticket_number'], 'ticket_number')
|
||||
|
||||
(ticket['owner_id']).should.equal(1)
|
||||
|
||||
(ticket['unread']).should.equal(1)
|
||||
|
||||
staff_ticket = $database.getRow('staff_ticket', 1 , 'ticket_id')
|
||||
staff_ticket = $database.getRow('staff_ticket', ticket['id'].to_i , 'ticket_id')
|
||||
|
||||
(staff_ticket['staff_id']).should.equal(1)
|
||||
|
||||
(staff_ticket['ticket_id']).should.equal(1)
|
||||
(staff_ticket['ticket_id']).should.equal(ticket['id'])
|
||||
end
|
||||
end
|
||||
it 'should assign ticket if a staff choose another to assing a ticket ' do
|
||||
staffId = $database.getRow('staff','ayra2@opensupports.com','email')['id']
|
||||
|
@ -46,7 +46,7 @@ describe 'Retrieve all tickets' do
|
||||
})
|
||||
|
||||
(response['status']).should.equal('success')
|
||||
(response['data']['pages']).should.equal(5)
|
||||
(response['data']['pages']).should.equal(7)
|
||||
(response['data']['tickets'].size).should.equal(10)
|
||||
(response['data']['tickets'][0]['title']).should.equal('Quisque egestas ipsum')
|
||||
(response['data']['tickets'][1]['title']).should.equal('placerat id velit')
|
||||
@ -68,7 +68,7 @@ describe 'Retrieve all tickets' do
|
||||
})
|
||||
|
||||
(response['status']).should.equal('success')
|
||||
(response['data']['pages']).should.equal(5)
|
||||
(response['data']['pages']).should.equal(7)
|
||||
(response['data']['tickets'].size).should.equal(10)
|
||||
(response['data']['tickets'][0]['title']).should.equal('quis vulputate lectus feugiat eu')
|
||||
(response['data']['tickets'][1]['title']).should.equal('Fusce venenatis iaculis commodo')
|
||||
|
@ -24,8 +24,8 @@ describe'/staff/get-all' do
|
||||
(result['data'][0]['departments'][1]['name']).should.equal('useless private deapartment')
|
||||
(result['data'][0]['departments'][2]['id']).should.equal('3')
|
||||
(result['data'][0]['departments'][2]['name']).should.equal('Suggestions')
|
||||
(result['data'][0]['assignedTickets']).should.equal(10)
|
||||
(result['data'][0]['closedTickets']).should.equal(1)
|
||||
(result['data'][0]['assignedTickets']).should.equal(22)
|
||||
(result['data'][0]['closedTickets']).should.equal(0)
|
||||
|
||||
(result['data'][2]['name']).should.equal('Arya Stark')
|
||||
(result['data'][2]['email']).should.equal('ayra2@opensupports.com')
|
||||
|
@ -25,6 +25,6 @@ describe '/staff/get-tickets' do
|
||||
})
|
||||
|
||||
(result['status']).should.equal('success')
|
||||
(result['data']['tickets'].size).should.equal(9)
|
||||
(result['data']['tickets'].size).should.equal(10)
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user