diff --git a/config/env/default.js b/config/env/default.js
index 449b5ace..21a5b148 100644
--- a/config/env/default.js
+++ b/config/env/default.js
@@ -108,7 +108,6 @@ module.exports = {
tickets: {
image: {
dest: './modules/tickets/client/uploads/image/',
- crop: './modules/tickets/client/uploads/image/crop/',
temp: './modules/tickets/client/uploads/temp/',
limits: {
fileSize: 2 * 1024 * 1024 // Max file size in bytes (2 MB)
diff --git a/config/env/torrents.js b/config/env/torrents.js
index 71390045..8064e86f 100644
--- a/config/env/torrents.js
+++ b/config/env/torrents.js
@@ -412,8 +412,10 @@ module.exports = {
*
* @userSignatureLength: user signature of forum string length limit
* @chatMessageMaxLength: chat room send message string length limit
+ * @messageTitleLength: user message send title length limit
* @messageBoxContentLength: user message send content length limit
* @messageBoxReplyLength: user message send reply content length limit
+ * @ticketContentLength: ticket content length limit
* @torrentCommentLength: torrent comment send content length limit
* @forumTopicTitleLength: forum topic title length limit
* @forumTopicContentLength: forum topic content length limit
@@ -425,8 +427,10 @@ module.exports = {
userSignatureLength: 512,
chatMessageMaxLength: 512,
+ messageTitleLength: 128,
messageBoxContentLength: 1024,
messageBoxReplyLength: 512,
+ ticketContentLength: 2048,
torrentCommentLength: 512,
@@ -1143,7 +1147,9 @@ module.exports = {
*
* @examinationUserListPerPage: users item number of examination result page
* @messageTicketsListPerPage: message tickets items number of support list page
+ * @messageTicketRepliesPerPage: message ticket replies list page settings
* @mailTicketsListPerPage: mail tickets items number of support list page
+ * @mailTicketRepliesPerPage: mail ticket replies list page settings
*/
itemsPerPage: {
topicsPerPage: 10,
@@ -1174,7 +1180,9 @@ module.exports = {
examinationUserListPerPage: 20,
messageTicketsListPerPage: 15,
- mailTicketsListPerPage: 15
+ messageTicketRepliesPerPage: 10,
+ mailTicketsListPerPage: 15,
+ mailTicketRepliesPerPage: 10
},
/**
diff --git a/config/lib/multer.js b/config/lib/multer.js
index 5227fc10..545ba9ef 100644
--- a/config/lib/multer.js
+++ b/config/lib/multer.js
@@ -202,3 +202,42 @@ module.exports.createUploadTorrentImageFilename = function (req, file, cb) {
module.exports.getUploadTorrentImageDestination = function (req, file, cb) {
cb(null, config.uploads.torrent.image.temp);
};
+
+
+module.exports.createUploadTicketImageFilename = function (req, file, cb) {
+ var RexStr = /\(|\)|\[|\]|\,/g;
+ var filename = file.originalname.replace(RexStr, function (MatchStr) {
+ switch (MatchStr) {
+ case '(':
+ return '<';
+ case ')':
+ return '>';
+ case '[':
+ return '{';
+ case ']':
+ return '}';
+ case ',':
+ return ' ';
+ default:
+ break;
+ }
+ });
+
+ if (fs.existsSync(config.uploads.tickets.image.temp + filename)) {
+ fs.unlinkSync(config.uploads.tickets.image.temp + filename);
+ }
+
+ if (fs.existsSync(config.uploads.tickets.image.dest + filename)) {
+ var ext = file.originalname.replace(/^.+\./, '');
+ var regex = new RegExp(ext, 'g');
+ filename = filename.replace(regex, Date.now() + '.' + ext);
+
+ cb(null, filename);
+ } else {
+ cb(null, filename);
+ }
+};
+
+module.exports.getUploadTicketImageDestination = function (req, file, cb) {
+ cb(null, config.uploads.tickets.image.temp);
+};
diff --git a/gulpfile.js b/gulpfile.js
index 6fcb7adf..c52a0b29 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -117,8 +117,8 @@ gulp.task('csslint', function () {
return gulp.src(defaultAssets.client.css)
.pipe(plugins.csslint('.csslintrc'))
.pipe(plugins.csslint.formatter());
- // Don't fail CSS issues yet
- // .pipe(plugins.csslint.failFormatter());
+ // Don't fail CSS issues yet
+ // .pipe(plugins.csslint.failFormatter());
});
// ESLint JS linting task
@@ -187,7 +187,7 @@ gulp.task('imagemin', function () {
return gulp.src(defaultAssets.client.img)
.pipe(plugins.imagemin({
progressive: true,
- svgoPlugins: [{ removeViewBox: false }],
+ svgoPlugins: [{removeViewBox: false}],
use: [pngquant()]
}))
.pipe(gulp.dest('public/dist/img'));
@@ -260,61 +260,66 @@ gulp.task('makeUploadsDir', function () {
fs.mkdir('modules/torrents/client/uploads', function (err) {
if (err && err.code !== 'EEXIST') {
console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/temp', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
+ } else {
+ fs.mkdir('modules/torrents/client/uploads/temp', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
+ fs.mkdir('modules/torrents/client/uploads/subtitles', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
+ fs.mkdir('modules/torrents/client/uploads/cover', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ } else {
+ fs.mkdir('modules/torrents/client/uploads/cover/crop', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
+ }
+ });
+ fs.mkdir('modules/torrents/client/uploads/image', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ } else {
+ fs.mkdir('modules/torrents/client/uploads/image/crop', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
+ }
+ });
}
});
fs.mkdir('modules/forums/client/attach', function (err) {
if (err && err.code !== 'EEXIST') {
console.error(err);
+ } else {
+ fs.mkdir('modules/forums/client/attach/temp', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
}
});
- fs.mkdir('modules/forums/client/attach/temp', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/subtitles', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/cover', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/cover/crop', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/image', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/torrents/client/uploads/image/crop', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/tickets/client/uploads/temp', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/tickets/client/uploads/image', function (err) {
- if (err && err.code !== 'EEXIST') {
- console.error(err);
- }
- });
- fs.mkdir('modules/tickets/client/uploads/image/crop', function (err) {
+ fs.mkdir('modules/tickets/client/uploads', function (err) {
if (err && err.code !== 'EEXIST') {
console.error(err);
+ } else {
+ fs.mkdir('modules/tickets/client/uploads/temp', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
+ fs.mkdir('modules/tickets/client/uploads/image', function (err) {
+ if (err && err.code !== 'EEXIST') {
+ console.error(err);
+ }
+ });
}
});
@@ -372,7 +377,7 @@ gulp.task('pre-test', function () {
// Display coverage for all server JavaScript files
return gulp.src(defaultAssets.server.allJS)
- // Covering files
+ // Covering files
.pipe(plugins.istanbul())
// Force `require` to return covered files
.pipe(plugins.istanbul.hookRequire());
@@ -384,7 +389,7 @@ gulp.task('mocha:coverage', ['pre-test', 'mocha'], function () {
return gulp.src(testSuites)
.pipe(plugins.istanbul.writeReports({
- reportOpts: { dir: './coverage/server' }
+ reportOpts: {dir: './coverage/server'}
}));
});
@@ -415,7 +420,7 @@ gulp.task('karma:coverage', function (done) {
coverageReporter: {
dir: 'coverage/client',
reporters: [
- { type: 'lcov', subdir: '.' }
+ {type: 'lcov', subdir: '.'}
// printing summary to console currently weirdly causes gulp to hang so disabled for now
// https://github.com/karma-runner/karma-coverage/issues/209
// { type: 'text-summary' }
diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js
index 05c9ce48..719a3fda 100644
--- a/modules/core/client/app/trans-string-en.js
+++ b/modules/core/client/app/trans-string-en.js
@@ -1184,8 +1184,8 @@
POST_TOPIC_FAILED: 'Post new topic failed',
POST_REPLY_SUCCESSFULLY: 'Post new reply successfully',
POST_REPLY_FAILED: 'Post new reply failed',
- TOPIC_EDIT_SUCCESSFULLY: 'Reply content modify successfully',
- TOPIC_EDIT_FAILED: 'Reply content modify failed',
+ TOPIC_EDIT_SUCCESSFULLY: 'Topic content modify successfully',
+ TOPIC_EDIT_FAILED: 'Topic content modify failed',
TOPIC_TOGGLE_READONLY_SUCCESSFULLY: 'Toggle set topic readonly successfully',
TOPIC_TOGGLE_READONLY_FAILED: 'Toggle set topic readonly failed',
TOPIC_SEARCH_FAILED: 'Topics search failed',
@@ -1363,7 +1363,16 @@
FIELDS_REPLIES: 'Replies',
FIELDS_STATUS: 'Status',
FIELDS_CREATEDAT: 'Created At',
- FIELDS_UPDATEDAT: 'Updated At'
+ FIELDS_UPDATEDAT: 'Updated At',
+ LINK_HANDLE: 'Handle',
+ TICKET_EDIT_SUCCESSFULLY: 'Ticket content modify successfully',
+ TICKET_EDIT_FAILED: 'Ticket content modify failed',
+ DELETE_TICKET_CONFIRM_OK: 'Delete',
+ DELETE_TICKET_CONFIRM_CANCEL: 'Cancel',
+ DELETE_TICKET_CONFIRM_HEADER_TEXT: 'Delete Ticket',
+ DELETE_TICKET_CONFIRM_BODY_TEXT: 'Are you sure want to delete this ticket?',
+ DELETE_TICKET_SUCCESSFULLY: 'Ticket deleted successfully',
+ DELETE_TICKET_FAILED: 'Ticket deleted failed'
},
/////////////////////////resources tag fields///////////////////////////////////
diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js
index b791820f..cc3a509a 100644
--- a/modules/core/client/app/trans-string-zh.js
+++ b/modules/core/client/app/trans-string-zh.js
@@ -1363,7 +1363,16 @@
FIELDS_REPLIES: '回复数',
FIELDS_STATUS: '状态',
FIELDS_CREATEDAT: '创建日期',
- FIELDS_UPDATEDAT: '更新日期'
+ FIELDS_UPDATEDAT: '更新日期',
+ LINK_HANDLE: '接手服务',
+ TICKET_EDIT_SUCCESSFULLY: '客服内容修改成功',
+ TICKET_EDIT_FAILED: '客服内容修改失败',
+ DELETE_TICKET_CONFIRM_OK: '删除',
+ DELETE_TICKET_CONFIRM_CANCEL: '取消',
+ DELETE_TICKET_CONFIRM_HEADER_TEXT: '删除客服条目',
+ DELETE_TICKET_CONFIRM_BODY_TEXT: '您确定要删除此客户服务内容条目?',
+ DELETE_TICKET_SUCCESSFULLY: '客服条目删除成功',
+ DELETE_TICKET_FAILED: '客服条目删除失败'
},
/////////////////////////resources tag fields///////////////////////////////////
diff --git a/modules/forums/client/controllers/forums-topic.client.controller.js b/modules/forums/client/controllers/forums-topic.client.controller.js
index 37371a11..6892b9be 100644
--- a/modules/forums/client/controllers/forums-topic.client.controller.js
+++ b/modules/forums/client/controllers/forums-topic.client.controller.js
@@ -326,7 +326,7 @@
vm.figureOutItemsToDisplay();
NotifycationService.showSuccessNotify('FORUMS.REPLY_EDIT_SUCCESSFULLY');
}, function (res) {
- NotifycationService.showErrorNotify(res.data.message, 'FORUMS.FORUMS');
+ NotifycationService.showErrorNotify(res.data.message, 'FORUMS.REPLY_EDIT_FAILED');
});
e.$options.hideable = true;
diff --git a/modules/forums/server/controllers/forums.server.controller.js b/modules/forums/server/controllers/forums.server.controller.js
index fbf7449f..0a6b890e 100644
--- a/modules/forums/server/controllers/forums.server.controller.js
+++ b/modules/forums/server/controllers/forums.server.controller.js
@@ -979,7 +979,6 @@ exports.updateReply = function (req, res) {
});
};
-
/**
* deleteReply
* @param req
diff --git a/modules/tickets/client/config/tickets-admin.client.routes.js b/modules/tickets/client/config/tickets-admin.client.routes.js
index 98b11be2..04d61bd9 100644
--- a/modules/tickets/client/config/tickets-admin.client.routes.js
+++ b/modules/tickets/client/config/tickets-admin.client.routes.js
@@ -31,6 +31,14 @@
.state('admin.tickets.support.mail', {
url: '/mail',
templateUrl: '/modules/tickets/client/views/support-mail.client.view.html'
+ })
+ .state('admin.tickets.support.viewMessage', {
+ url: '/viewMessage/:messageTicketId',
+ templateUrl: '/modules/tickets/client/views/support-view-message.client.view.html'
+ })
+ .state('admin.tickets.support.viewMail', {
+ url: '/viewMail/:mailTicketId',
+ templateUrl: '/modules/tickets/client/views/support-view-mail.client.view.html'
});
}
diff --git a/modules/tickets/client/controllers/message-tickets.client.controller.js b/modules/tickets/client/controllers/message-tickets.client.controller.js
index 7448be01..59473d99 100644
--- a/modules/tickets/client/controllers/message-tickets.client.controller.js
+++ b/modules/tickets/client/controllers/message-tickets.client.controller.js
@@ -6,11 +6,12 @@
.controller('MessageTicketController', MessageTicketController);
MessageTicketController.$inject = ['$scope', '$state', '$timeout', '$translate', 'Authentication', 'MessageTicketsService', 'ModalConfirmService', 'NotifycationService', 'marked',
- 'DebugConsoleService', 'MeanTorrentConfig', '$filter'];
+ 'DebugConsoleService', 'MeanTorrentConfig', '$filter', '$rootScope'];
function MessageTicketController($scope, $state, $timeout, $translate, Authentication, MessageTicketsService, ModalConfirmService, NotifycationService, marked,
- mtDebug, MeanTorrentConfig, $filter) {
+ mtDebug, MeanTorrentConfig, $filter, $rootScope) {
var vm = this;
+ $rootScope.$state = $state;
vm.user = Authentication.user;
vm.itemsPerPageConfig = MeanTorrentConfig.meanTorrentConfig.itemsPerPage;
vm.supportConfig = MeanTorrentConfig.meanTorrentConfig.support;
diff --git a/modules/tickets/client/controllers/view-message-tickets.client.controller.js b/modules/tickets/client/controllers/view-message-tickets.client.controller.js
new file mode 100644
index 00000000..3d5c35af
--- /dev/null
+++ b/modules/tickets/client/controllers/view-message-tickets.client.controller.js
@@ -0,0 +1,447 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('tickets')
+ .controller('ViewMessageTicketController', ViewMessageTicketController);
+
+ ViewMessageTicketController.$inject = ['$scope', '$state', '$timeout', '$translate', 'Authentication', 'MessageTicketsService', 'ModalConfirmService', 'NotifycationService', 'marked',
+ 'DebugConsoleService', 'MeanTorrentConfig', '$filter', '$stateParams', 'Upload', 'localStorageService', '$compile'];
+
+ function ViewMessageTicketController($scope, $state, $timeout, $translate, Authentication, MessageTicketsService, ModalConfirmService, NotifycationService, marked,
+ mtDebug, MeanTorrentConfig, $filter, $stateParams, Upload, localStorageService, $compile) {
+ var vm = this;
+ vm.user = Authentication.user;
+ vm.itemsPerPageConfig = MeanTorrentConfig.meanTorrentConfig.itemsPerPage;
+ vm.supportConfig = MeanTorrentConfig.meanTorrentConfig.support;
+ vm.inputLengthConfig = MeanTorrentConfig.meanTorrentConfig.inputLength;
+
+ /**
+ * init
+ */
+ vm.init = function () {
+ MessageTicketsService.get({
+ messageTicketId: $stateParams.messageTicketId
+ }, function (ticket) {
+ mtDebug.info(ticket);
+ vm.ticket = ticket;
+ vm.buildPager();
+ });
+ };
+
+ /**
+ * buildPager
+ * pagination init
+ */
+ vm.buildPager = function () {
+ vm.pagedItems = [];
+ vm.itemsPerPage = vm.itemsPerPageConfig.messageTicketRepliesPerPage;
+ vm.currentPage = 1;
+ vm.figureOutItemsToDisplay();
+ };
+
+ /**
+ * figureOutItemsToDisplay
+ * @param callback
+ */
+ vm.figureOutItemsToDisplay = function (callback) {
+ vm.filterLength = vm.ticket._replies.length;
+ var begin = ((vm.currentPage - 1) * vm.itemsPerPage);
+ var end = begin + vm.itemsPerPage;
+ vm.pagedItems = vm.ticket._replies.slice(begin, end);
+
+ if (callback) callback();
+ };
+
+ /**
+ * pageChanged
+ */
+ vm.pageChanged = function () {
+ var element = angular.element('#top_of_reply_list');
+
+ vm.figureOutItemsToDisplay(function () {
+ $timeout(function () {
+ $('html,body').animate({scrollTop: element[0].offsetTop - 60}, 200);
+ }, 10);
+ });
+ };
+
+ /**
+ * getTicketContent
+ * @param t
+ * @returns {*}
+ */
+ vm.getTicketContent = function (t) {
+ if (t) {
+ return marked(t.content, {sanitize: true});
+ }
+ };
+
+ /**
+ * canEdit
+ * @returns {boolean}
+ */
+ vm.canEdit = function () {
+ if (vm.user.isOper) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ /**
+ * isOwner
+ * @param o, ticket
+ * @returns {boolean}
+ */
+ vm.isOwner = function (o) {
+ if (o) {
+ if (o.from._id === vm.user._id) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ };
+
+ /**
+ * onTopicTitleEdited
+ */
+ $scope.onTopicTitleEdited = function (modifyed) {
+ if (vm.ticket && modifyed) {
+ vm.ticket.$update(function (res) {
+ vm.ticket = res;
+ NotifycationService.showSuccessNotify('SUPPORT.TICKET_EDIT_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'SUPPORT.TICKET_EDIT_FAILED');
+ });
+ }
+ };
+
+ /**
+ * postReply
+ * @param isValid
+ * @returns {boolean}
+ */
+ vm.postReply = function (isValid) {
+ if (!isValid) {
+ $scope.$broadcast('show-errors-check-validity', 'vm.replyForm');
+ return false;
+ }
+
+ mtDebug.info($scope.uImages);
+ var uimg = [];
+ angular.forEach($scope.uImages, function (f) {
+ uimg.push({
+ filename: f.name
+ });
+ });
+
+ var reply = new MessageTicketsService(vm.postReplyFields);
+ reply._uImage = uimg;
+
+ reply.$save({
+ messageTicketId: vm.ticket._id
+ }, function (response) {
+ successCallback(response);
+ }, function (errorResponse) {
+ errorCallback(errorResponse);
+ });
+
+ function successCallback(res) {
+ console.log(res);
+ vm.postReplyFields = {};
+ vm.currentPage = Math.ceil(res._replies.length / vm.itemsPerPage);
+ vm.ticket = res;
+ vm.pageChanged();
+
+ $scope.$broadcast('show-errors-reset', 'vm.replyForm');
+ $scope.clearnAttach();
+ $scope.hidePreview();
+ NotifycationService.showSuccessNotify('FORUMS.POST_REPLY_SUCCESSFULLY');
+ }
+
+ function errorCallback(res) {
+ NotifycationService.showErrorNotify(res.data.message, 'FORUMS.POST_REPLY_FAILED');
+ }
+ };
+
+ /**
+ * uploadTicketImage
+ * @param editor
+ * @param ufile
+ * @param progressback
+ * @param callback
+ * @param errback
+ */
+ vm.uploadTicketImage = function (editor, ufile, progressback, callback, errback) {
+ Upload.upload({
+ url: '/api/messageTickets/uploadTicketImage',
+ data: {
+ newTicketImageFile: ufile
+ }
+ }).then(function (res) {
+ if (callback) {
+ callback(res.data.filename);
+ }
+ }, function (res) {
+ if (errback && res.status > 0) {
+ errback(res);
+ }
+ }, function (evt) {
+ if (progressback) {
+ progressback(parseInt(100.0 * evt.loaded / evt.total, 10));
+ }
+ });
+ };
+
+ /**
+ * beginDeleteTicket
+ * @param t
+ */
+ vm.beginDeleteTicket = function (t) {
+ var modalOptions = {
+ closeButtonText: $translate.instant('SUPPORT.DELETE_TICKET_CONFIRM_CANCEL'),
+ actionButtonText: $translate.instant('SUPPORT.DELETE_TICKET_CONFIRM_OK'),
+ headerText: $translate.instant('SUPPORT.DELETE_TICKET_CONFIRM_HEADER_TEXT'),
+ bodyText: $translate.instant('SUPPORT.DELETE_TICKET_CONFIRM_BODY_TEXT')
+ };
+
+ ModalConfirmService.showModal({}, modalOptions)
+ .then(function (result) {
+ MessageTicketsService.remove({
+ messageTicketId: t._id,
+ replyId: undefined
+ }, function (res) {
+ console.log(res);
+ NotifycationService.showSuccessNotify('SUPPORT.DELETE_TICKET_SUCCESSFULLY');
+ $state.go('admin.tickets.support.message');
+ }, function (res) {
+ console.log(res);
+ NotifycationService.showErrorNotify(res.data.message, 'SUPPORT.DELETE_TICKET_FAILED');
+ });
+ });
+ };
+
+ /**
+ * beginDeleteReply
+ * @param reply
+ */
+ vm.beginDeleteReply = function (reply) {
+ var modalOptions = {
+ closeButtonText: $translate.instant('FORUMS.DELETE_TOPIC_CONFIRM_CANCEL'),
+ actionButtonText: $translate.instant('FORUMS.DELETE_TOPIC_CONFIRM_OK'),
+ headerText: $translate.instant('FORUMS.DELETE_REPLY_CONFIRM_HEADER_TEXT'),
+ bodyText: $translate.instant('FORUMS.DELETE_REPLY_CONFIRM_BODY_TEXT')
+ };
+
+ ModalConfirmService.showModal({}, modalOptions)
+ .then(function (result) {
+ MessageTicketsService.remove({
+ messageTicketId: vm.ticket._id,
+ replyId: reply._id
+ }, function (res) {
+ console.log(res);
+ vm.ticket = res;
+ vm.figureOutItemsToDisplay();
+ NotifycationService.showSuccessNotify('FORUMS.DELETE_REPLY_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'FORUMS.DELETE_REPLY_FAILED');
+ });
+ });
+ };
+
+ /**
+ * beginEditTicket
+ * @param t
+ */
+ vm.beginEditTicket = function (t) {
+ var el = $('#' + t._id);
+
+ el.markdown({
+ autofocus: true,
+ savable: true,
+ hideable: true,
+ iconlibrary: 'fa',
+ resize: 'vertical',
+ language: localStorageService.get('storage_user_lang'),
+ fullscreen: {enable: false},
+ onSave: function (e) {
+ if (e.isDirty()) {
+ //save content
+ t.content = e.getContent();
+ t.$update(function (res) {
+ vm.ticket = res;
+ vm.figureOutItemsToDisplay();
+ NotifycationService.showSuccessNotify('SUPPORT.TICKET_EDIT_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'SUPPORT.TICKET_EDIT_FAILED');
+ });
+
+ e.$options.hideable = true;
+ e.blur();
+ } else {
+ e.$options.hideable = true;
+ e.blur();
+ }
+ },
+ onChange: function (e) {
+ e.$options.hideable = false;
+ },
+ onShow: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-input').textcomplete([
+ { // emoji strategy
+ match: /\B:([\-+\w]*)$/,
+ search: function (term, callback) {
+ callback($.map(window.emojies, function (emoji) {
+ return emoji.indexOf(term) === 0 ? emoji : null;
+ }));
+ },
+ template: function (value) {
+ return '
' + '' + value + '';
+ },
+ replace: function (value) {
+ return ':' + value + ': ';
+ },
+ index: 1
+ }
+ ]);
+
+ e.setContent(t.content);
+ $('#' + e.$editor.attr('id') + ' .md-input').attr('maxlength', vm.inputLengthConfig.ticketContentLength);
+
+ var inputInfo = angular.element('');
+ inputInfo.addClass('pull-right');
+ inputInfo.addClass('input-length');
+ inputInfo.text(e.getContent().length + '/' + vm.inputLengthConfig.ticketContentLength);
+ $('#' + e.$editor.attr('id') + ' .md-header').append(inputInfo);
+ $('#' + e.$editor.attr('id') + ' .md-input').on('input propertychange', function (evt) {
+ inputInfo.text(e.getContent().length + '/' + vm.inputLengthConfig.ticketContentLength);
+ });
+
+ var ele = $('#' + e.$editor.attr('id') + ' .md-footer');
+ angular.element(ele).addClass('text-right');
+ angular.element(ele[0].childNodes[0]).addClass('btn-width-80');
+ ele[0].childNodes[0].innerText = $translate.instant('FORUMS.BTN_SAVE');
+
+ var cbtn = angular.element('');
+ cbtn.bind('click', function (evt) {
+ e.setContent(t.content);
+ e.$options.hideable = true;
+ e.blur();
+ });
+
+ ele.append(cbtn);
+ $compile(e.$editor.contents())($scope);
+ },
+ onPreview: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-footer').css('display', 'none');
+ },
+ onPreviewEnd: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-footer').css('display', 'block');
+ }
+ });
+ };
+
+ /**
+ * beginEditReply
+ * @param r
+ */
+ vm.beginEditReply = function (r) {
+ var el = $('#' + r._id);
+
+ el.markdown({
+ autofocus: true,
+ savable: true,
+ hideable: true,
+ iconlibrary: 'fa',
+ resize: 'vertical',
+ language: localStorageService.get('storage_user_lang'),
+ fullscreen: {enable: false},
+ onSave: function (e) {
+ if (e.isDirty()) {
+ //save content
+ var rep = new MessageTicketsService({
+ _id: vm.ticket._id,
+ _rid: r._id,
+ content: e.getContent()
+ });
+
+ rep.$update(function (res) {
+ vm.ticket = res;
+ vm.figureOutItemsToDisplay();
+ NotifycationService.showSuccessNotify('FORUMS.REPLY_EDIT_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'FORUMS.REPLY_EDIT_FAILED');
+ });
+
+ e.$options.hideable = true;
+ e.blur();
+ } else {
+ e.$options.hideable = true;
+ e.blur();
+ }
+ },
+ onChange: function (e) {
+ e.$options.hideable = false;
+ },
+ onShow: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-input').textcomplete([
+ { // emoji strategy
+ match: /\B:([\-+\w]*)$/,
+ search: function (term, callback) {
+ callback($.map(window.emojies, function (emoji) {
+ return emoji.indexOf(term) === 0 ? emoji : null;
+ }));
+ },
+ template: function (value) {
+ return '
' + '' + value + '';
+ },
+ replace: function (value) {
+ return ':' + value + ': ';
+ },
+ index: 1
+ }
+ ]);
+
+ e.setContent(r.content);
+ $('#' + e.$editor.attr('id') + ' .md-input').attr('maxlength', vm.inputLengthConfig.ticketContentLength);
+
+ var inputInfo = angular.element('');
+ inputInfo.addClass('pull-right');
+ inputInfo.addClass('input-length');
+ inputInfo.text(e.getContent().length + '/' + vm.inputLengthConfig.ticketContentLength);
+ $('#' + e.$editor.attr('id') + ' .md-header').append(inputInfo);
+ $('#' + e.$editor.attr('id') + ' .md-input').on('input propertychange', function (evt) {
+ inputInfo.text(e.getContent().length + '/' + vm.inputLengthConfig.ticketContentLength);
+ });
+
+ var ele = $('#' + e.$editor.attr('id') + ' .md-footer');
+ angular.element(ele).addClass('text-right');
+ angular.element(ele[0].childNodes[0]).addClass('btn-width-80');
+ ele[0].childNodes[0].innerText = $translate.instant('FORUMS.BTN_SAVE');
+
+ var cbtn = angular.element('');
+ cbtn.bind('click', function (evt) {
+ e.setContent(r.content);
+ e.$options.hideable = true;
+ e.blur();
+ });
+
+ ele.append(cbtn);
+ $compile(e.$editor.contents())($scope);
+ },
+ onPreview: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-footer').css('display', 'none');
+ },
+ onPreviewEnd: function (e) {
+ $('#' + e.$editor.attr('id') + ' .md-footer').css('display', 'block');
+ }
+ });
+ };
+
+
+ }
+}());
diff --git a/modules/tickets/client/less/tickets.less b/modules/tickets/client/less/tickets.less
index e1e05dfb..d01924f3 100644
--- a/modules/tickets/client/less/tickets.less
+++ b/modules/tickets/client/less/tickets.less
@@ -18,4 +18,46 @@
max-width: 450px !important;
min-width: 300px !important;
}
+}
+
+.ticket-reply-list {
+ .reply-item {
+ .reply-wrapper {
+ &:not(:first-child) {
+ margin-left: 60px;
+ }
+ margin: 20px 0 0 0;
+ .reply-comment {
+ margin-left: 0;
+ }
+ .reply-avatar {
+ img {
+ cursor: pointer;
+ float: left;
+ margin-left: -60px;
+ border-radius: 3px;
+ height: 44px;
+ width: 44px;
+ }
+ }
+ .reply-comment-header-command {
+ margin-right: 0 !important;
+ }
+ }
+ }
+ .reply-post-title {
+ margin: 30px 0 5px 0;
+ padding: 13px;
+ background-color: @brand-primary;
+ color: #fcfcfc;
+ font-weight: 500;
+ border-top-right-radius: 5px;
+ border-top-left-radius: 5px;
+ }
+ .editable-line {
+ min-height: 30px;
+ }
+ .pagination {
+ margin: 20px 0 0 120px;
+ }
}
\ No newline at end of file
diff --git a/modules/tickets/client/services/tickets.client.service.js b/modules/tickets/client/services/tickets.client.service.js
index a336f3cb..a683d8e5 100644
--- a/modules/tickets/client/services/tickets.client.service.js
+++ b/modules/tickets/client/services/tickets.client.service.js
@@ -8,8 +8,9 @@
MessageTicketsService.$inject = ['$resource'];
function MessageTicketsService($resource) {
- return $resource('/api/messageTickets/:messageTicketId', {
- requestId: '@_id'
+ return $resource('/api/messageTickets/:messageTicketId/:replyId', {
+ messageTicketId: '@_id',
+ replyId: '@_rid'
}, {
update: {
method: 'PUT'
@@ -25,7 +26,7 @@
function MailTicketsService($resource) {
return $resource('/api/mailTickets/:mailTicketId', {
- requestId: '@_id'
+ mailTicketId: '@_id'
}, {
update: {
method: 'PUT'
diff --git a/modules/tickets/client/views/support-message.client.view.html b/modules/tickets/client/views/support-message.client.view.html
index 3443509f..9fac3a01 100644
--- a/modules/tickets/client/views/support-message.client.view.html
+++ b/modules/tickets/client/views/support-message.client.view.html
@@ -41,10 +41,10 @@