From 8dd11af96bb65bfb637ec6833b998d8480821fbf Mon Sep 17 00:00:00 2001 From: AntonyAntonio Date: Mon, 5 Dec 2016 23:17:18 -0300 Subject: [PATCH 01/22] Guillermo - path / staff/add[skip ci] --- server/controllers/staff.php | 2 + server/controllers/staff/add.php | 76 ++++++++++++++++++++++++++++++++ server/data/ERRORS.php | 2 + 3 files changed, 80 insertions(+) create mode 100644 server/controllers/staff/add.php diff --git a/server/controllers/staff.php b/server/controllers/staff.php index aafedcbd..c7cf0e91 100644 --- a/server/controllers/staff.php +++ b/server/controllers/staff.php @@ -6,6 +6,7 @@ require_once 'staff/get-tickets.php'; require_once 'staff/get-new-tickets.php'; require_once 'staff/get-all-tickets.php'; require_once 'staff/search-tickets.php'; +require_once 'staff/add.php'; $systemControllerGroup = new ControllerGroup(); $systemControllerGroup->setGroupPath('/staff'); @@ -17,5 +18,6 @@ $systemControllerGroup->addController(new GetTicketStaffController); $systemControllerGroup->addController(new GetNewTicketsStaffController); $systemControllerGroup->addController(new GetAllTicketsStaffController); $systemControllerGroup->addController(new SearchTicketStaffController); +$systemControllerGroup->addController(new AddStaffController); $systemControllerGroup->finalize(); \ No newline at end of file diff --git a/server/controllers/staff/add.php b/server/controllers/staff/add.php new file mode 100644 index 00000000..63183974 --- /dev/null +++ b/server/controllers/staff/add.php @@ -0,0 +1,76 @@ + 'staff_3', + 'requestData' => [ + 'name' => [ + 'validation' => DataValidator::length(2, 55)->alpha(), + 'error' => ERRORS::INVALID_NAME + ], + 'email' => [ + 'validation' => DataValidator::email(), + 'error' => ERRORS::INVALID_EMAIL + ], + 'password' => [ + 'validation' => DataValidator::length(5, 200), + 'error' => ERRORS::INVALID_PASSWORD + ], + 'level' => [ + 'validation' => DataValidator::between(1, 3, true), + 'error' => ERRORS::INVALID_LEVEL + ] + + ] + ]; + } + + public function handler() { + + $this->storeRequestData(); + $staff = new Staff(); + + $staffrow = Staff::getDataStore($this->email,'email'); + + if($staffrow->isNull()) { + $staff->setProperties([ + 'name'=> $this->name, + 'email' => $this->email, + 'password'=> $this->password, + 'profilePic' => $this->profilePic, + 'level' => $this->level, + 'sharedDepartmentList'=> $this->departments, + ]); + + $staff->store(); + + Response::respondSuccess(); + return; + } + + Response::respondError(ERRORS::ALREADY_A_STAFF); + + + } + public function storeRequestData() { + $this->name = Controller::request('name'); + $this->email = Controller::request('email'); + $this->password = Controller::request('password'); + $this->profilePic = Controller::request('profilePic'); + $this->level = Controller::request('level'); + $this->departments = Controller::request('departments'); + } +} \ No newline at end of file diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index 91387377..f0bd8322 100644 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -26,4 +26,6 @@ class ERRORS { const INVALID_ORDER = 'INVALID_ORDER'; const INVALID_USER = 'INVALID_USER'; const ALREADY_BANNED = 'ALREADY_BANNED'; + const INVALID_LEVEL = 'INVALID_LEVEL'; + const ALREADY_A_STAFF = 'ALREADY_A_STAFF'; } From b2547ce5f86be82692960a7ddec487f0d5ea7900 Mon Sep 17 00:00:00 2001 From: AntonyAntonio Date: Tue, 6 Dec 2016 01:32:00 -0300 Subject: [PATCH 02/22] Guillermo - path / staff/add[skip ci] --- server/controllers/staff/get.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/controllers/staff/get.php b/server/controllers/staff/get.php index db922c80..dfbf5ce1 100644 --- a/server/controllers/staff/get.php +++ b/server/controllers/staff/get.php @@ -14,6 +14,20 @@ class GetStaffController extends Controller { public function handler() { $user = Controller::getLoggedUser(); + + $userId = Controller::request('userId'); + $userRow = Staff::getDataStore($userId,'id'); + + if($user->level == 3 && !$userRow->isNull()) { + Response::respondSuccess([ + 'id' => $userRow->id, + 'name' => $userRow->name, + 'email' => $userRow->email, + 'password' => $userRow->password + ]); + return; + } + $parsedDepartmentList = []; $departmentList = $user->sharedDepartmentList; From 1a3adfe41821ce6242f5cd6ca3a90e378cba3ab9 Mon Sep 17 00:00:00 2001 From: AntonyAntonio Date: Wed, 7 Dec 2016 01:37:18 -0300 Subject: [PATCH 03/22] Guillermo - path / staff/get-all[skip ci] --- server/controllers/staff.php | 4 ++++ server/controllers/staff/delete.php | 18 ++++++++++++++++++ server/controllers/staff/get-all.php | 27 +++++++++++++++++++++++++++ server/models/Staff.php | 11 +++++++++++ 4 files changed, 60 insertions(+) create mode 100644 server/controllers/staff/delete.php create mode 100644 server/controllers/staff/get-all.php diff --git a/server/controllers/staff.php b/server/controllers/staff.php index c7cf0e91..f1cfb954 100644 --- a/server/controllers/staff.php +++ b/server/controllers/staff.php @@ -7,6 +7,8 @@ require_once 'staff/get-new-tickets.php'; require_once 'staff/get-all-tickets.php'; require_once 'staff/search-tickets.php'; require_once 'staff/add.php'; +require_once 'staff/get-all.php'; +require_once 'staff/delete.php'; $systemControllerGroup = new ControllerGroup(); $systemControllerGroup->setGroupPath('/staff'); @@ -19,5 +21,7 @@ $systemControllerGroup->addController(new GetNewTicketsStaffController); $systemControllerGroup->addController(new GetAllTicketsStaffController); $systemControllerGroup->addController(new SearchTicketStaffController); $systemControllerGroup->addController(new AddStaffController); +$systemControllerGroup->addController(new GetAllStaffController); +$systemControllerGroup->addController(new DeleteStaffController); $systemControllerGroup->finalize(); \ No newline at end of file diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php new file mode 100644 index 00000000..1ffdbe9a --- /dev/null +++ b/server/controllers/staff/delete.php @@ -0,0 +1,18 @@ + 'staff_3', + 'requestData' => [] + ]; + } + + public function handler (){ + + } + +} \ No newline at end of file diff --git a/server/controllers/staff/get-all.php b/server/controllers/staff/get-all.php new file mode 100644 index 00000000..afec9d07 --- /dev/null +++ b/server/controllers/staff/get-all.php @@ -0,0 +1,27 @@ + 'staff_3', + 'requestData' => [] + ]; + } + + + public function handler() { + $staffs = Staff::getAll(); + $staffArray = []; + + foreach($staffs as $staff) { + $staffArray[] = $staff->toArray(); + } + + Response::respondSuccess($staffArray); + + } +} \ No newline at end of file diff --git a/server/models/Staff.php b/server/models/Staff.php index 03e3e078..67cf9e8a 100644 --- a/server/models/Staff.php +++ b/server/models/Staff.php @@ -30,4 +30,15 @@ class Staff extends DataStore { public static function getUser($value, $property = 'id') { return parent::getDataStore($value, $property); } + public function toArray() { + return [ + 'name'=> $this->name, + 'email' => $this->email, + 'password' => $this->password, + 'profilePic' => $this->profilePic, + 'level' => $this->level, + 'departments' => $this->sharedDepartmentList->toArray(), + 'tickets' => $this->sharedTicketList->toArray(), + ]; + } } From 60211c2b3cf383169cafc6d2876b48de296a6dff Mon Sep 17 00:00:00 2001 From: AntonyAntonio Date: Wed, 7 Dec 2016 02:06:50 -0300 Subject: [PATCH 04/22] Guillermo - path / staff/delete[skip ci] --- server/controllers/staff/delete.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php index 1ffdbe9a..67b50f89 100644 --- a/server/controllers/staff/delete.php +++ b/server/controllers/staff/delete.php @@ -1,5 +1,6 @@ 'staff_3', - 'requestData' => [] + 'requestData' => [ + + ] ]; } - public function handler (){ + public function handler() { + $staffId = Controller::request('userId'); + + + $staff = Staff::getDataStore($staffId); + $staff->delete(); + Response::respondSuccess(); } } \ No newline at end of file From 630e121bfbc85478dafcbe8a83dce8151abc7a8f Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 7 Dec 2016 16:59:42 -0300 Subject: [PATCH 05/22] Guillermo - staff/add [skip ci] --- server/controllers/staff/add.php | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/server/controllers/staff/add.php b/server/controllers/staff/add.php index 63183974..dbcaeccf 100644 --- a/server/controllers/staff/add.php +++ b/server/controllers/staff/add.php @@ -39,20 +39,19 @@ class AddStaffController extends Controller { } public function handler() { - $this->storeRequestData(); - $staff = new Staff(); + $staff = new Staff(); - $staffrow = Staff::getDataStore($this->email,'email'); + $staffRow = Staff::getDataStore($this->email,'email'); - if($staffrow->isNull()) { + if($staffRow->isNull()) { $staff->setProperties([ 'name'=> $this->name, 'email' => $this->email, 'password'=> $this->password, 'profilePic' => $this->profilePic, 'level' => $this->level, - 'sharedDepartmentList'=> $this->departments, + 'sharedDepartmentList'=> $this->getDepartmentList(), ]); $staff->store(); @@ -62,9 +61,8 @@ class AddStaffController extends Controller { } Response::respondError(ERRORS::ALREADY_A_STAFF); - - } + public function storeRequestData() { $this->name = Controller::request('name'); $this->email = Controller::request('email'); @@ -73,4 +71,16 @@ class AddStaffController extends Controller { $this->level = Controller::request('level'); $this->departments = Controller::request('departments'); } + + public function getDepartmentList() { + $listDepartments = new DataStoreList(); + $departmentIds = json_decode($this->departments); + + foreach($departmentIds as $id) { + $department = Department::getDataStore($id); + $listDepartments->add($department); + } + + return $listDepartments; + } } \ No newline at end of file From d57baa6cd8b93e9dbb764a31b4d6d25461a917b1 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 7 Dec 2016 17:24:42 -0300 Subject: [PATCH 06/22] Guillermo - staff/dellete[skip ci] --- server/controllers/staff/delete.php | 17 ++++++++++++----- server/data/ERRORS.php | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php index 67b50f89..17fb8042 100644 --- a/server/controllers/staff/delete.php +++ b/server/controllers/staff/delete.php @@ -9,17 +9,24 @@ class DeleteStaffController extends Controller { return [ 'permission' => 'staff_3', 'requestData' => [ - + 'staffId' => [ + 'validation' => DataValidator::dataStoreId('staff'), + 'error' => ERRORS::INVALID_STAFF + ] ] ]; } public function handler() { - $staffId = Controller::request('userId'); - - - + $staffId = Controller::request('staffId'); $staff = Staff::getDataStore($staffId); + + foreach($staff->sharedTicketList as $ticket) { + $ticket->owner = null; + $ticket->unread = true; + $ticket->store(); + } + $staff->delete(); Response::respondSuccess(); } diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index f0bd8322..5f1c70b0 100644 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -28,4 +28,5 @@ class ERRORS { const ALREADY_BANNED = 'ALREADY_BANNED'; const INVALID_LEVEL = 'INVALID_LEVEL'; const ALREADY_A_STAFF = 'ALREADY_A_STAFF'; + const INVALID_STAFF = 'INVALID_STAFF'; } From 6bad1949034f8e68126f1ccd1b7f791720b78ef8 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 7 Dec 2016 19:30:31 -0300 Subject: [PATCH 07/22] Guillermo - staff/edit[skip ci] --- server/controllers/staff.php | 2 + server/controllers/staff/delete.php | 9 ++-- server/controllers/staff/edit.php | 66 +++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 server/controllers/staff/edit.php diff --git a/server/controllers/staff.php b/server/controllers/staff.php index f1cfb954..fff73e65 100644 --- a/server/controllers/staff.php +++ b/server/controllers/staff.php @@ -9,6 +9,7 @@ require_once 'staff/search-tickets.php'; require_once 'staff/add.php'; require_once 'staff/get-all.php'; require_once 'staff/delete.php'; +require_once 'staff/edit.php'; $systemControllerGroup = new ControllerGroup(); $systemControllerGroup->setGroupPath('/staff'); @@ -23,5 +24,6 @@ $systemControllerGroup->addController(new SearchTicketStaffController); $systemControllerGroup->addController(new AddStaffController); $systemControllerGroup->addController(new GetAllStaffController); $systemControllerGroup->addController(new DeleteStaffController); +$systemControllerGroup->addController(new EditStaffController); $systemControllerGroup->finalize(); \ No newline at end of file diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php index 17fb8042..1b315abe 100644 --- a/server/controllers/staff/delete.php +++ b/server/controllers/staff/delete.php @@ -9,10 +9,7 @@ class DeleteStaffController extends Controller { return [ 'permission' => 'staff_3', 'requestData' => [ - 'staffId' => [ - 'validation' => DataValidator::dataStoreId('staff'), - 'error' => ERRORS::INVALID_STAFF - ] + ] ]; } @@ -23,8 +20,8 @@ class DeleteStaffController extends Controller { foreach($staff->sharedTicketList as $ticket) { $ticket->owner = null; - $ticket->unread = true; - $ticket->store(); + $ticket->true = true; + $ticket->store() } $staff->delete(); diff --git a/server/controllers/staff/edit.php b/server/controllers/staff/edit.php new file mode 100644 index 00000000..4d675b99 --- /dev/null +++ b/server/controllers/staff/edit.php @@ -0,0 +1,66 @@ + 'staff_3', + 'requestData' => [ + 'staffId' =>[ + 'validation' => DataValidator::dataStoreId('staff'), + 'error' => ERRORS::INVALID_STAFF + ] + ] + ]; + } + + public function handler() { + $this->staffId = Controller::request('staffId'); + + if(!$this->staffId) { + $this->staffRow = Controller::getLoggedUser(); + } else { + $this->staffRow = Staff::getDataStore($this->staffId,'id'); + } + + $this->editInformation(); + Response::respondSuccess(); + } + + public function editInformation() { + + if(Controller::request('email')) { + $this->staffRow->email = Controller::request('email'); + } + + if(Controller::request('password')) { + $this->staffRow->password = Controller::request('password'); + } + if(Controller::request('level')) { + $this->staffRow->level = Controller::request('level'); + } + if(Controller::request('departments')) { + $this->staffRow->sharedDepartmentList = $this->getDepartmentList(); + } + + $this->staffRow->store(); + } + + + public function getDepartmentList() { + $listDepartments = new DataStoreList(); + $departmentIds = json_decode(Controller::request('departments')); + + foreach($departmentIds as $id) { + $department = Department::getDataStore($id); + $listDepartments->add($department); + } + + return $listDepartments; + } +} \ No newline at end of file From d67d9ebfb12f89e0d4e00ec80c7fe6073143c264 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 7 Dec 2016 20:19:07 -0300 Subject: [PATCH 08/22] Max - WIP people list and admin panel staff members [skip ci] --- client/src/app-components/people-list.js | 108 ++++++++++++++++++ client/src/app-components/people-list.scss | 64 +++++++++++ .../panel/staff/admin-panel-staff-members.js | 82 ++++++++++++- client/src/data/languages/en.js | 5 + 4 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 client/src/app-components/people-list.js create mode 100644 client/src/app-components/people-list.scss diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js new file mode 100644 index 00000000..d0c1c0ff --- /dev/null +++ b/client/src/app-components/people-list.js @@ -0,0 +1,108 @@ +import React from 'react'; +import _ from 'lodash'; +import {StaggeredMotion, spring} from 'react-motion'; +import Menu from 'core-components/menu' + +import DateTransformer from 'lib-core/date-transformer'; +import i18n from 'lib-app/i18n'; + +class PeopleList extends React.Component { + static propTypes = { + list: React.PropTypes.arrayOf(React.PropTypes.shape({ + profilePic: React.PropTypes.string, + name: React.PropTypes.string, + assignedTickets: React.PropTypes.number, + closedTickets: React.PropTypes.number, + lastLogin: React.PropTypes.number + })), + pageSize: React.PropTypes.number + }; + + static defaultProps = { + pageSize: 4, + list: [] + }; + + state = { + page: 1 + }; + + render() { + const pages = _.range(1, this.getPages() + 1).map((index) => {return {content: index};}); + + return ( +
+
+ {return {offset: -100, alpha: 0};})} styles={(prevStyles) => prevStyles.map((_, i) => { + return i === 0 + ? {offset: spring(0), alpha: spring(1)} + : {offset: spring(prevStyles[i - 1].offset), alpha: spring(prevStyles[i - 1].alpha)} + })}> + {(styles) => +
+ {styles.map((style, index) => +
+ {this.renderItem(index + this.props.pageSize * (this.state.page - 1))} +
+ )} +
+ } +
+
+
+ this.setState({page: index+1})} tabbable/> +
+
+ ); + } + + renderItem(index) { + if(index >= this.props.list.length) { + return null; + } + + const item = this.props.list[index]; + const minIndex = this.props.pageSize * (this.state.page - 1); + const maxIndex = this.props.pageSize * this.state.page; + + return (minIndex <= index && index < maxIndex) ? ( +
+
+ +
+
{item.name}
+
+ {i18n('ASSIGNED_TICKETS', {tickets: item.assignedTickets})} +
+
+ {i18n('CLOSED_TICKETS', {tickets: item.closedTickets})} +
+
+
{i18n('LAST_LOGIN')}
+
{DateTransformer.transformToString(item.lastLogin)}
+
+
+ ) : null; + } + + getRowsQuantity() { + console.log(this.state.page); + if(this.state.page == this.getPages()){ + console.log("Ultima pagina"); + console.log(this.props.list.length); + console.log(this.props.pageSize); + return this.props.list.length % this.props.pageSize; + } + else { + return this.props.pageSize; + } + } + + + getPages() { + return Math.ceil(this.props.list.length / this.props.pageSize); + } + +} + +export default PeopleList; \ No newline at end of file diff --git a/client/src/app-components/people-list.scss b/client/src/app-components/people-list.scss new file mode 100644 index 00000000..8c52b03d --- /dev/null +++ b/client/src/app-components/people-list.scss @@ -0,0 +1,64 @@ +@import "../scss/vars"; + +.people-list { + max-width: 800px; + margin: 0 auto; + + &__list { + } + + &__item { + border: 2px solid $grey; + border-radius: 4px; + margin-bottom: 12px; + position: relative; + height: 105px; + padding-left: 60px; + font-size: $font-size--md; + + &-profile-pic-wrapper { + vertical-align: top; + background-color: $secondary-blue; + color: white; + border-radius: 5px; + width: 60px; + height: 60px; + top: 20px; + left: 20px; + + overflow: hidden; + position: absolute; + border: 2px solid $light-grey; + } + + &-profile-pic { + position: absolute; + height: 100%; + left: 50%; + transform: translate(-50%, 0) + } + + &-block { + padding: 30px 0; + width: 25%; + display: inline-block; + vertical-align: middle; + } + + &-assigned-tickets { + + } + + &-closed-tickets { + + } + + &-last-login { + + } + } + + &__pagination { + + } +} \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index f869fc8b..58061cbd 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -1,14 +1,94 @@ import React from 'react'; +import i18n from 'lib-app/i18n'; + +import PeopleList from 'app-components/people-list'; +import Header from 'core-components/header'; +import DropDown from 'core-components/drop-down'; + class AdminPanelStaffMembers extends React.Component { + static propTypes = { + departments: React.PropTypes.array + }; + + static defaultProps = { + departments: [] + }; + render() { return (
- /admin/panel/staff/staff-members +
+ +
); } + + getDepartmentDropdownProps() { + return { + items: this.getDepartments(), + onChange: (event) => { + this.setState({ + selectedDepartment: event.index && this.props.departments[event.index - 1].id + }); + }, + size: 'medium' + }; + } + + getDepartments() { + let departments = this.props.departments.map((department) => { + return {content: department.name}; + }); + + departments.unshift({ + content: i18n('ALL_DEPARTMENTS') + }); + + return departments; + } + + getStaffList() { + return [ + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emilia Clarke', + assignedTickets: 4, + closedTickets: 21, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Yulian A GUI Yermo', + assignedTickets: 9, + closedTickets: 0, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Miltona Costa', + assignedTickets: -1, + closedTickets: -1, + lastLogin: 20160212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emiliasnikova Rusachestkvuy', + assignedTickets: 100, + closedTickets: 21, + lastLogin: 20130101 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Laurita Morrechaga Rusachestkvuy', + assignedTickets: 1, + closedTickets: 1, + lastLogin: 2012050 + } + ]; + } } export default AdminPanelStaffMembers; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index e60a8f4e..cb3b2980 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -94,6 +94,10 @@ export default { 'EDIT': 'Edit', 'NO_RESULTS': 'No results', 'DELETE_AND_BAN': 'Delete and ban', + 'ASSIGNED_TICKETS': '{tickets} assigned tickets', + 'CLOSED_TICKETS': '{tickets} closed tickets', + 'LAST_LOGIN': 'Last login', + 'STAFF_MEMBERS': 'Staff members', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', @@ -116,6 +120,7 @@ export default { 'ADD_ARTICLE_DESCRIPTION': 'Here you can add an article that will be available for every user. It will be added inside the category {category}.', 'LIST_ARTICLES_DESCRIPTION': 'This is a list of articles that includes information about our services.', 'ADD_TOPIC_DESCRIPTION': 'Here you can add a topic that works as a category for articles.', + 'STAFF_MEMBERS_DESCRIPTION': 'Here you can see who are your staff members.', //ERRORS 'EMAIL_OR_PASSWORD': 'Email or password invalid', From c2ab1f9b6e662f4200ac913a6a752ccd694299c6 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 7 Dec 2016 21:13:39 -0300 Subject: [PATCH 09/22] Max - WIP [skip ci] --- .../panel/staff/admin-panel-staff-members.js | 74 ++++++++----------- client/src/data/fixtures/staff-fixtures.js | 52 +++++++++++++ client/src/data/languages/en.js | 1 + 3 files changed, 85 insertions(+), 42 deletions(-) diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 58061cbd..2cf7fda1 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -1,10 +1,15 @@ import React from 'react'; import i18n from 'lib-app/i18n'; - +import API from 'lib-app/api-call'; +import SessionStore from 'lib-app/session-store'; import PeopleList from 'app-components/people-list'; + import Header from 'core-components/header'; import DropDown from 'core-components/drop-down'; +import Button from 'core-components/button'; +import Icon from 'core-components/icon'; +import Loading from 'core-components/loading'; class AdminPanelStaffMembers extends React.Component { @@ -16,12 +21,28 @@ class AdminPanelStaffMembers extends React.Component { departments: [] }; + state = { + selectedDepartment: 0, + staffList: [], + loading: true + }; + + componentDidMount() { + API.call({ + path: '/staff/get-all', + data: {} + }).then(this.onStaffRetrieved.bind(this)); + } + render() { return (
- + + {(this.state.loading) ? : }
); } @@ -31,7 +52,7 @@ class AdminPanelStaffMembers extends React.Component { items: this.getDepartments(), onChange: (event) => { this.setState({ - selectedDepartment: event.index && this.props.departments[event.index - 1].id + selectedDepartment: event.index && this.props.departments[event.index - 1].id }); }, size: 'medium' @@ -39,7 +60,7 @@ class AdminPanelStaffMembers extends React.Component { } getDepartments() { - let departments = this.props.departments.map((department) => { + let departments = SessionStore.getDepartments().map((department) => { return {content: department.name}; }); @@ -50,44 +71,13 @@ class AdminPanelStaffMembers extends React.Component { return departments; } - getStaffList() { - return [ - { - profilePic: 'http://www.opensupports.com/profilepic.jpg', - name: 'Emilia Clarke', - assignedTickets: 4, - closedTickets: 21, - lastLogin: 20161212 - }, - { - profilePic: 'http://www.opensupports.com/profilepic.jpg', - name: 'Yulian A GUI Yermo', - assignedTickets: 9, - closedTickets: 0, - lastLogin: 20161212 - }, - { - profilePic: 'http://www.opensupports.com/profilepic.jpg', - name: 'Miltona Costa', - assignedTickets: -1, - closedTickets: -1, - lastLogin: 20160212 - }, - { - profilePic: 'http://www.opensupports.com/profilepic.jpg', - name: 'Emiliasnikova Rusachestkvuy', - assignedTickets: 100, - closedTickets: 21, - lastLogin: 20130101 - }, - { - profilePic: 'http://www.opensupports.com/profilepic.jpg', - name: 'Laurita Morrechaga Rusachestkvuy', - assignedTickets: 1, - closedTickets: 1, - lastLogin: 2012050 - } - ]; + onStaffRetrieved(result) { + if(result.status == 'success'){ + this.setState({ + loading: false, + staffList: result.data + }); + } } } diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index 4aadb436..efa0ff2d 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -577,5 +577,57 @@ module.exports = [ } } } + }, + { + path: '/staff/get-all', + time: 100, + response: function() { + return { + status: 'success', + data: [ + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emilia Clarke', + departments: [{id: 2, name: 'Technical issues'}], + assignedTickets: 4, + closedTickets: 21, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Yulian A GUI Yermo', + departments: [{id: 2, name: 'Technical issues'}, {id: 1, name: 'Sales Support'}], + assignedTickets: 9, + closedTickets: 0, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Miltona Costa', + departments: [{id: 1, name: 'Sales Support'}], + assignedTickets: -1, + closedTickets: -1, + lastLogin: 20160212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emiliasnikova Rusachestkvuy', + departments: [{id: 1, name: 'Sales Support'}, {id: 3, name: 'System and Administration'}], + assignedTickets: 100, + closedTickets: 21, + lastLogin: 20130101 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Laurita Morrechaga Rusachestkvuy', + departments: [{id: 3, name: 'System and Administration'}], + assignedTickets: 1, + closedTickets: 1, + lastLogin: 2012050 + } + ] + }; + } + } ]; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index cb3b2980..f608dcfa 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -98,6 +98,7 @@ export default { 'CLOSED_TICKETS': '{tickets} closed tickets', 'LAST_LOGIN': 'Last login', 'STAFF_MEMBERS': 'Staff members', + 'ADD_NEW_STAFF': 'Add new staff', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', From 829e6060f5d200bffb76b19c5f90a267e87c3224 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 7 Dec 2016 23:43:32 -0300 Subject: [PATCH 10/22] Guillermo - staff/edit[skip ci] --- server/controllers/staff/delete.php | 2 +- server/models/Department.php | 2 +- tests/staff/add.rb | 5 +++++ tests/staff/delete.rb | 0 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 tests/staff/add.rb create mode 100644 tests/staff/delete.rb diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php index 1b315abe..78df1c6b 100644 --- a/server/controllers/staff/delete.php +++ b/server/controllers/staff/delete.php @@ -21,7 +21,7 @@ class DeleteStaffController extends Controller { foreach($staff->sharedTicketList as $ticket) { $ticket->owner = null; $ticket->true = true; - $ticket->store() + $ticket->store(); } $staff->delete(); diff --git a/server/models/Department.php b/server/models/Department.php index a263d38e..ac499081 100644 --- a/server/models/Department.php +++ b/server/models/Department.php @@ -7,7 +7,7 @@ class Department extends DataStore { public static function getProps() { return [ 'name', - 'sharedTicketList' + 'sharedTicketList', ]; } diff --git a/tests/staff/add.rb b/tests/staff/add.rb new file mode 100644 index 00000000..5f9c6e75 --- /dev/null +++ b/tests/staff/add.rb @@ -0,0 +1,5 @@ +describe'/staff/add' do + request() + + it 'should ' +end \ No newline at end of file diff --git a/tests/staff/delete.rb b/tests/staff/delete.rb new file mode 100644 index 00000000..e69de29b From 80f4281ab1b0ca457e999709721954698d479a1c Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 01:01:57 -0300 Subject: [PATCH 11/22] Max - Add filter by department in staff members [skip ci] --- .../panel/staff/admin-panel-staff-members.js | 25 +++++++++++-------- .../staff/admin-panel-staff-members.scss | 0 2 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 client/src/app/admin/panel/staff/admin-panel-staff-members.scss diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 2cf7fda1..ddd49eec 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -1,4 +1,5 @@ import React from 'react'; +import _ from 'lodash'; import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; @@ -13,14 +14,6 @@ import Loading from 'core-components/loading'; class AdminPanelStaffMembers extends React.Component { - static propTypes = { - departments: React.PropTypes.array - }; - - static defaultProps = { - departments: [] - }; - state = { selectedDepartment: 0, staffList: [], @@ -35,6 +28,7 @@ class AdminPanelStaffMembers extends React.Component { } render() { + console.log(this.state.staffList); return (
@@ -42,7 +36,7 @@ class AdminPanelStaffMembers extends React.Component { - {(this.state.loading) ? : } + {(this.state.loading) ? : }
); } @@ -51,14 +45,25 @@ class AdminPanelStaffMembers extends React.Component { return { items: this.getDepartments(), onChange: (event) => { + let departments = SessionStore.getDepartments(); this.setState({ - selectedDepartment: event.index && this.props.departments[event.index - 1].id + selectedDepartment: event.index && departments[event.index - 1].id }); }, size: 'medium' }; } + getStaffList() { + if(!this.state.selectedDepartment) { + return this.state.staffList; + } + + return _.filter(this.state.staffList, (o) => { + return _.findIndex(o.departments, {id: this.state.selectedDepartment}) !== -1; + }); + } + getDepartments() { let departments = SessionStore.getDepartments().map((department) => { return {content: department.name}; diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss new file mode 100644 index 00000000..e69de29b From 8722c857424c3267b852eeead1701cab507eaa6a Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 01:27:50 -0300 Subject: [PATCH 12/22] Max - Add CSS styling to dropdown and button [skip ci] --- client/src/app-components/people-list.js | 1 - .../panel/staff/admin-panel-staff-members.js | 13 +++++++------ .../panel/staff/admin-panel-staff-members.scss | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index d0c1c0ff..9a8ffb0c 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -98,7 +98,6 @@ class PeopleList extends React.Component { } } - getPages() { return Math.ceil(this.props.list.length / this.props.pageSize); } diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index ddd49eec..9be08ff4 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -28,14 +28,15 @@ class AdminPanelStaffMembers extends React.Component { } render() { - console.log(this.state.staffList); return ( -
+
- - +
+ + +
{(this.state.loading) ? : }
); diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss index e69de29b..d31be626 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss @@ -0,0 +1,17 @@ +@import "../../../../scss/vars"; + +.admin-panel-staff-members { + + &__wrapper { + height: 60px; + } + + &__dropdown { + float: left; + } + + &__button { + float: right; + margin-top: -5px; + } +} \ No newline at end of file From 7dbdac126f38142fc53cef199c15151a380751ac Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 01:39:38 -0300 Subject: [PATCH 13/22] Max - Fix pagination bug by adding controlled pattern [skip ci] --- client/src/app-components/people-list.js | 20 +++++++++---------- .../panel/staff/admin-panel-staff-members.js | 8 +++++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 9a8ffb0c..f957ebd0 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -15,7 +15,9 @@ class PeopleList extends React.Component { closedTickets: React.PropTypes.number, lastLogin: React.PropTypes.number })), - pageSize: React.PropTypes.number + pageSize: React.PropTypes.number, + page: React.PropTypes.number, + onPageSelect: React.PropTypes.func }; static defaultProps = { @@ -23,10 +25,6 @@ class PeopleList extends React.Component { list: [] }; - state = { - page: 1 - }; - render() { const pages = _.range(1, this.getPages() + 1).map((index) => {return {content: index};}); @@ -42,7 +40,7 @@ class PeopleList extends React.Component {
{styles.map((style, index) =>
- {this.renderItem(index + this.props.pageSize * (this.state.page - 1))} + {this.renderItem(index + this.props.pageSize * (this.props.page - 1))}
)}
@@ -50,7 +48,7 @@ class PeopleList extends React.Component {
- this.setState({page: index+1})} tabbable/> +
); @@ -62,8 +60,8 @@ class PeopleList extends React.Component { } const item = this.props.list[index]; - const minIndex = this.props.pageSize * (this.state.page - 1); - const maxIndex = this.props.pageSize * this.state.page; + const minIndex = this.props.pageSize * (this.props.page - 1); + const maxIndex = this.props.pageSize * this.props.page; return (minIndex <= index && index < maxIndex) ? (
@@ -86,8 +84,8 @@ class PeopleList extends React.Component { } getRowsQuantity() { - console.log(this.state.page); - if(this.state.page == this.getPages()){ + console.log(this.props.page); + if(this.props.page == this.getPages()){ console.log("Ultima pagina"); console.log(this.props.list.length); console.log(this.props.pageSize); diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 9be08ff4..2c47a6b3 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -17,7 +17,8 @@ class AdminPanelStaffMembers extends React.Component { state = { selectedDepartment: 0, staffList: [], - loading: true + loading: true, + page: 1 }; componentDidMount() { @@ -37,7 +38,7 @@ class AdminPanelStaffMembers extends React.Component { {i18n('ADD_NEW_STAFF')}
- {(this.state.loading) ? : } + {(this.state.loading) ? : this.setState({page: index+1})} />} ); } @@ -48,7 +49,8 @@ class AdminPanelStaffMembers extends React.Component { onChange: (event) => { let departments = SessionStore.getDepartments(); this.setState({ - selectedDepartment: event.index && departments[event.index - 1].id + selectedDepartment: event.index && departments[event.index - 1].id, + page: 1 }); }, size: 'medium' From 84c25e46c119d8cbed5eacded9470624a05e7ecf Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 01:55:57 -0300 Subject: [PATCH 14/22] Max - Prettify StaggeredMotion [skip ci] --- client/src/app-components/people-list.js | 44 ++++++++++++++++-------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index f957ebd0..9c9217b5 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -31,20 +31,8 @@ class PeopleList extends React.Component { return (
- {return {offset: -100, alpha: 0};})} styles={(prevStyles) => prevStyles.map((_, i) => { - return i === 0 - ? {offset: spring(0), alpha: spring(1)} - : {offset: spring(prevStyles[i - 1].offset), alpha: spring(prevStyles[i - 1].alpha)} - })}> - {(styles) => -
- {styles.map((style, index) => -
- {this.renderItem(index + this.props.pageSize * (this.props.page - 1))} -
- )} -
- } + + {this.renderList.bind(this)}
@@ -54,6 +42,34 @@ class PeopleList extends React.Component { ); } + getDefaultStyles() { + return _.times(this.props.pageSize).map(() => {return {offset: -100, alpha: 0}}); + } + + getStyles(prevStyles) { + return prevStyles.map((_, i) => { + return i === 0 + ? {offset: spring(0), alpha: spring(1)} + : {offset: spring(prevStyles[i - 1].offset), alpha: spring(prevStyles[i - 1].alpha)} + }); + } + + renderList(styles) { + return ( +
+ {styles.map(this.renderAnimatedItem.bind(this))} +
+ ); + } + + renderAnimatedItem(style, index) { + return ( +
+ {this.renderItem(index + this.props.pageSize * (this.props.page - 1))} +
+ ); + } + renderItem(index) { if(index >= this.props.list.length) { return null; From 823126d930fe2c9592f77d6021b558e28e9b1b46 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 02:09:05 -0300 Subject: [PATCH 15/22] Max - Delete some console.logs [skip ci] --- client/src/app-components/people-list.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 9c9217b5..1fd18346 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -100,11 +100,7 @@ class PeopleList extends React.Component { } getRowsQuantity() { - console.log(this.props.page); if(this.props.page == this.getPages()){ - console.log("Ultima pagina"); - console.log(this.props.list.length); - console.log(this.props.pageSize); return this.props.list.length % this.props.pageSize; } else { From 895fbf011f82bae82ae9df7d546e6b5eb05fdd63 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 8 Dec 2016 03:21:37 -0300 Subject: [PATCH 16/22] GUILLERMO - all test staff [skip ci] --- server/controllers/staff/add.php | 9 ++-- server/controllers/staff/delete.php | 5 ++- server/controllers/staff/edit.php | 27 +++++++----- server/controllers/staff/get-all.php | 18 +++++++- server/controllers/staff/get.php | 12 ++---- server/libs/validations/dataStoreId.php | 4 ++ server/models/Department.php | 6 +++ server/models/Staff.php | 3 +- tests/init.rb | 4 ++ tests/staff/add.rb | 41 +++++++++++++++++- tests/staff/delete.rb | 29 +++++++++++++ tests/staff/edit.rb | 56 +++++++++++++++++++++++++ tests/staff/get-all.rb | 35 ++++++++++++++++ tests/staff/get.rb | 15 +++++++ 14 files changed, 234 insertions(+), 30 deletions(-) create mode 100644 tests/staff/edit.rb create mode 100644 tests/staff/get-all.rb diff --git a/server/controllers/staff/add.php b/server/controllers/staff/add.php index dbcaeccf..e3b13390 100644 --- a/server/controllers/staff/add.php +++ b/server/controllers/staff/add.php @@ -48,15 +48,16 @@ class AddStaffController extends Controller { $staff->setProperties([ 'name'=> $this->name, 'email' => $this->email, - 'password'=> $this->password, + 'password'=> Hashing::hashPassword($this->password), 'profilePic' => $this->profilePic, 'level' => $this->level, 'sharedDepartmentList'=> $this->getDepartmentList(), ]); - $staff->store(); - - Response::respondSuccess(); + + Response::respondSuccess([ + 'id' => $staff->store() + ]); return; } diff --git a/server/controllers/staff/delete.php b/server/controllers/staff/delete.php index 78df1c6b..d9332267 100644 --- a/server/controllers/staff/delete.php +++ b/server/controllers/staff/delete.php @@ -9,7 +9,10 @@ class DeleteStaffController extends Controller { return [ 'permission' => 'staff_3', 'requestData' => [ - + 'staffId' =>[ + 'validation' => DataValidator::dataStoreId('staff'), + 'error' => ERRORS::INVALID_STAFF + ] ] ]; } diff --git a/server/controllers/staff/edit.php b/server/controllers/staff/edit.php index 4d675b99..66500cc0 100644 --- a/server/controllers/staff/edit.php +++ b/server/controllers/staff/edit.php @@ -9,13 +9,8 @@ class EditStaffController extends Controller { public function validations() { return [ - 'permission' => 'staff_3', - 'requestData' => [ - 'staffId' =>[ - 'validation' => DataValidator::dataStoreId('staff'), - 'error' => ERRORS::INVALID_STAFF - ] - ] + 'permission' => 'staff_1', + 'requestData' => [] ]; } @@ -24,8 +19,16 @@ class EditStaffController extends Controller { if(!$this->staffId) { $this->staffRow = Controller::getLoggedUser(); + } else if(Controller::isStaffLogged(3)) { + $this->staffRow = Staff::getDataStore($this->staffId, 'id'); + + if($this->staffRow->isNull()) { + Response::respondError(ERRORS::INVALID_STAFF); + return; + } } else { - $this->staffRow = Staff::getDataStore($this->staffId,'id'); + Response::respondError(ERRORS::NO_PERMISSION); + return; } $this->editInformation(); @@ -39,12 +42,14 @@ class EditStaffController extends Controller { } if(Controller::request('password')) { - $this->staffRow->password = Controller::request('password'); + $this->staffRow->password = Hashing::hashPassword(Controller::request('password')); } - if(Controller::request('level')) { + + if(Controller::request('level') && Controller::isStaffLogged(3)) { $this->staffRow->level = Controller::request('level'); } - if(Controller::request('departments')) { + + if(Controller::request('departments') && Controller::isStaffLogged(3)) { $this->staffRow->sharedDepartmentList = $this->getDepartmentList(); } diff --git a/server/controllers/staff/get-all.php b/server/controllers/staff/get-all.php index afec9d07..12f027c6 100644 --- a/server/controllers/staff/get-all.php +++ b/server/controllers/staff/get-all.php @@ -18,7 +18,23 @@ class GetAllStaffController extends Controller { $staffArray = []; foreach($staffs as $staff) { - $staffArray[] = $staff->toArray(); + $assignedTickets = 0; + $closedTickets = 0; + + foreach ($staff->sharedTicketList as $ticket) { + if($ticket->closed) $closedTickets++; + else $assignedTickets++; + } + + $staffArray[] = [ + 'name' => $staff->name, + 'email' => $staff->email, + 'profilePic' => $staff->profilePic, + 'level' => $staff->level, + 'departments' => $staff->sharedDepartmentList->toArray(), + 'assignedTickets' => $assignedTickets, + 'closedTickets' => $closedTickets, + ]; } Response::respondSuccess($staffArray); diff --git a/server/controllers/staff/get.php b/server/controllers/staff/get.php index dfbf5ce1..1cd6a491 100644 --- a/server/controllers/staff/get.php +++ b/server/controllers/staff/get.php @@ -15,17 +15,11 @@ class GetStaffController extends Controller { public function handler() { $user = Controller::getLoggedUser(); - $userId = Controller::request('userId'); - $userRow = Staff::getDataStore($userId,'id'); + $userId = Controller::request('staffId'); + $userRow = Staff::getDataStore($userId); if($user->level == 3 && !$userRow->isNull()) { - Response::respondSuccess([ - 'id' => $userRow->id, - 'name' => $userRow->name, - 'email' => $userRow->email, - 'password' => $userRow->password - ]); - return; + $user = $userRow; } $parsedDepartmentList = []; diff --git a/server/libs/validations/dataStoreId.php b/server/libs/validations/dataStoreId.php index a510cb55..029ee33c 100644 --- a/server/libs/validations/dataStoreId.php +++ b/server/libs/validations/dataStoreId.php @@ -22,6 +22,9 @@ class DataStoreId extends AbstractRule { case 'user': $dataStore = \User::getUser($dataStoreId); break; + case 'staff': + $dataStore = \Staff::getUser($dataStoreId); + break; case 'ticket': $dataStore = \Ticket::getTicket($dataStoreId); break; @@ -45,6 +48,7 @@ class DataStoreId extends AbstractRule { private function isDataStoreNameValid($dataStoreName) { return in_array($dataStoreName, [ 'user', + 'staff', 'ticket', 'department', 'customresponse', diff --git a/server/models/Department.php b/server/models/Department.php index ac499081..f2abbaa0 100644 --- a/server/models/Department.php +++ b/server/models/Department.php @@ -24,4 +24,10 @@ class Department extends DataStore { return $departmentsNameList; } + public function toArray() { + return [ + 'id' => $this->id, + 'name' => $this->name + ]; + } } \ No newline at end of file diff --git a/server/models/Staff.php b/server/models/Staff.php index 67cf9e8a..02e72cf3 100644 --- a/server/models/Staff.php +++ b/server/models/Staff.php @@ -34,11 +34,10 @@ class Staff extends DataStore { return [ 'name'=> $this->name, 'email' => $this->email, - 'password' => $this->password, 'profilePic' => $this->profilePic, 'level' => $this->level, 'departments' => $this->sharedDepartmentList->toArray(), - 'tickets' => $this->sharedTicketList->toArray(), + 'tickets' => $this->sharedTicketList->toArray() ]; } } diff --git a/tests/init.rb b/tests/init.rb index 45791f55..0af3e81a 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -25,7 +25,10 @@ require './ticket/custom-response.rb' require './ticket/change-department.rb' require './ticket/close.rb' require './ticket/re-open.rb' +require './staff/add.rb' require './staff/get.rb' +require './staff/edit.rb' +require './staff/delete.rb' require './staff/assign-ticket.rb' require './staff/un-assign-ticket.rb' require './staff/get-tickets.rb' @@ -39,5 +42,6 @@ require './user/get-user.rb' require './user/ban.rb' require './user/get-users-test.rb' require './user/delete.rb' +require './staff/get-all.rb' diff --git a/tests/staff/add.rb b/tests/staff/add.rb index 5f9c6e75..5b189cc3 100644 --- a/tests/staff/add.rb +++ b/tests/staff/add.rb @@ -1,5 +1,42 @@ describe'/staff/add' do - request() + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) - it 'should ' + it 'should add staff member' do + result= request('/staff/add', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + name: 'Tyrion Lannister', + email: 'tyrion@opensupports.com', + password: 'testpassword', + level: 2, + profilePic: 'http://www.opensupports.com/profilepic.jpg', + departments: '[1]' + }) + + (result['status']).should.equal('success') + + row = $database.getRow('staff', result['data']['id'], 'id') + + (row['name']).should.equal('Tyrion Lannister') + (row['email']).should.equal('tyrion@opensupports.com') + (row['profile_pic']).should.equal('http://www.opensupports.com/profilepic.jpg') + (row['level']).should.equal('2') + end + it 'should fail if staff member is alrady a staff' do + result= request('/staff/add', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + name: 'Tyrion Lannister', + email: 'tyrion@opensupports.com', + password: 'testpassword', + level: 2, + profilePic: 'http://www.opensupports.com/profilepic.jpg', + departments: '[1]' + }) + + (result['status']).should.equal('fail') + (result['message']).should.equal('ALREADY_A_STAFF') + + end end \ No newline at end of file diff --git a/tests/staff/delete.rb b/tests/staff/delete.rb index e69de29b..af55dcc5 100644 --- a/tests/staff/delete.rb +++ b/tests/staff/delete.rb @@ -0,0 +1,29 @@ +describe'/staff/delete' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + + it 'should delete staff member' do + result= request('/staff/delete', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + staffId:2 + }) + + (result['status']).should.equal('success') + + row = $database.getRow('staff', 2, 'id') + (row).should.equal(nil) + + end + it 'should fail delete if staff member is does not exist' do + result= request('/staff/delete', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + staffId:2 + }) + + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_STAFF') + + end +end \ No newline at end of file diff --git a/tests/staff/edit.rb b/tests/staff/edit.rb new file mode 100644 index 00000000..3167359f --- /dev/null +++ b/tests/staff/edit.rb @@ -0,0 +1,56 @@ +describe'/staff/edit' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + + it 'should edit another staff member' do + result= request('/staff/edit', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + email: 'LittleLannister@opensupports.com', + level: 1, + departments: '[1, 2]', + staffId: 2 + }) + + (result['status']).should.equal('success') + + row = $database.getRow('staff', 2, 'id') + + (row['email']).should.equal('LittleLannister@opensupports.com') + (row['level']).should.equal('1') + + rows = $database.getRow('department_staff', 2, 'staff_id') + + (rows['department_id']).should.equal('1') + + end + + it 'should edit staff member ' do + request('/staff/add', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + name: 'Arya Stark', + password: 'starkpassword', + email: 'arya@opensupports.com', + level: 2, + profilePic: 'http://www.opensupports.com/profilepic.jpg', + departments: '[1]' + }) + request('/user/logout') + Scripts.login('arya@opensupports.com', 'starkpassword', true) + + result = request('/staff/edit', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + email: 'newwstaff@opensupports.com', + }) + + (result['status']).should.equal('success') + + row = $database.getRow('staff', $csrf_userid, 'id') + + (row['email']).should.equal('newwstaff@opensupports.com') + (row['level']).should.equal('2') + + end +end \ No newline at end of file diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb new file mode 100644 index 00000000..ba5544f5 --- /dev/null +++ b/tests/staff/get-all.rb @@ -0,0 +1,35 @@ +describe'/staff/get-all' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + + it 'should get all staff member' do + result= request('/staff/get-all', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + (result['status']).should.equal('success') + + (result['data'][0]['name']).should.equal('Emilia Clarke') + (result['data'][0]['email']).should.equal('staff@opensupports.com') + (result['data'][0]['profilePic']).should.equal('http://www.opensupports.com/profilepic.jpg') + (result['data'][0]['level']).should.equal('3') + (result['data'][0]['departments'][0]['id']).should.equal('1') + (result['data'][0]['departments'][0]['name']).should.equal('Tech Support') + (result['data'][0]['departments'][1]['id']).should.equal('2') + (result['data'][0]['departments'][1]['name']).should.equal('Suggestions') + (result['data'][0]['departments'][2]['id']).should.equal('3') + (result['data'][0]['departments'][2]['name']).should.equal('Sales and Subscriptions') + (result['data'][0]['assignedTickets']).should.equal(3) + (result['data'][0]['closedTickets']).should.equal(0) + + (result['data'][1]['name']).should.equal('Arya Stark') + (result['data'][1]['email']).should.equal('newwstaff@opensupports.com') + (result['data'][1]['profilePic']).should.equal('http://www.opensupports.com/profilepic.jpg') + (result['data'][1]['level']).should.equal('2') + (result['data'][1]['departments'][0]['id']).should.equal('1') + (result['data'][1]['departments'][0]['name']).should.equal('Tech Support') + (result['data'][1]['assignedTickets']).should.equal(0) + (result['data'][1]['closedTickets']).should.equal(0) + end +end \ No newline at end of file diff --git a/tests/staff/get.rb b/tests/staff/get.rb index a0abd11b..86f1870b 100644 --- a/tests/staff/get.rb +++ b/tests/staff/get.rb @@ -11,5 +11,20 @@ describe '/staff/get/' do (result['status']).should.equal('success') (result['data']['name']).should.equal('Emilia Clarke') (result['data']['staff']).should.equal(true) + (result['data']['email']).should.equal('staff@opensupports.com') + (result['data']['level']).should.equal('3') + end + it 'should return staff member data with staff Id' do + result = request('/staff/get', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + staffId:2 + }) + + (result['status']).should.equal('success') + (result['data']['name']).should.equal('Tyrion Lannister') + (result['data']['staff']).should.equal(true) + (result['data']['email']).should.equal('tyrion@opensupports.com') + (result['data']['level']).should.equal('2') end end \ No newline at end of file From 980904f86e2612bdaf2caf31f15ab021e65874b5 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 14:30:19 -0300 Subject: [PATCH 17/22] Guillermo - staff/edit[skip ci] --- client/src/data/fixtures/staff-fixtures.js | 1 + server/controllers/staff/get-all.php | 1 + server/models/Department.php | 2 +- server/models/Staff.php | 4 +++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index 4aadb436..97d3fe28 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -536,6 +536,7 @@ module.exports = [ pages: 4 } } + } }, { diff --git a/server/controllers/staff/get-all.php b/server/controllers/staff/get-all.php index 12f027c6..13428201 100644 --- a/server/controllers/staff/get-all.php +++ b/server/controllers/staff/get-all.php @@ -27,6 +27,7 @@ class GetAllStaffController extends Controller { } $staffArray[] = [ + 'id' => $staff->id, 'name' => $staff->name, 'email' => $staff->email, 'profilePic' => $staff->profilePic, diff --git a/server/models/Department.php b/server/models/Department.php index f2abbaa0..58d8cd38 100644 --- a/server/models/Department.php +++ b/server/models/Department.php @@ -7,7 +7,7 @@ class Department extends DataStore { public static function getProps() { return [ 'name', - 'sharedTicketList', + 'sharedTicketList' ]; } diff --git a/server/models/Staff.php b/server/models/Staff.php index 02e72cf3..d2895eb4 100644 --- a/server/models/Staff.php +++ b/server/models/Staff.php @@ -30,9 +30,11 @@ class Staff extends DataStore { public static function getUser($value, $property = 'id') { return parent::getDataStore($value, $property); } + public function toArray() { return [ - 'name'=> $this->name, + 'id' => $this->id, + 'name' => $this->name, 'email' => $this->email, 'profilePic' => $this->profilePic, 'level' => $this->level, From 97ef914d270ac4890797ca1f7738ee6cb9a24720 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 8 Dec 2016 17:39:47 -0300 Subject: [PATCH 18/22] Guillermo - staff/add-last-login [skip ci] --- server/controllers/staff/get-all.php | 1 + server/controllers/user/login.php | 4 ++++ server/models/Staff.php | 6 ++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/server/controllers/staff/get-all.php b/server/controllers/staff/get-all.php index 13428201..2c93165a 100644 --- a/server/controllers/staff/get-all.php +++ b/server/controllers/staff/get-all.php @@ -35,6 +35,7 @@ class GetAllStaffController extends Controller { 'departments' => $staff->sharedDepartmentList->toArray(), 'assignedTickets' => $assignedTickets, 'closedTickets' => $closedTickets, + 'lastLogin' => $staff->lastLogin ]; } diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index 07cb3340..020eae13 100644 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -22,6 +22,10 @@ class LoginController extends Controller { if ($this->checkInputCredentials() || $this->checkRememberToken()) { $this->createUserSession(); $this->createSessionCookie(); + if(Controller::request('staff')) { + $this->userInstance->lastLogin = Date::getCurrentDate(); + $this->userInstance->store(); + } Response::respondSuccess($this->getUserData()); } else { diff --git a/server/models/Staff.php b/server/models/Staff.php index d2895eb4..cca0bc4c 100644 --- a/server/models/Staff.php +++ b/server/models/Staff.php @@ -17,7 +17,8 @@ class Staff extends DataStore { 'profilePic', 'level', 'sharedDepartmentList', - 'sharedTicketList' + 'sharedTicketList', + 'lastLogin' ]; } @@ -39,7 +40,8 @@ class Staff extends DataStore { 'profilePic' => $this->profilePic, 'level' => $this->level, 'departments' => $this->sharedDepartmentList->toArray(), - 'tickets' => $this->sharedTicketList->toArray() + 'tickets' => $this->sharedTicketList->toArray(), + 'lastLogin' => $this->lastLogin ]; } } From 8a5474ffc491a5e764fe8bd838725525bbbf083f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 8 Dec 2016 18:37:41 -0300 Subject: [PATCH 19/22] Max - Create add staff modal [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 38 +++++++++++++++++++ .../admin/panel/staff/add-staff-modal.scss | 0 .../panel/staff/admin-panel-staff-members.js | 9 ++++- client/src/data/languages/en.js | 3 ++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 client/src/app/admin/panel/staff/add-staff-modal.js create mode 100644 client/src/app/admin/panel/staff/add-staff-modal.scss diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js new file mode 100644 index 00000000..01ba0268 --- /dev/null +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -0,0 +1,38 @@ +import React from 'react'; + +import i18n from 'lib-app/i18n'; + +import Header from 'core-components/header' +import Form from 'core-components/form'; +import FormField from 'core-components/form-field'; +import SubmitButton from 'core-components/submit-button'; + +class AddStaffModal extends React.Component { + + render() { + return ( +
+
+
+ + + + + + {i18n('SAVE')} + + +
+ ); + } + + onSubmit(form) { + console.log(form); + } + +} + +export default AddStaffModal; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss new file mode 100644 index 00000000..e69de29b diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 2c47a6b3..5d85a0ea 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -5,6 +5,9 @@ import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import PeopleList from 'app-components/people-list'; +import ModalContainer from 'app-components/modal-container'; + +import AddStaffModal from 'app/admin/panel/staff/add-staff-modal'; import Header from 'core-components/header'; import DropDown from 'core-components/drop-down'; @@ -34,7 +37,7 @@ class AdminPanelStaffMembers extends React.Component {
-
@@ -43,6 +46,10 @@ class AdminPanelStaffMembers extends React.Component { ); } + onAddNewStaff() { + ModalContainer.openModal(); + } + getDepartmentDropdownProps() { return { items: this.getDepartments(), diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index f608dcfa..cdd04281 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -99,6 +99,8 @@ export default { 'LAST_LOGIN': 'Last login', 'STAFF_MEMBERS': 'Staff members', 'ADD_NEW_STAFF': 'Add new staff', + 'ADD_STAFF': 'Add staff', + 'LEVEL': 'Level', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', @@ -122,6 +124,7 @@ export default { 'LIST_ARTICLES_DESCRIPTION': 'This is a list of articles that includes information about our services.', 'ADD_TOPIC_DESCRIPTION': 'Here you can add a topic that works as a category for articles.', 'STAFF_MEMBERS_DESCRIPTION': 'Here you can see who are your staff members.', + 'ADD_STAFF_DESCRIPTION': 'Here you can add staff members to your teams', //ERRORS 'EMAIL_OR_PASSWORD': 'Email or password invalid', From 77f8976896dcdbaadaba3be2d71516ce4056a9c7 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 Dec 2016 17:51:30 -0300 Subject: [PATCH 20/22] Ivan - Add Checkbox group component [skip ci] --- client/src/app-components/people-list.js | 2 +- .../app/admin/panel/staff/add-staff-modal.js | 21 ++++--- .../admin/panel/staff/add-staff-modal.scss | 6 ++ client/src/core-components/checkbox-group.js | 57 +++++++++++++++++++ client/src/core-components/checkbox.js | 28 ++++++--- client/src/core-components/drop-down.scss | 13 +++++ client/src/core-components/form-field.js | 18 +++++- client/src/data/languages/en.js | 4 +- 8 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 client/src/core-components/checkbox-group.js diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 1fd18346..604d8967 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -64,7 +64,7 @@ class PeopleList extends React.Component { renderAnimatedItem(style, index) { return ( -
+
{this.renderItem(index + this.props.pageSize * (this.props.page - 1))}
); diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 01ba0268..52c2ed63 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -1,6 +1,7 @@ import React from 'react'; import i18n from 'lib-app/i18n'; +import SessionStore from 'lib-app/session-store'; import Header from 'core-components/header' import Form from 'core-components/form'; @@ -11,16 +12,19 @@ class AddStaffModal extends React.Component { render() { return ( -
+
- - + +
+ +
+ {i18n('SAVE')} @@ -29,10 +33,13 @@ class AddStaffModal extends React.Component { ); } + getDepartments() { + return SessionStore.getDepartments().map((department) => department.name); + } + onSubmit(form) { console.log(form); } - } export default AddStaffModal; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss index e69de29b..e2456788 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.scss +++ b/client/src/app/admin/panel/staff/add-staff-modal.scss @@ -0,0 +1,6 @@ +.add-staff-modal { + + &__level-selector { + text-align: center; + } +} \ No newline at end of file diff --git a/client/src/core-components/checkbox-group.js b/client/src/core-components/checkbox-group.js new file mode 100644 index 00000000..a5e97e76 --- /dev/null +++ b/client/src/core-components/checkbox-group.js @@ -0,0 +1,57 @@ +import React from 'react'; +import _ from 'lodash'; + +import Checkbox from 'core-components/checkbox'; + +class CheckboxGroup extends React.Component { + static propTypes = { + items: React.PropTypes.array.isRequired, + value: React.PropTypes.arrayOf(React.PropTypes.number), + onChange: React.PropTypes.func + }; + + state = { + value: [] + }; + + render() { + return ( +
    + {this.props.items.map(this.renderItem.bind(this))} +
+ ); + } + + renderItem(label, index) { + const checked = (_.includes(this.getValue(), index)); + + return ( +
  • + +
  • + ); + } + + onCheckboxChange(index) { + let value = _.clone(this.getValue()); + + if(_.includes(value, index)) { + _.pull(value, index); + } else { + value.push(index); + value.sort(); + } + + this.setState({value}); + + if(this.props.onChange) { + this.props.onChange({target: {value}}); + } + } + + getValue() { + return (this.props.value !== undefined) ? this.props.value : this.state.value; + } +} + +export default CheckboxGroup; \ No newline at end of file diff --git a/client/src/core-components/checkbox.js b/client/src/core-components/checkbox.js index c148783a..d269efee 100644 --- a/client/src/core-components/checkbox.js +++ b/client/src/core-components/checkbox.js @@ -11,28 +11,38 @@ class CheckBox extends React.Component { static propTypes = { alignment: React.PropTypes.string, label: React.PropTypes.string, - value: React.PropTypes.bool + value: React.PropTypes.bool, + wrapInLabel: React.PropTypes.bool, + onChange: React.PropTypes.func }; static defaultProps = { + wrapInLabel: false, alignment: 'right' }; - constructor(props) { - super(props); - - this.state = { - checked: false - }; - } + state = { + checked: false + }; render() { + let Wrapper = (this.props.wrapInLabel) ? 'label' : 'span'; + return ( - + {getIcon((this.getValue()) ? 'check-square' : 'square', 'lg') } + {(this.props.label) ? this.renderLabel() : null} + + ); + } + + renderLabel() { + return ( + + {this.props.label} ); } diff --git a/client/src/core-components/drop-down.scss b/client/src/core-components/drop-down.scss index facd5c53..7082e708 100644 --- a/client/src/core-components/drop-down.scss +++ b/client/src/core-components/drop-down.scss @@ -49,4 +49,17 @@ border: 1px solid $light-grey; } } + + &_large { + width: 300px; + + .drop-down__current-item { + border-radius: 4px; + } + + .drop-down__list-container { + width: 300px; + border: 1px solid $light-grey; + } + } } \ No newline at end of file diff --git a/client/src/core-components/form-field.js b/client/src/core-components/form-field.js index ad93729a..78cb9dad 100644 --- a/client/src/core-components/form-field.js +++ b/client/src/core-components/form-field.js @@ -6,6 +6,7 @@ import _ from 'lodash'; import Input from 'core-components/input'; import DropDown from 'core-components/drop-down'; import Checkbox from 'core-components/checkbox'; +import CheckboxGroup from 'core-components/checkbox-group'; import TextEditor from 'core-components/text-editor'; class FormField extends React.Component { @@ -21,7 +22,7 @@ class FormField extends React.Component { required: React.PropTypes.bool, error: React.PropTypes.string, value: React.PropTypes.any, - field: React.PropTypes.oneOf(['input', 'textarea', 'select', 'checkbox']), + field: React.PropTypes.oneOf(['input', 'textarea', 'select', 'checkbox', 'checkbox-group']), fieldProps: React.PropTypes.object }; @@ -36,6 +37,9 @@ class FormField extends React.Component { else if (field === 'checkbox') { return false; } + else if (field === 'checkbox-group') { + return []; + } else if (field === 'textarea') { return RichTextEditor.createEmptyValue(); } @@ -45,7 +49,7 @@ class FormField extends React.Component { } render() { - const Wrapper = (this.props.field === 'textarea') ? 'div' : 'label'; + const Wrapper = (_.includes(this.getDivTypes(), this.props.field)) ? 'div' : 'label'; const fieldContent = [ {this.props.label}, this.renderField(), @@ -67,7 +71,8 @@ class FormField extends React.Component { 'input': Input, 'textarea': TextEditor, 'select': DropDown, - 'checkbox': Checkbox + 'checkbox': Checkbox, + 'checkbox-group': CheckboxGroup }[this.props.field]; if(this.props.decorator) { @@ -122,6 +127,13 @@ class FormField extends React.Component { return props; } + getDivTypes() { + return [ + 'textarea', + 'checkbox-group' + ]; + } + onChange(nativeEvent) { let event = nativeEvent; diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index cdd04281..dc9d268f 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -97,10 +97,12 @@ export default { 'ASSIGNED_TICKETS': '{tickets} assigned tickets', 'CLOSED_TICKETS': '{tickets} closed tickets', 'LAST_LOGIN': 'Last login', - 'STAFF_MEMBERS': 'Staff members', 'ADD_NEW_STAFF': 'Add new staff', 'ADD_STAFF': 'Add staff', 'LEVEL': 'Level', + 'LEVEL_1': 'Level 1 (Tickets)', + 'LEVEL_2': 'Level 2 (Tickets + Articles)', + 'LEVEL_3': 'Level 2 (Tickets + Articles + Staff)', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', From 1e69ca3651c21156a0929950bd594b2bca00fdc5 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 Dec 2016 18:59:26 -0300 Subject: [PATCH 21/22] Ivan - Update checkbox styling, add custom scroll style for chrome [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 21 +++++++---- .../admin/panel/staff/add-staff-modal.scss | 17 +++++++++ .../src/core-components/checkbox-group.scss | 11 ++++++ client/src/core-components/checkbox.js | 4 +-- client/src/core-components/checkbox.scss | 10 ++++-- client/src/scss/_vars.scss | 35 ++++++++++++++++++- 6 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 client/src/core-components/checkbox-group.scss diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 52c2ed63..80d7fb65 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -15,16 +15,25 @@ class AddStaffModal extends React.Component {
    - - - -
    - +
    + + + +
    + +
    +
    +
    +
    +
    {i18n('Departments')}
    + +
    +
    - {i18n('SAVE')} diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss index e2456788..a2dd0d64 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.scss +++ b/client/src/app/admin/panel/staff/add-staff-modal.scss @@ -1,6 +1,23 @@ +@import "../../../../scss/vars"; + .add-staff-modal { + width: 700px; &__level-selector { text-align: center; } + + &__departments { + @include scrollbars(); + + border: 1px solid $grey; + padding: 20px; + height: 320px; + overflow-y: auto; + } + + &__departments-title { + font-size: $font-size--md; + text-align: center; + } } \ No newline at end of file diff --git a/client/src/core-components/checkbox-group.scss b/client/src/core-components/checkbox-group.scss new file mode 100644 index 00000000..92612c5c --- /dev/null +++ b/client/src/core-components/checkbox-group.scss @@ -0,0 +1,11 @@ +@import "../scss/vars"; + +.checkbox-group { + list-style-type: none; + margin: 0; + padding: 0; + + &__item { + margin: 10px 0; + } +} \ No newline at end of file diff --git a/client/src/core-components/checkbox.js b/client/src/core-components/checkbox.js index d269efee..0dc5efed 100644 --- a/client/src/core-components/checkbox.js +++ b/client/src/core-components/checkbox.js @@ -53,7 +53,7 @@ class CheckBox extends React.Component { props.type = 'checkbox'; props['aria-hidden'] = true; - props.className = 'checkbox--box'; + props.className = 'checkbox__box'; props.checked = this.getValue(); props.onChange = callback(this.handleChange.bind(this), this.props.onChange); @@ -79,7 +79,7 @@ class CheckBox extends React.Component { getIconProps() { return { 'aria-checked': this.getValue(), - className: 'checkbox--icon', + className: 'checkbox__icon', onKeyDown: callback(this.handleIconKeyDown.bind(this), this.props.onKeyDown), role: "checkbox", tabIndex: 0 diff --git a/client/src/core-components/checkbox.scss b/client/src/core-components/checkbox.scss index 9e09a1c5..68d3a18d 100644 --- a/client/src/core-components/checkbox.scss +++ b/client/src/core-components/checkbox.scss @@ -5,11 +5,11 @@ border-radius: 5px; display: inline-block; - &--box { + &__box { display: none; } - &--icon { + &__icon { color: $light-grey; outline: none; @@ -18,8 +18,12 @@ } } + &__label { + margin-left: 10px; + } + &_checked { - .checkbox--icon { + .checkbox__icon { color: $primary-red; &:focus { diff --git a/client/src/scss/_vars.scss b/client/src/scss/_vars.scss index 59793c65..cea6e370 100644 --- a/client/src/scss/_vars.scss +++ b/client/src/scss/_vars.scss @@ -25,4 +25,37 @@ $font-size--sm: 13px; $font-size--md: 16px; $font-size--bg: 19px; $font-size--lg: 24px; -$font-size--xl: 32px; \ No newline at end of file +$font-size--xl: 32px; + +@mixin scrollbars() { + $size: .4em; + $color: $grey; + + &::-webkit-scrollbar { + width: $size; + height: $size; + } + + &::-webkit-scrollbar-thumb { + background: transparent; + } + + &::-webkit-scrollbar-track { + backgroundr: transparent; + } + + &:hover { + &::-webkit-scrollbar { + width: $size; + height: $size; + } + + &::-webkit-scrollbar-thumb { + background: $color; + } + + &::-webkit-scrollbar-track { + background: lighten($color, 50%); + } + } +} From 5ce4fa1f445c3851ddfb24eb16e5dc6925c00499 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Sat, 10 Dec 2016 16:33:49 -0300 Subject: [PATCH 22/22] Ivan - Add API call to add staff modal [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 57 ++++++++++++++++++- client/src/data/fixtures/staff-fixtures.js | 13 ++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 80d7fb65..defd85bd 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -1,20 +1,33 @@ import React from 'react'; +import _ from 'lodash'; import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import Header from 'core-components/header' import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; +import Button from 'core-components/button'; class AddStaffModal extends React.Component { + static contextTypes = { + closeModal: React.PropTypes.func + }; + + state = { + loading: false, + errors: {}, + error: null + }; + render() { return (
    - + this.setState({errors})} loading={this.state.loading}>
    @@ -37,17 +50,55 @@ class AddStaffModal extends React.Component { {i18n('SAVE')} +
    ); } getDepartments() { - return SessionStore.getDepartments().map((department) => department.name); + return SessionStore.getDepartments().map(department => department.name); } onSubmit(form) { - console.log(form); + let departments = _.filter(SessionStore.getDepartments(), (department, index) => { + return _.includes(form.departments, index); + }).map(department => department.id); + + this.setState({loading: true}); + + API.call({ + path: '/staff/add', + data: { + name: form.name, + email: form.email, + password: form.password, + level: form.level + 1, + department: JSON.stringify(departments) + } + }).then(this.context.closeModal).catch((result) => { + this.setState({ + loading: false, + error: result.message + }); + }); + } + + onCancelClick(event) { + event.preventDefault(); + this.context.closeModal(); + } + + getErrors() { + let errors = _.extend({}, this.state.errors); + + if (this.state.error === 'ALREADY_A_STAFF') { + errors.email = i18n('EMAIL_EXISTS'); + } + + return errors; } } diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index 73bbd707..b0180b7b 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -629,6 +629,17 @@ module.exports = [ ] }; } - + }, + { + path: '/staff/add', + time: 100, + response: function () { + return { + status: 'success', + data: { + staffId: 5 + } + }; + } } ]; \ No newline at end of file