Paginate all ticket list request, avoid returting too much data
This commit is contained in:
parent
5f0996f243
commit
e8848d898e
|
@ -12,22 +12,22 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
retrieveMyTickets(closed = 0) {
|
||||
retrieveMyTickets(page, closed = 0) {
|
||||
return {
|
||||
type: 'MY_TICKETS',
|
||||
payload: API.call({
|
||||
path: '/staff/get-tickets',
|
||||
data: {closed}
|
||||
data: {page, closed}
|
||||
})
|
||||
};
|
||||
},
|
||||
|
||||
retrieveNewTickets() {
|
||||
retrieveNewTickets(page = 1) {
|
||||
return {
|
||||
type: 'NEW_TICKETS',
|
||||
payload: API.call({
|
||||
path: '/staff/get-new-tickets',
|
||||
data: {}
|
||||
data: {page}
|
||||
})
|
||||
};
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@ class AdminPanelAllTickets extends React.Component {
|
|||
state = {
|
||||
page: 1,
|
||||
query: '',
|
||||
closedTicketsShown: false
|
||||
closedTicketsShown: 0
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -46,7 +46,7 @@ class AdminPanelAllTickets extends React.Component {
|
|||
this.props.dispatch(AdminDataAction.retrieveAllTickets(
|
||||
this.state.page,
|
||||
this.state.query,
|
||||
this.state.closedTicketsShown*1
|
||||
this.state.closedTicketsShown * 1
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ class AdminPanelAllTickets extends React.Component {
|
|||
page: this.state.page,
|
||||
pages: this.props.pages,
|
||||
closedTicketsShown: this.state.closedTicketsShown,
|
||||
onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this)
|
||||
onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,15 +18,17 @@ class AdminPanelMyTickets extends React.Component {
|
|||
static defaultProps = {
|
||||
userId: 0,
|
||||
departments: [],
|
||||
tickets: []
|
||||
tickets: [],
|
||||
page: 1,
|
||||
pages: 0,
|
||||
};
|
||||
|
||||
state = {
|
||||
closedTicketsShown: false
|
||||
closedTicketsShown: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(AdminDataAction.retrieveMyTickets());
|
||||
this.retrieveMyTickets()
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -52,7 +54,10 @@ class AdminPanelMyTickets extends React.Component {
|
|||
loading: this.props.loading,
|
||||
ticketPath: '/admin/panel/tickets/view-ticket/',
|
||||
closedTicketsShown: this.state.closedTicketsShown,
|
||||
onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this)
|
||||
onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this),
|
||||
pages: this.props.pages,
|
||||
page: this.props.page,
|
||||
onPageChange: event => this.retrieveMyTickets(event.target.value)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -61,9 +66,7 @@ class AdminPanelMyTickets extends React.Component {
|
|||
return {
|
||||
closedTicketsShown: !state.closedTicketsShown
|
||||
};
|
||||
}, () => {
|
||||
this.props.dispatch(AdminDataAction.retrieveMyTickets(this.state.closedTicketsShown * 1));
|
||||
});
|
||||
}, () => this.retrieveMyTickets());
|
||||
}
|
||||
|
||||
onCreateTicket() {
|
||||
|
@ -79,7 +82,11 @@ class AdminPanelMyTickets extends React.Component {
|
|||
|
||||
onCreateTicketSuccess() {
|
||||
ModalContainer.closeModal();
|
||||
this.props.dispatch(AdminDataAction.retrieveMyTickets());
|
||||
this.retrieveMyTickets();
|
||||
}
|
||||
|
||||
retrieveMyTickets(page = this.props.page, closed = this.state.closedTicketsShown) {
|
||||
this.props.dispatch(AdminDataAction.retrieveMyTickets(page, closed * 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +95,8 @@ export default connect((store) => {
|
|||
userId: store.session.userId,
|
||||
departments: store.session.userDepartments,
|
||||
tickets: store.adminData.myTickets,
|
||||
page: store.adminData.myTicketsPage,
|
||||
pages: store.adminData.myTicketsPages,
|
||||
loading: !store.adminData.myTicketsLoaded,
|
||||
error: store.adminData.myTicketsError
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ class AdminPanelNewTickets extends React.Component {
|
|||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(AdminDataAction.retrieveNewTickets());
|
||||
this.retrieveNewTickets()
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -39,9 +39,16 @@ class AdminPanelNewTickets extends React.Component {
|
|||
tickets: this.props.tickets,
|
||||
type: 'secondary',
|
||||
loading: this.props.loading,
|
||||
ticketPath: '/admin/panel/tickets/view-ticket/'
|
||||
ticketPath: '/admin/panel/tickets/view-ticket/',
|
||||
page: this.props.page,
|
||||
pages: this.props.pages,
|
||||
onPageChange: event => this.retrieveNewTickets(event.target.value)
|
||||
};
|
||||
}
|
||||
|
||||
retrieveNewTickets(page = this.props.page) {
|
||||
this.props.dispatch(AdminDataAction.retrieveNewTickets(page));
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((store) => {
|
||||
|
@ -49,6 +56,8 @@ export default connect((store) => {
|
|||
userId: store.session.userId,
|
||||
departments: store.session.userDepartments,
|
||||
tickets: store.adminData.newTickets,
|
||||
page: store.adminData.newTicketsPage,
|
||||
pages: store.adminData.newTicketsPages,
|
||||
loading: !store.adminData.newTicketsLoaded,
|
||||
error: store.adminData.newTicketsError
|
||||
};
|
||||
|
|
|
@ -11,14 +11,20 @@ class AdminDataReducer extends Reducer {
|
|||
customResponsesLoaded: false,
|
||||
|
||||
myTickets: [],
|
||||
myTicketsPage: 1,
|
||||
myTicketsPages: 1,
|
||||
myTicketsLoaded: false,
|
||||
myTicketsError: false,
|
||||
|
||||
newTickets: [],
|
||||
newTicketsPage: 1,
|
||||
newTicketsPages: 1,
|
||||
newTicketsLoaded: false,
|
||||
newTicketsError: false,
|
||||
|
||||
allTickets: [],
|
||||
allTicketsPage: 1,
|
||||
allTicketsPages: 1,
|
||||
allTicketsLoaded: false,
|
||||
allTicketsError: false,
|
||||
|
||||
|
@ -61,7 +67,9 @@ class AdminDataReducer extends Reducer {
|
|||
|
||||
onMyTicketsRetrieved(state, payload) {
|
||||
return _.extend({}, state, {
|
||||
myTickets: payload.data,
|
||||
myTickets: payload.data.tickets,
|
||||
myTicketsPage: payload.data.page * 1,
|
||||
myTicketsPages: payload.data.pages * 1,
|
||||
myTicketsLoaded: true
|
||||
});
|
||||
}
|
||||
|
@ -82,7 +90,9 @@ class AdminDataReducer extends Reducer {
|
|||
|
||||
onNewTicketsRetrieved(state, payload) {
|
||||
return _.extend({}, state, {
|
||||
newTickets: payload.data,
|
||||
newTickets: payload.data.tickets,
|
||||
newTicketsPage: payload.data.page * 1,
|
||||
newTicketsPages: payload.data.pages * 1,
|
||||
newTicketsLoaded: true
|
||||
});
|
||||
}
|
||||
|
@ -104,7 +114,8 @@ class AdminDataReducer extends Reducer {
|
|||
onAllTicketsRetrieved(state, payload) {
|
||||
return _.extend({}, state, {
|
||||
allTickets: payload.data.tickets,
|
||||
allTicketsPages: payload.data.pages,
|
||||
allTicketsPage: payload.data.page * 1,
|
||||
allTicketsPages: payload.data.pages * 1,
|
||||
allTicketsLoaded: true
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ class GetAllTicketsStaffController extends Controller {
|
|||
}
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $this->getTicketList()->toArray(),
|
||||
'tickets' => $this->getTicketList()->toArray(true),
|
||||
'pages' => $this->getTotalPages()
|
||||
]);
|
||||
}
|
||||
|
@ -81,9 +81,14 @@ class GetAllTicketsStaffController extends Controller {
|
|||
}
|
||||
|
||||
private function getTotalPages() {
|
||||
$query = $this->getStaffDepartmentsQueryFilter();
|
||||
$query = $this->getSearchQuery();
|
||||
$query .= $this->getStaffDepartmentsQueryFilter();
|
||||
$query .= $this->getClosedFilter();
|
||||
|
||||
return ceil(Ticket::count($query) / 10);
|
||||
return ceil(Ticket::count($query, [
|
||||
Controller::request('query') . '%',
|
||||
'%' . Controller::request('query') . '%'
|
||||
]) / 10);
|
||||
}
|
||||
|
||||
private function getStaffDepartmentsQueryFilter() {
|
||||
|
|
|
@ -14,9 +14,15 @@ use Respect\Validation\Validator as DataValidator;
|
|||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiParam {Number} page The page number.
|
||||
*
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data Array of new tickets.
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Information about a tickets and quantity of pages.
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of new tickets of the current page.
|
||||
* @apiSuccess {Number} data.page Number of current page.
|
||||
* @apiSuccess {Number} data.pages Quantity of pages.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -27,7 +33,12 @@ class GetNewTicketsStaffController extends Controller {
|
|||
public function validations() {
|
||||
return[
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => []
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
public function handler() {
|
||||
|
@ -37,6 +48,8 @@ class GetNewTicketsStaffController extends Controller {
|
|||
}
|
||||
|
||||
$user = Controller::getLoggedUser();
|
||||
$page = Controller::request('page');
|
||||
|
||||
$query = ' (';
|
||||
foreach ($user->sharedDepartmentList as $department) {
|
||||
$query .= 'department_id=' . $department->id . ' OR ';
|
||||
|
@ -45,13 +58,22 @@ class GetNewTicketsStaffController extends Controller {
|
|||
$ownerExists = RedBean::exec('SHOW COLUMNS FROM ticket LIKE \'owner_id\'');
|
||||
|
||||
if($ownerExists != 0) {
|
||||
$query .= 'FALSE) AND owner_id IS NULL';
|
||||
$query .= 'FALSE) AND closed = 0 AND owner_id IS NULL';
|
||||
} else {
|
||||
$query .= 'FALSE)';
|
||||
$query .= 'FALSE) AND closed = 0';
|
||||
}
|
||||
|
||||
$countTotal = Ticket::count($query);
|
||||
|
||||
$query .= ' ORDER BY unread_staff DESC';
|
||||
$query .= ' LIMIT 10 OFFSET ' . ($page-1)*10;
|
||||
|
||||
$ticketList = Ticket::find($query);
|
||||
|
||||
Response::respondSuccess($ticketList->toArray());
|
||||
Response::respondSuccess([
|
||||
'tickets' => $ticketList->toArray(true),
|
||||
'page' => $page,
|
||||
'pages' => ceil($countTotal / 10)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,16 @@ use Respect\Validation\Validator as DataValidator;
|
|||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} page The page number.
|
||||
* @apiParam {bool} closed Include closed tickets in the response.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data Array of tickets assigned to the staff
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Information about a tickets and quantity of pages.
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of tickets assigned to the staff of the current page.
|
||||
* @apiSuccess {Number} data.page Number of current page.
|
||||
* @apiSuccess {Number} data.pages Quantity of pages.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -28,17 +33,33 @@ class GetTicketStaffController extends Controller {
|
|||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => []
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
$closed = Controller::request('closed');
|
||||
$page = Controller::request('page');
|
||||
$offset = ($page-1)*10;
|
||||
|
||||
if ($closed) {
|
||||
Response::respondSuccess($user->sharedTicketList->toArray());
|
||||
$tickets = $user->withCondition(' TRUE LIMIT 10 OFFSET ?', [$offset])->sharedTicketList->toArray(true);
|
||||
$countTotal = $user->countShared('ticket');
|
||||
} else {
|
||||
Response::respondSuccess($user->withCondition('closed = ?', ['0'])->sharedTicketList->toArray());
|
||||
$tickets = $user->withCondition(' closed = ? LIMIT 10 OFFSET ?', ['0', $offset])->sharedTicketList->toArray(true);
|
||||
$countTotal = $user->withCondition(' closed = ?', ['0'])->countShared('ticket');
|
||||
}
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $tickets,
|
||||
'page' => $page,
|
||||
'pages' => ceil($countTotal / 10)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ require_once 'models/DataStore.php';
|
|||
|
||||
class DataStoreList implements IteratorAggregate {
|
||||
private $list = [];
|
||||
|
||||
|
||||
public static function getList($type, $beanList) {
|
||||
$dataStoreList = new DataStoreList();
|
||||
|
||||
|
||||
foreach ($beanList as $bean) {
|
||||
$dataStoreList->add(new $type($bean));
|
||||
}
|
||||
|
||||
|
||||
return $dataStoreList;
|
||||
}
|
||||
|
||||
|
@ -51,21 +51,21 @@ class DataStoreList implements IteratorAggregate {
|
|||
|
||||
public function toBeanList() {
|
||||
$beanList = [];
|
||||
|
||||
|
||||
foreach($this->list as $item) {
|
||||
$item->updateBeanProperties();
|
||||
$beanList[] = $item->getBeanInstance();
|
||||
}
|
||||
|
||||
|
||||
return $beanList;
|
||||
}
|
||||
|
||||
public function toArray() {
|
||||
|
||||
public function toArray($minimized = false) {
|
||||
$array = [];
|
||||
|
||||
foreach($this->list as $item) {
|
||||
$item->updateBeanProperties();
|
||||
$array[] = $item->toArray();
|
||||
$array[] = $item->toArray($minimized);
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
@ -80,4 +80,4 @@ class DataStoreList implements IteratorAggregate {
|
|||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,13 +33,13 @@ abstract class DataStore {
|
|||
}
|
||||
public static function find($query = '', $matches = []) {
|
||||
$beanList = RedBean::find(static::TABLE, $query, $matches);
|
||||
|
||||
|
||||
return DataStoreList::getList(ucfirst(static::TABLE), $beanList);
|
||||
}
|
||||
|
||||
|
||||
public static function findOne($query = '', $matches = []) {
|
||||
$bean = RedBean::findOne(static::TABLE, $query, $matches);
|
||||
|
||||
|
||||
return ($bean) ? new static($bean) : new NullDataStore();
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,11 @@ abstract class DataStore {
|
|||
}
|
||||
|
||||
public function withCondition($condition, $values) {
|
||||
return new static($this->_bean->withCondition($condition, $values));
|
||||
return new static($this->_bean->withCondition($condition, $values));
|
||||
}
|
||||
|
||||
public function countShared($shared) {
|
||||
return $this->_bean->countShared($shared);
|
||||
}
|
||||
|
||||
private function updateBeanProp($key, $value) {
|
||||
|
|
|
@ -2,13 +2,14 @@ describe '/staff/get-new-tickets' do
|
|||
request('/user/logout')
|
||||
Scripts.login($staff[:email], $staff[:password], true)
|
||||
|
||||
it 'should get news tickets' do
|
||||
it 'should get new tickets' do
|
||||
result = request('/staff/get-new-tickets', {
|
||||
page: 1,
|
||||
csrf_userid: $csrf_userid,
|
||||
csrf_token: $csrf_token
|
||||
})
|
||||
|
||||
(result['status']).should.equal('success')
|
||||
(result['data'].size).should.equal(9)
|
||||
(result['data']['tickets'].size).should.equal(8)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,21 +7,24 @@ describe '/staff/get-tickets' do
|
|||
ticket = $database.getRow('ticket', 1 , 'id')
|
||||
request('/staff/assign-ticket', {
|
||||
ticketNumber: ticket['ticket_number'],
|
||||
page: 1,
|
||||
csrf_userid: $csrf_userid,
|
||||
csrf_token: $csrf_token
|
||||
})
|
||||
ticket = $database.getRow('ticket', 2 , 'id')
|
||||
request('/staff/assign-ticket', {
|
||||
ticketNumber: ticket['ticket_number'],
|
||||
page: 1,
|
||||
csrf_userid: $csrf_userid,
|
||||
csrf_token: $csrf_token
|
||||
})
|
||||
result = request('/staff/get-tickets', {
|
||||
page: 1,
|
||||
csrf_userid: $csrf_userid,
|
||||
csrf_token: $csrf_token
|
||||
})
|
||||
|
||||
(result['status']).should.equal('success')
|
||||
(result['data'].size).should.equal(5)
|
||||
(result['data']['tickets'].size).should.equal(5)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue