diff --git a/client/src/app-components/activity-row.js b/client/src/app-components/activity-row.js
new file mode 100644
index 00000000..dab5d581
--- /dev/null
+++ b/client/src/app-components/activity-row.js
@@ -0,0 +1,129 @@
+import React from 'react';
+import _ from 'lodash';
+import {Link} from 'react-router';
+
+import Icon from 'core-components/icon';
+
+import i18n from 'lib-app/i18n';
+
+class ActivityRow extends React.Component {
+
+ static propTypes = {
+ mode: React.PropTypes.oneOf(['staff', 'system']),
+ type: React.PropTypes.oneOf([
+ 'COMMENT',
+ 'ASSIGN',
+ 'UN_ASSIGN',
+ 'CLOSE',
+ 'CREATE_TICKET',
+ 'RE_OPEN',
+ 'DEPARTMENT_CHANGED',
+ 'PRIORITY_CHANGED',
+
+ 'EDIT_SETTINGS',
+ 'SIGNUP',
+ 'ADD_TOPIC',
+ 'ADD_ARTICLE',
+ 'DELETE_TOPIC',
+ 'DELETE_ARTICLE',
+ 'EDIT_ARTICLE',
+ 'ADD_STAFF',
+ 'ADD_DEPARTMENT',
+ 'DELETE_DEPARTMENT',
+ 'EDIT_DEPARTMENT',
+ 'ADD_CUSTOM_RESPONSE',
+ 'DELETE_CUSTOM_RESPONSE',
+ 'EDIT_CUSTOM_RESPONSE',
+ 'BAN_USER',
+ 'DELETE_USER',
+ 'UN_BAN_USER'
+ ]),
+ to: React.PropTypes.string,
+ ticketNumber: React.PropTypes.string,
+ author: React.PropTypes.shape({
+ name: React.PropTypes.string,
+ staff: React.PropTypes.bool,
+ id: React.PropTypes.string
+ })
+ };
+
+ render() {
+ let ticketRelatedTypes = [
+ 'COMMENT',
+ 'ASSIGN',
+ 'UN_ASSIGN',
+ 'CLOSE',
+ 'CREATE_TICKET',
+ 'RE_OPEN',
+ 'DEPARTMENT_CHANGED',
+ 'PRIORITY_CHANGED'
+ ];
+
+ return (
+
+ {this.state.activities.map(this.renderRow.bind(this))}
+ {(!this.state.limit) ? this.renderButton() : null}
+
+ );
+ }
+ else {
+ return (
+
+ {this.state.activities.map(this.renderRow.bind(this))}
+ {(!this.state.limit) ? this.renderButton() : null}
+
+ );
+ }
+ }
+
+ renderButton() {
+ return (
+
- /admin/panel/activity
+
+
+
+ {this.renderList()}
);
}
+
+ getMenuProps() {
+ return {
+ className: 'admin-panel-activity__menu',
+ type: 'horizontal-list-bright',
+ onItemClick: this.onMenuItemClick.bind(this),
+ tabbable: true,
+ items: [
+ {
+ content: i18n('MY_NOTIFICATIONS'),
+ icon: ''
+ },
+ {
+ content: i18n('ALL_NOTIFICATIONS'),
+ icon: ''
+ }
+ ]
+ };
+ }
+
+ renderList() {
+ return (
+
+ {this.state.activities.map(this.renderRow.bind(this))}
+ {(!this.state.limit) ? this.renderButton() : null}
+
+ );
+ }
+
+ renderButton() {
+ return (
+
+ {i18n('LOAD_MORE')}
+
+ );
+ }
+
+ renderRow(row, index) {
+ return (
+
+ );
+ }
+
+ onMenuItemClick(index) {
+ this.setState({
+ page: 0,
+ mode: (index === 0) ? 'staff' : 'system',
+ activities: []
+ }, this.retrieveNextPage.bind(this));
+ }
+
+ retrieveNextPage() {
+ this.setState({loading: true});
+
+ API.call({
+ path: (this.state.mode === 'staff') ? '/staff/last-events' : '/system/get-logs',
+ data: {
+ page: this.state.page
+ }
+ }).then(this.onRetrieveSuccess.bind(this));
+ }
+
+ onRetrieveSuccess(result) {
+ this.setState({
+ activities: this.state.activities.concat(result.data),
+ page: this.state.page + 1,
+ limit: (result.data.length !== 10),
+ loading: false
+ });
+ }
}
export default AdminPanelActivity;
\ No newline at end of file
diff --git a/client/src/app/admin/panel/dashboard/admin-panel-activity.scss b/client/src/app/admin/panel/dashboard/admin-panel-activity.scss
new file mode 100644
index 00000000..f3f4b462
--- /dev/null
+++ b/client/src/app/admin/panel/dashboard/admin-panel-activity.scss
@@ -0,0 +1,7 @@
+.admin-panel-activity {
+
+ &__menu {
+ margin: 0 auto 20px auto;
+ width: 300px;
+ }
+}
\ No newline at end of file
diff --git a/client/src/core-components/menu.js b/client/src/core-components/menu.js
index de7cd63e..25cd805d 100644
--- a/client/src/core-components/menu.js
+++ b/client/src/core-components/menu.js
@@ -11,7 +11,7 @@ class Menu extends React.Component {
id: React.PropTypes.string,
itemsRole: React.PropTypes.string,
header: React.PropTypes.string,
- type: React.PropTypes.oneOf(['primary', 'secondary', 'navigation', 'horizontal', 'horizontal-list']),
+ type: React.PropTypes.oneOf(['primary', 'secondary', 'navigation', 'horizontal', 'horizontal-list', 'horizontal-list-bright']),
items: React.PropTypes.arrayOf(React.PropTypes.shape({
content: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number, React.PropTypes.node]),
icon: React.PropTypes.string
@@ -86,7 +86,8 @@ class Menu extends React.Component {
'menu_secondary': (this.props.type === 'secondary'),
'menu_navigation': (this.props.type === 'navigation'),
'menu_horizontal': (this.props.type === 'horizontal'),
- 'menu_horizontal-list': (this.props.type === 'horizontal-list')
+ 'menu_horizontal-list': (this.props.type === 'horizontal-list'),
+ 'menu_horizontal-list-bright': (this.props.type === 'horizontal-list-bright')
};
classes[this.props.className] = true;
diff --git a/client/src/core-components/menu.scss b/client/src/core-components/menu.scss
index 6fc7486a..64eab16c 100644
--- a/client/src/core-components/menu.scss
+++ b/client/src/core-components/menu.scss
@@ -132,7 +132,8 @@ $transition: background-color 0.3s ease, color 0.3s ease;
}
}
- &_horizontal-list {
+ &_horizontal-list,
+ &_horizontal-list-bright {
text-align: left;
background-color: $secondary-blue;
min-height: 45px;
@@ -165,6 +166,32 @@ $transition: background-color 0.3s ease, color 0.3s ease;
outline: none;
}
+ .menu__list-item_selected,
+ .menu__list-item_selected:hover {
+ transition: $transition;
+ padding: 2px 13px;
+ border-radius: 30px;
+ background-color: $primary-blue;
+ color: white;
+ }
+ }
+
+ &_horizontal-list-bright {
+ background-color: transparent;
+
+ .menu__list-item {
+ transition: none;
+ background-color: transparent;
+ color: black;
+ cursor: pointer;
+ display: inline-block;
+ margin-top: 11px;
+ margin-bottom: 10px;
+ margin-left: 20px;
+ padding: 2px 13px;
+ }
+
+
.menu__list-item_selected,
.menu__list-item_selected:hover {
transition: $transition;
diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js
index 0de75e1f..ac7a07ee 100644
--- a/client/src/data/fixtures/staff-fixtures.js
+++ b/client/src/data/fixtures/staff-fixtures.js
@@ -1057,5 +1057,114 @@ module.exports = [
data: {}
};
}
+ },
+ {
+ path: '/staff/last-events',
+ time: 300,
+ response: function(data) {
+
+ if(data.page > 5) {
+ return {
+ status: 'success',
+ data: []
+ };
+ }
+
+ return {
+ status: 'success',
+ data: [
+ {
+ "type": "COMMENT",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Tyrion Lannister",
+ "staff": false,
+ "id": "10"
+ }
+ },
+ {
+ "type": "RE_OPEN",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Tyrion Lannister",
+ "staff": false,
+ "id": "10"
+ }
+ },
+ {
+ "type": "CLOSE",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "DEPARTMENT_CHANGED",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "PRIORITY_CHANGED",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "ASSIGN",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "UN_ASSIGN",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "COMMENT",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "ASSIGN",
+ "ticketNumber": "683061",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ },
+ {
+ "type": "PRIORITY_CHANGED",
+ "ticketNumber": "608120",
+ "author": {
+ "name": "Emilia Clarke",
+ "staff": true,
+ "id": "1"
+ }
+ }
+ ]
+ };
+ }
}
];
diff --git a/client/src/data/fixtures/system-fixtures.js b/client/src/data/fixtures/system-fixtures.js
index 5d410a10..a9f5687c 100644
--- a/client/src/data/fixtures/system-fixtures.js
+++ b/client/src/data/fixtures/system-fixtures.js
@@ -156,5 +156,106 @@ module.exports = [
]
};
}
+ },
+ {
+ path: '/system/get-logs',
+ time: 300,
+ response: function() {
+ return {
+ "status": "success",
+ "data": [
+ {
+ "type": "EDIT_SETTINGS",
+ "to": null,
+ "author": {
+ "name": "Emilia Clarke",
+ "id": "1",
+ "staff": true
+ }
+ },
+ {
+ "type": "SIGNUP",
+ "to": null,
+ "author": {
+ "name": "Steve Jobs",
+ "id": "1",
+ "staff": false
+ }
+ },
+ {
+ "type": "SIGNUP",
+ "to": null,
+ "author": {
+ "name": "steve jobs",
+ "id": "2",
+ "staff": false
+ }
+ },
+ {
+ "type": "SIGNUP",
+ "to": null,
+ "author": {
+ "name": "steve jobs",
+ "id": "3",
+ "staff": false
+ }
+ },
+ {
+ "type": "SIGNUP",
+ "to": null,
+ "author": {
+ "name": "Creator",
+ "id": "5",
+ "staff": false
+ }
+ },
+ {
+ "type": "CREATE_TICKET",
+ "to": "739228",
+ "author": {
+ "name": "Creator",
+ "id": "5",
+ "staff": false
+ }
+ },
+ {
+ "type": "CREATE_TICKET",
+ "to": "915839",
+ "author": {
+ "name": "Creator",
+ "id": "5",
+ "staff": false
+ }
+ },
+ {
+ "type": "CREATE_TICKET",
+ "to": "192450",
+ "author": {
+ "name": "Creator",
+ "id": "5",
+ "staff": false
+ }
+ },
+ {
+ "type": "CREATE_TICKET",
+ "to": "369061",
+ "author": {
+ "name": "Creator",
+ "id": "5",
+ "staff": false
+ }
+ },
+ {
+ "type": "SIGNUP",
+ "to": null,
+ "author": {
+ "name": "Commenter",
+ "id": "6",
+ "staff": false
+ }
+ }
+ ]
+ };
+ }
}
];
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index d3df05aa..3f193dd2 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -141,6 +141,37 @@ export default {
'OFF': 'Off',
'BOXED': 'Boxed',
'FULL_WIDTH': 'Full width',
+ 'LOAD_MORE': 'Load More',
+ 'MY_NOTIFICATIONS': 'My notifications',
+ 'ALL_NOTIFICATIONS': 'All notifications',
+
+ //ACTIVITIES
+ 'ACTIVITY_COMMENT': 'commented ticket',
+ 'ACTIVITY_ASSIGN': 'assigned ticket',
+ 'ACTIVITY_UN_ASSIGN': 'unassigned ticket',
+ 'ACTIVITY_CLOSE': 'closed ticket',
+ 'ACTIVITY_CREATE_TICKET': 'created ticket',
+ 'ACTIVITY_RE_OPEN': 'reopened ticket',
+ 'ACTIVITY_DEPARTMENT_CHANGED': 'changed department of ticket',
+ 'ACTIVITY_PRIORITY_CHANGED': 'changed priority of ticket',
+
+ 'ACTIVITY_EDIT_SETTINGS': 'edited settings',
+ 'ACTIVITY_SIGNUP': 'signed up',
+ 'ACTIVITY_ADD_TOPIC': 'added topic',
+ 'ACTIVITY_ADD_ARTICLE': 'added article',
+ 'ACTIVITY_DELETE_TOPIC': 'deleted topic',
+ 'ACTIVITY_DELETE_ARTICLE': 'deleted article',
+ 'ACTIVITY_EDIT_ARTICLE': 'edited article',
+ 'ACTIVITY_ADD_STAFF': 'added staff',
+ 'ACTIVITY_ADD_DEPARTMENT': 'added department',
+ 'ACTIVITY_DELETE_DEPARTMENT': 'deleted department',
+ 'ACTIVITY_EDIT_DEPARTMENT': 'edited department',
+ 'ACTIVITY_ADD_CUSTOM_RESPONSE': 'added custom response',
+ 'ACTIVITY_DELETE_CUSTOM_RESPONSE': 'deleted custom response',
+ 'ACTIVITY_EDIT_CUSTOM_RESPONSE': 'edited custom response',
+ 'ACTIVITY_BAN_USER': 'banned user',
+ 'ACTIVITY_DELETE_USER': 'deleted user',
+ 'ACTIVITY_UN_BAN_USER': 'banned user',
//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.',
diff --git a/server/controllers/system/get-logs.php b/server/controllers/system/get-logs.php
index 52f0224b..90ffd6b9 100644
--- a/server/controllers/system/get-logs.php
+++ b/server/controllers/system/get-logs.php
@@ -17,7 +17,7 @@ class GetLogsController extends Controller {
}
public function handler() {
- $page =Controller::request('page');
+ $page = Controller::request('page');
$logList = Log::find('LIMIT ? OFFSET ?', [10, 10*($page-1)+1]);
Response::respondSuccess($logList->toArray());
diff --git a/server/controllers/ticket/change-department.php b/server/controllers/ticket/change-department.php
index 2cfe0f25..ac2e78da 100644
--- a/server/controllers/ticket/change-department.php
+++ b/server/controllers/ticket/change-department.php
@@ -44,7 +44,7 @@ class ChangeDepartmentController extends Controller {
$ticket->unread = true;
$ticket->store();
- Log::createLog('CHANGE_DEPARTMENT', $department);
+ Log::createLog('DEPARTMENT_CHANGED', $ticket->ticketNumber);
Response::respondSuccess();
}
diff --git a/server/controllers/ticket/change-priority.php b/server/controllers/ticket/change-priority.php
index 989fa5ec..2e671a57 100644
--- a/server/controllers/ticket/change-priority.php
+++ b/server/controllers/ticket/change-priority.php
@@ -38,7 +38,7 @@ class ChangePriorityController extends Controller {
$ticket->addEvent($event);
$ticket->store();
- Log::createLog('CHANGE_PRIORITY', $priority);
+ Log::createLog('PRIORITY_CHANGED', $ticket->ticketNumber);
Response::respondSuccess();
} else {
Response::respondError(ERRORS::NO_PERMISSION);
diff --git a/server/controllers/ticket/close.php b/server/controllers/ticket/close.php
index 3080c7b2..ed983a35 100644
--- a/server/controllers/ticket/close.php
+++ b/server/controllers/ticket/close.php
@@ -33,7 +33,7 @@ class CloseController extends Controller {
$this->ticket->store();
- Log::createLog('CLOSE_TICKET', $this->ticket);
+ Log::createLog('CLOSE', $this->ticket->ticketNumber);
Response::respondSuccess();
}
diff --git a/server/controllers/ticket/comment.php b/server/controllers/ticket/comment.php
index b998ee5e..b51414c2 100644
--- a/server/controllers/ticket/comment.php
+++ b/server/controllers/ticket/comment.php
@@ -31,7 +31,7 @@ class CommentController extends Controller {
if ($session->isLoggedWithId($this->ticket->author->id) || Controller::isStaffLogged()) {
$this->storeComment();
- Log::createLog('COMMENT_TICKET', $this->ticket);
+ Log::createLog('COMMENT', $this->ticket->ticketNumber);
Response::respondSuccess();
} else {
diff --git a/server/controllers/ticket/create.php b/server/controllers/ticket/create.php
index 4818ca11..ac9f4c53 100644
--- a/server/controllers/ticket/create.php
+++ b/server/controllers/ticket/create.php
@@ -43,7 +43,7 @@ class CreateController extends Controller {
$this->storeTicket();
- Log::createLog('CREATE_TICKET', $this->title);
+ Log::createLog('CREATE_TICKET', $this->ticketNumber);
Response::respondSuccess([
'ticketNumber' => $this->ticketNumber
]);
diff --git a/server/controllers/ticket/re-open.php b/server/controllers/ticket/re-open.php
index b5f97713..b2754256 100644
--- a/server/controllers/ticket/re-open.php
+++ b/server/controllers/ticket/re-open.php
@@ -32,7 +32,7 @@ class ReOpenController extends Controller {
$this->ticket->store();
- Log::createLog('RE_OPEN_TICKET', $this->ticket);
+ Log::createLog('RE_OPEN', $this->ticket->ticketNumber);
Response::respondSuccess();
}
diff --git a/server/controllers/user/un-ban.php b/server/controllers/user/un-ban.php
index 30a83e02..d1d53d52 100644
--- a/server/controllers/user/un-ban.php
+++ b/server/controllers/user/un-ban.php
@@ -29,7 +29,6 @@ class UnBanUserController extends Controller {
Response::respondSuccess();
}
-
}
}
\ No newline at end of file
diff --git a/server/models/Log.php b/server/models/Log.php
index 30038d3c..ebe24469 100644
--- a/server/models/Log.php
+++ b/server/models/Log.php
@@ -17,7 +17,8 @@ class Log extends DataStore {
if($author === null) {
$author = Controller::getLoggedUser();
}
- $log = new Log();
+
+ $log = new Log();
$log->setProperties(array(
'type' => $type,
@@ -34,10 +35,16 @@ class Log extends DataStore {
}
public function toArray() {
+ $author = ($this->authorUser instanceof User) ? $this->authorUser : $this->authorStaff;
+
return [
'type' => $this->type,
'to' => $this->to,
- 'author' => ($this->authorUser instanceof User) ? $this->authorUser->toArray() : $this->authorStaff->toArray()
+ 'author' => [
+ 'name' => $author->name,
+ 'id' => $author->id,
+ 'staff' => $author instanceof Staff
+ ]
];
}
}
\ No newline at end of file
diff --git a/server/models/Ticketevent.php b/server/models/Ticketevent.php
index be1229bf..4bd7ebb1 100644
--- a/server/models/Ticketevent.php
+++ b/server/models/Ticketevent.php
@@ -67,6 +67,7 @@ class Ticketevent extends DataStore {
'ticketNumber' => $this->ticket->ticketNumber,
'author' => [
'name' => $user->name,
+ 'staff' => $user instanceOf Staff,
'id' => $user->id
]
];