diff --git a/src/controllers/api/v1/tickets.js b/src/controllers/api/v1/tickets.js
index 7d21c298d..390e4cd99 100644
--- a/src/controllers/api/v1/tickets.js
+++ b/src/controllers/api/v1/tickets.js
@@ -841,11 +841,17 @@ api_tickets.createType = function(req, res) {
if (_.isUndefined(typeName) || typeName.length < 3) return res.status(400).json({success: false, error: 'Invalid Type Name!'});
var ticketTypeSchema = require('../../../models/tickettype');
- ticketTypeSchema.create({name: typeName}, function(err, ticketType) {
+ var ticketPrioritiesSchema = require('../../../models/ticketpriority');
+ ticketPrioritiesSchema.find({default: true}, function(err, priorities) {
if (err) return res.status(400).json({success: false, error: err.message});
+ priorities = _.sortBy(priorities, 'migrationNum');
+
+ ticketTypeSchema.create({name: typeName, priorities: priorities}, function(err, ticketType) {
+ if (err) return res.status(400).json({success: false, error: err.message});
- return res.json({success: true, tickettype: ticketType});
- })
+ return res.json({success: true, tickettype: ticketType});
+ })
+ });
};
/**
@@ -883,6 +889,58 @@ api_tickets.updateType = function(req, res) {
});
};
+api_tickets.typeAddPriority = function(req, res) {
+ var id = req.params.id;
+ var data = req.body;
+ if (!id || !data || !data.priority)
+ return res.status(400).json({success: false, error: 'Invalid request data'});
+
+ var ticketTypeSchema = require('../../../models/tickettype');
+ ticketTypeSchema.getType(id, function(err, type) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ type.addPriority(data.priority, function(err, type) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ type.save(function(err, t) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ t.populate('priorities', function(err, tt) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ return res.json({success: true, type: tt});
+ });
+ });
+ });
+ });
+};
+
+api_tickets.typeRemovePriority = function(req, res) {
+ var id = req.params.id;
+ var data = req.body;
+ if (!id || !data || !data.priority)
+ return res.status(400).json({success: false, error: 'Invalid request data'});
+
+ var ticketTypeSchema = require('../../../models/tickettype');
+ ticketTypeSchema.getType(id, function(err, type) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ type.removePriority(data.priority, function(err, type) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ type.save(function(err, t) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ t.populate('priorities', function(err, tt) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ return res.json({success: true, type: tt});
+ });
+ });
+ });
+ });
+};
+
/**
* @api {delete} /api/v1/tickets/types/:id Delete Ticket Type
* @apiName deleteType
@@ -940,6 +998,95 @@ api_tickets.deleteType = function(req, res) {
});
};
+api_tickets.createPriority = function(req, res) {
+ var data = req.body;
+ var pName = data.name;
+ var pOverdueIn = data.overdueIn;
+ var pHtmlColor = data.htmlColor;
+
+ if (!pName)
+ return res.status(400).json({success: false, error: 'Invalid Request Data.'});
+
+ var ticketPrioritySchema = require('../../../models/ticketpriority');
+ var P = new ticketPrioritySchema({
+ name: pName,
+ overdueIn: pOverdueIn,
+ htmlColor: pHtmlColor
+ });
+
+ P.save(function(err, savedPriority) {
+ if (err)
+ return res.status(400).json({success: false, error: err.message});
+
+ return res.json({success: true, priority: savedPriority});
+ });
+};
+
+api_tickets.getPriorities = function(req, res) {
+ var ticketPrioritySchema = require('../../../models/ticketpriority');
+ ticketPrioritySchema.find({}, function(err, priorities) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ priorities = _.sortBy(priorities, ['migrationNum', 'name']);
+
+ return res.json({success: true, priorities: priorities});
+ });
+};
+
+api_tickets.updatePriority = function(req, res) {
+ var id = req.params.id;
+ var data = req.body;
+ if (_.isUndefined(id) || _.isNull(id) || _.isNull(data) || _.isUndefined(data))
+ return res.status(400).json({success: false, error: 'Invalid Request Data'});
+
+ var ticketPrioritySchema = require('../../../models/ticketpriority');
+ ticketPrioritySchema.findOne({_id: id}, function(err, priority) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ if (data.name)
+ priority.name = data.name;
+ if (data.htmlColor)
+ priority.htmlColor = data.htmlColor;
+ if (data.overdueIn)
+ priority.overdueIn = data.overdueIn;
+
+ priority.save(function(err, p) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ return res.json({success: true, priority: p});
+ });
+ });
+};
+
+api_tickets.deletePriority = function(req, res) {
+ var id = req.params.id;
+ var newPriority = req.body.newPriority;
+ if (!id || !newPriority)
+ return res.status(400).json({success: false, error: 'Invalid Request Data'});
+
+ async.series([
+ function(next) {
+ var ticketSchema = require('../../../models/ticket');
+ ticketSchema.updateMany({priority: id}, {priority: newPriority}, next);
+ },
+ function(next) {
+ var ticketPrioritySchema = require('../../../models/ticketpriority');
+ ticketPrioritySchema.findOne({_id: id}, function(err, priority) {
+ if (err) return next(err);
+
+ if (priority.default)
+ return next('Unable to delete default priority: ' + priority.name);
+
+ priority.remove(next);
+ });
+ }
+ ], function(err) {
+ if (err) return res.status(400).json({success: false, error: err.message});
+
+ return res.json({success: true});
+ });
+};
+
/**
* @api {get} /api/v1/tickets/stats Get Ticket Stats
* @apiName getTicketStats
diff --git a/src/controllers/settings.js b/src/controllers/settings.js
index a04e26a77..bf4b85dff 100644
--- a/src/controllers/settings.js
+++ b/src/controllers/settings.js
@@ -40,7 +40,7 @@ settingsController.general = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -59,7 +59,7 @@ settingsController.ticketSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -78,7 +78,7 @@ settingsController.mailerSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -97,7 +97,7 @@ settingsController.notificationsSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -116,7 +116,7 @@ settingsController.tpsSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -135,7 +135,7 @@ settingsController.legal = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);
- return res.render('subviews/settings/settings-tickets', content);
+ return res.render('settings', content);
});
};
@@ -208,36 +208,22 @@ function getSettings(content, callback) {
if (err) return callback(err);
content.data.ticketTypes = _.sortBy(types, function(o){ return o.name; });
+ _.each(content.data.ticketTypes, function(type) {
+ type.priorities = _.sortBy(type.priorities, ['migrationNum', 'name']);
+ });
+
+ var ticketPrioritySchema = require('../models/ticketpriority');
+ ticketPrioritySchema.getPriorities(function(err, priorities) {
+ if (err) return callback(err);
+
+ content.data.priorities = _.sortBy(priorities, ['migrationNum', 'name']);
- return callback();
+ return callback();
+ });
});
});
}
-// settingsController.legal = function(req, res) {
-// var content = {};
-// content.title = "Legal Settings";
-// content.nav = 'settings';
-// content.subnav = 'settings-legal';
-//
-// content.data = {};
-// content.data.user = req.user;
-// content.data.common = req.viewdata;
-//
-// settingSchema.getSettings(function(err, settings) {
-// if (err) return handleError(res, 'Invalid Settings');
-//
-// var s = {};
-// s.privacyPolicy = _.find(settings, function(x){return x.name === 'legal:privacypolicy'});
-// s.privacyPolicy = (s.privacyPolicy === undefined) ? {value: ''} : s.privacyPolicy;
-// s.privacyPolicy.value = jsStringEscape(s.privacyPolicy.value);
-//
-// content.data.settings = s;
-//
-// return res.render('subviews/settings/legal', content);
-// });
-// };
-
settingsController.logs = function(req, res) {
if (!checkPerms(req, 'settings:logs')) return res.redirect('/settings');
diff --git a/src/helpers/viewdata/index.js b/src/helpers/viewdata/index.js
index 591861a2e..1e3add413 100644
--- a/src/helpers/viewdata/index.js
+++ b/src/helpers/viewdata/index.js
@@ -106,6 +106,15 @@ viewController.getData = function(request, cb) {
return callback();
});
},
+ function(callback) {
+ viewController.getPriorities(request, function(err, data) {
+ if (err) return callback();
+
+ viewdata.priorities = data;
+
+ return callback();
+ });
+ },
function(callback) {
viewController.getTags(request, function(err, data) {
if (err) return callback();
@@ -329,6 +338,20 @@ viewController.getDefaultTicketType = function(request, callback) {
});
};
+viewController.getPriorities = function(request, callback) {
+ var ticketPrioritySchema = require('../../models/ticketpriority');
+ ticketPrioritySchema.getPriorities(function(err, priorities) {
+ if (err) {
+ winston.debug('Error viewController:getPriorities: ' + err);
+ return callback(err);
+ }
+
+ priorities = _.sortBy(priorities, ['migrationNum', 'name']);
+
+ return callback(null, priorities);
+ });
+};
+
viewController.getTags = function(request, callback) {
var tagSchema = require('../../models/tag');
diff --git a/src/models/ticket.js b/src/models/ticket.js
index 091c7ad7b..69d9a2594 100644
--- a/src/models/ticket.js
+++ b/src/models/ticket.js
@@ -75,7 +75,7 @@ var ticketSchema = mongoose.Schema({
deleted: { type: Boolean, default: false, required: true, index: true },
type: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'tickettypes' },
status: { type: Number, default: 0, required: true, index: true },
- // priority: { type: Number, required: true },
+
priority: { type: mongoose.Schema.Types.ObjectId, ref: 'priorities', required: true },
tags: [{ type: mongoose.Schema.Types.ObjectId, ref: 'tags' }],
subject: { type: String, required: true },
diff --git a/src/models/ticketpriority.js b/src/models/ticketpriority.js
index 252a1fc46..aa1a299d0 100644
--- a/src/models/ticketpriority.js
+++ b/src/models/ticketpriority.js
@@ -12,18 +12,29 @@
**/
-var mongoose = require('mongoose');
-var _ = require('lodash');
+var _ = require('lodash');
+var mongoose = require('mongoose');
+var moment = require('moment');
+var durationFormat = require('moment-duration-format');
var COLLECTION = 'priorities';
var prioritySchema = mongoose.Schema({
name: { type: String, required: true, unique: true },
- overdueIn: { type: Number, required: true, default: 2880}, // Minutes until overdue (48 Hours)
- htmlColor: { type: String, default: '#29b955'},
+ overdueIn: { type: Number, required: true, default: 2880 }, // Minutes until overdue (48 Hours)
+ htmlColor: { type: String, default: '#29b955' },
migrationNum: { type: Number, index: true }, //Needed to convert <1.0 priorities to new format.
default: { type: Boolean }
+}, {
+ toJSON: {
+ virtuals: true
+ }
+});
+
+prioritySchema.virtual('durationFormatted').get(function() {
+ var priority = this;
+ return moment.duration(priority.overdueIn, 'minutes').format('Y [year], M [month], d [day], h [hour], m [min]', {trim: 'both'});
});
prioritySchema.statics.getPriority = function(_id, callback) {
diff --git a/src/models/tickettype.js b/src/models/tickettype.js
index 684a60f35..9006e2be6 100644
--- a/src/models/tickettype.js
+++ b/src/models/tickettype.js
@@ -12,6 +12,7 @@
**/
+var _ = require('lodash');
var mongoose = require('mongoose');
var COLLECTION = 'tickettypes';
@@ -88,4 +89,29 @@ ticketTypeSchema.statics.getTypeByName = function(name, callback) {
return q.exec(callback);
};
+ticketTypeSchema.methods.addPriority = function(priorityId, callback) {
+ if (!priorityId) return callback({message: 'Invalid Priority Id'});
+
+ var self = this;
+
+ if (!_.isArray(self.priorities))
+ self.priorities = [];
+
+ self.priorities.push(priorityId);
+
+ return callback(null, self);
+};
+
+ticketTypeSchema.methods.removePriority = function(priorityId, callback) {
+ if (!priorityId) return callback({message: 'Invalid Priority Id'});
+
+ var self = this;
+
+ self.priorities = _.reject(self.priorities, function(p) {
+ return p._id.toString() === priorityId.toString();
+ });
+
+ return callback(null, self);
+};
+
module.exports = mongoose.model(COLLECTION, ticketTypeSchema);
\ No newline at end of file
diff --git a/src/public/js/angularjs/controllers/settings.js b/src/public/js/angularjs/controllers/settings.js
index 5877ac769..82384f6b7 100644
--- a/src/public/js/angularjs/controllers/settings.js
+++ b/src/public/js/angularjs/controllers/settings.js
@@ -95,6 +95,8 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
}
];
+ var privacyPolicyMDE = null;
+
$scope.init = function() {
//Fix Inputs if input is preloaded with a value
$timeout(function() {
@@ -110,7 +112,7 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
var $privacyPolicy = $('#privacyPolicy');
if ($privacyPolicy.length > 0) {
- var privacyPolicyMDE = new EasyMDE({
+ privacyPolicyMDE = new EasyMDE({
element: $privacyPolicy[0],
forceSync: true,
minHeight: "220px", //Slighty smaller to adjust the scroll
@@ -176,6 +178,8 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
$(vm).removeClass('active');
});
+ $('.page-wrapper').scrollTop(0);
+
//Show Selected
$target.addClass('active');
if (currentTarget.length > 0) {
@@ -185,6 +189,12 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
if (settings === 'settings-tickets') {
$target.find('ul>li[data-key]').first().addClass('active');
}
+
+ if (settings === 'settings-legal') {
+ if (privacyPolicyMDE) {
+ privacyPolicyMDE.codemirror.refresh();
+ }
+ }
}
}
};
@@ -322,7 +332,24 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
'Content-Type': 'application/json'
}
}).then(function successCallback() {
-
+ if (!$scope.mailerCheckEnabled) {
+ UIkit.modal.confirm(
+ 'Settings will take affect after server restart. Would you like to restart the server now?'
+ , function() {
+ $http.get(
+ '/api/v1/admin/restart'
+ )
+ .success(function() {
+ })
+ .error(function(err) {
+ helpers.hideLoader();
+ $log.log('[trudesk:settings:mailerCheckSubmit] - Error: ' + err.error);
+ $log.error(err);
+ });
+ }, {
+ labels: {'Ok': 'Yes', 'Cancel': 'No'}, confirmButtonClass: 'md-btn-primary'
+ });
+ }
}, function errorCallback(err) {
helpers.UI.showSnackbar(err, true);
});
@@ -615,11 +642,12 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
};
$scope.showDeleteTicketType = function(typeId, hasTickets) {
- event.preventDefault();
if (hasTickets) {
- var delTicketTypeModal = $('#deleteTicketTypeModal');
+ var delTicketTypeModal = $('#deleteTicketTypeModal-' + typeId);
if (delTicketTypeModal.length > 0) {
UIkit.modal(delTicketTypeModal, {bgclose: false}).show();
+ } else {
+ $log.log('Unable to locate modal window: #deleteTicketTypeModal' + typeId);
}
} else {
$scope.submitDeleteTicketType(typeId, undefined);
@@ -630,12 +658,12 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
if (event) event.preventDefault();
if (_.isUndefined(typeId) || typeId.length < 1) {
- helpers.UI.showSnackbar('Unable to get tag ID', true);
+ helpers.UI.showSnackbar('Unable to get type ID', true);
return true;
}
- var typeName = $('input#del_type_name').val();
- var newTypeId = $('form#deleteTicketTypeForm select[name="type"]').val();
+ var typeName = $('input#del_type_name-' + typeId).val();
+ var newTypeId = $('form#deleteTicketTypeForm-' + typeId + ' select[name="ticketType"]').val();
if (!newTypeId || newTypeId.length < 1) {
helpers.UI.showSnackbar('Unable to get new ticket type. Aborting...', true);
@@ -655,7 +683,7 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
if (response.data.success) {
helpers.UI.showSnackbar('Successfully removed ticket type: ' + typeName, false);
- return History.pushState(null, null, '/settings/tickettypes/');
+ return History.pushState(null, null, '/settings/tickets/');
}
}, function errorCallback(response) {
if (!_.isUndefined(response.data.error.custom)) {
@@ -668,6 +696,521 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
});
};
+ $scope.editPriority = function(pId, $event) {
+ $event.preventDefault();
+ var $viewBox = $('#view-p-' + pId);
+ var $editBox = $('#edit-p-' + pId);
+ if ($editBox.length > 0 && $viewBox.length > 0) {
+ $editBox.find('.uk-color-button').css({background: $editBox.find('input[name="p-' + pId + '-htmlColor"]').val()});
+ $viewBox.addClass('hide');
+ $editBox.removeClass('hide');
+ }
+ };
+
+ $scope.cancelEditPriority = function(pId, $event) {
+ if ($event)
+ $event.preventDefault();
+ var $viewBox = $('#view-p-' + pId);
+ var $editBox = $('#edit-p-' + pId);
+ if ($editBox.length > 0 && $viewBox.length > 0) {
+ if ($event)
+ $($event.currentTarget).parents('form').trigger('reset');
+ $viewBox.removeClass('hide');
+ $editBox.addClass('hide');
+ }
+ };
+
+ $scope.editTicketTypePriority = function(typeId, id, $event) {
+ $event.preventDefault();
+ var $viewBox = $('#t-' + typeId + '-view-p-' + id);
+ var $editBox = $('#t-' + typeId + '-edit-p-' + id);
+ if ($editBox.length > 0 && $viewBox.length > 0) {
+ $editBox.find('.uk-color-button').css({background: $editBox.find('input[name="p-' + id + '-htmlColor"]').val()});
+ $viewBox.addClass('hide');
+ $editBox.removeClass('hide');
+ }
+ };
+
+ $scope.cancelEditTicketTypePriority = function(typeId, id, $event) {
+ if ($event)
+ $event.preventDefault();
+ var $viewBox = $('#t-' + typeId + '-view-p-' + id);
+ var $editBox = $('#t-' + typeId + '-edit-p-' + id);
+ if ($editBox.length > 0 && $viewBox.length > 0) {
+ if ($event)
+ $($event.currentTarget).parents('form').trigger('reset');
+ $viewBox.removeClass('hide');
+ $editBox.addClass('hide');
+ }
+ };
+
+ $scope.showAddPriorityToType = function(typeId, $event) {
+ if ($event)
+ $event.preventDefault();
+
+ //Dynamically load priorities....
+ $http.get('/api/v1/tickets/type/' + typeId)
+ .success(function(response) {
+ if (response.success) {
+ var updatedType = response.type;
+ $http.get('/api/v1/tickets/priorities')
+ .success(function(response) {
+ var priorities = response.priorities;
+ var $addPriorityToTypeModal = $('#addPriorityTicketType-' + typeId);
+ var $pLoop = $addPriorityToTypeModal.find('.priority-loop');
+ $pLoop.empty();
+
+ var html = '';
+ _.each(priorities, function(priority) {
+ if (_.some(updatedType.priorities, priority)) {
+ html = '';
+ html += '
\n' +
+ '
\n' +
+ '
' + priority.name + ' \n' +
+ '
SLA Overdue: ' + priority.durationFormatted + '
\n' +
+ '
\n' +
+ '
\n' +
+ ' check \n' +
+ '
\n' +
+ '
';
+
+ $pLoop.append(html);
+ } else {
+ html = '';
+ html += '\n' +
+ '
\n' +
+ '
' + priority.name + ' \n' +
+ '
SLA Overdue: ' + priority.durationFormatted + '
\n' +
+ '
\n' +
+ '
\n' +
+ '
Add \n' +
+ '
check \n' +
+ '
\n' +
+ '
';
+
+ $pLoop.append(html);
+ }
+ });
+
+ var $injector = angular.injector(["ng", "trudesk"]);
+ $injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) {
+ var $scope = $pLoop.scope();
+ $compile($pLoop)($scope || $rootScope);
+ $rootScope.$digest();
+ }]);
+
+ if ($addPriorityToTypeModal.length > 0) {
+ UIkit.modal($addPriorityToTypeModal, {bgclose: false}).show();
+ } else {
+ $log.error('Unable to locate add priority modal.');
+ }
+ })
+ .error(function(error) {
+ $log.error(error);
+ helpers.UI.showSnackbar('Unable to load ticket type. Check Console.');
+ });
+ } else {
+ helpers.UI.showSnackbar('Unable to load ticket type. Check Console.');
+ }
+ })
+ .error(function(error) {
+ $log.error(error);
+ helpers.UI.showSnackbar('Unable to load ticket type. Check Console.');
+ });
+ };
+
+ $scope.priorityAddBtnClicked = function(typeId, pId, $event) {
+ $event.preventDefault();
+ var $addButton = $($event.currentTarget);
+ if ($addButton.length < 1)
+ return false;
+
+ $http.post('/api/v1/tickets/type/' + typeId + '/addpriority', {
+ priority: pId
+ }, {
+ 'Content-Type': 'application/json'
+ }).then(function success(response) {
+ var Type = response.data.type;
+ if (Type) {
+ //Update UI
+ var $typeContainer = $('div[data-ticket-type-id="' + typeId + '"]');
+ if ($typeContainer.length > 0) {
+ var $prioritiesBox = $typeContainer.find('.priority-loop');
+ var html = '';
+ $prioritiesBox.empty();
+ var sortedTypePriorities = _.sortBy(( _.sortBy(Type.priorities, 'name')), 'migrationNum');
+
+ _.each(sortedTypePriorities, function(priority) {
+ html = '';
+ html += '\n' +
+ '
\n' +
+ '
' + priority.name + ' \n' +
+ '
SLA Overdue: ' + priority.durationFormatted + '
\n' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ ' ';
+
+ $prioritiesBox.append(html);
+ });
+
+ //Bootstrap Angular dynamically...
+ var $injector = angular.injector(["ng", "trudesk"]);
+ $injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) {
+ var $scope = $prioritiesBox.scope();
+ $compile($prioritiesBox)($scope || $rootScope);
+ $rootScope.$digest();
+ }]);
+
+ //Fix filled inputs
+ helpers.UI.inputs();
+ helpers.UI.reRenderInputs();
+ }
+ }
+
+
+ //Animation
+ $addButton.velocity({
+ opacity: 0
+ }, {
+ duration: 350,
+ complete: function() {
+ $addButton.addClass('hide');
+ }
+ });
+
+ var $check = $addButton.siblings('i.material-icons');
+ if ($check.length > 0) {
+ $check.velocity({
+ opacity: 1
+ }, {
+ delay: 360,
+ duration: 200,
+ begin: function() {
+ $check.show();
+ }
+ });
+ }
+ }, function errorCallback(err) {
+ $log.error(err);
+ helpers.UI.showSnackbar('Error: ' + err, true);
+ });
+ };
+
+ $scope.removePriorityClicked = function(pId, $event) {
+ if ($event)
+ $event.preventDefault();
+
+ var deletePriorityModal = $('#deletePriorityModal-' + pId);
+ if (deletePriorityModal.length > 0) {
+ deletePriorityModal.find('form').trigger('reset');
+ UIkit.modal(deletePriorityModal, {bgclose: false}).show();
+ } else {
+ $log.error('Unable to locate delete priority modal.');
+ }
+ };
+
+ $scope.submitRemovePriority = function(pId, $event) {
+ if ($event)
+ $event.preventDefault();
+
+ if (pId) {
+ var $form = $($event.currentTarget).parents('form');
+ var selectedPriority = $form.find('select[name="priority"]').val();
+
+ $http.post('/api/v1/tickets/priority/' + pId + '/delete', {
+ newPriority: selectedPriority
+ }, {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+ .then(function() {
+ var $body = $('body');
+ // $body.find('div#view-p-' + pId).remove();
+ // $body.find('div#edit-p-' + pId).remove();
+ $body.find('div[data-pId="' + pId + '"]').remove();
+ var deletePriorityModal = $('#deletePriorityModal-' + pId);
+ if (deletePriorityModal) {
+ UIkit.modal(deletePriorityModal).hide();
+ }
+ }, function(err) {
+ $log.error(err);
+ helpers.UI.showSnackbar(err.data.error, true);
+ })
+ }
+ };
+
+ $scope.submitRemoveTicketTypePriority = function(typeId, priorityId, $event) {
+ if ($event)
+ $event.preventDefault();
+
+ if (typeId && priorityId) {
+ $http.post('/api/v1/tickets/type/' + typeId + '/removepriority', {
+ priority: priorityId
+ }, {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then(function() {
+ helpers.UI.showSnackbar('Removed priority from type', false);
+ var $body = $('body');
+ $body.find('div#t-' + typeId + '-view-p-' + priorityId).remove();
+ $body.find('div#t-' + typeId + '-edit-p-' + priorityId).remove();
+ }, function(err) {
+ $log.error(err);
+ helpers.UI.showSnackbar(err.data.error, true);
+ });
+ }
+ };
+
+ $scope.showCreatePriorityWindow = function($event) {
+ if ($event)
+ $event.preventDefault();
+
+ var createPriorityModal = $('#createPriorityModal');
+ if (createPriorityModal.length > 0) {
+ createPriorityModal.find('form').trigger('reset');
+ helpers.UI.inputs();
+ helpers.UI.reRenderInputs();
+ createPriorityModal.find('form').trigger('reset');
+ createPriorityModal.find('#generateHtmlColor').css({background: '#29B955'});
+ UIkit.modal(createPriorityModal, {bgclose: false}).show();
+ createPriorityModal.find('input[name="p-name"]').focus();
+ } else {
+ $log.error('Unable to locate create priority modal.');
+ }
+ };
+
+ $scope.createPrioritySubmit = function($event) {
+ $event.preventDefault();
+ var $form = $($event.currentTarget);
+ if ($form) {
+ if (!$form.isValid(null, null, false)) {
+ return true;
+ } else {
+ var $priorityName = $form.find('input[name="p-name"]');
+ var $priorityOverdueIn = $form.find('input[name="p-overdueIn"]');
+ var $priorityHtmlColor = $form.find('input[name="p-htmlColor"]');
+ if ($priorityName.length < 1 || $priorityOverdueIn.length < 1 || $priorityHtmlColor.length < 1)
+ return false;
+
+ var name = $priorityName.val();
+ var overdueIn = $priorityOverdueIn.val();
+ var htmlColor = $priorityHtmlColor.val();
+
+ $http.post('/api/v1/tickets/priority/create', {
+ name: name,
+ overdueIn: overdueIn,
+ htmlColor: htmlColor
+ }, {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then(function successCallback(response) {
+ var savedPriority = response.data.priority;
+ if (savedPriority) {
+ var priorityLoop = $('body').find('.all-priorities-loop');
+ if (priorityLoop) {
+ $http.get('/api/v1/tickets/priorities')
+ .success(function(pResponse) {
+ var priorities = pResponse.priorities;
+ var html = '';
+ html += '\n' +
+ '
\n' +
+ '
' + savedPriority.name + ' \n' +
+ '
SLA Overdue: ' + savedPriority.durationFormatted + '
\n' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ ' \n' +
+ '\n';
+
+ priorityLoop.append(html);
+
+ helpers.UI.selectize();
+
+ //Bootstrap Angular dynamically...
+ var $injector = angular.injector(["ng", "trudesk"]);
+ $injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) {
+ var $scope = priorityLoop.scope();
+ $compile(priorityLoop)($scope || $rootScope);
+ $rootScope.$digest();
+ }]);
+
+ helpers.UI.showSnackbar('Priority Created.', false);
+ var createPriorityModal = $('#createPriorityModal');
+ if (createPriorityModal.length > 0) {
+ UIkit.modal(createPriorityModal).hide();
+ }
+ })
+ .error(function(errorResponse) {
+ $log.error(errorResponse);
+ helpers.UI.showSnackbar('Error: ' + errorResponse.data.error, true);
+ });
+ }
+ }
+ }, function errorCallback(errorResponse) {
+ $log.error(errorResponse);
+ helpers.UI.showSnackbar('Error: ' + errorResponse.data.error, true);
+ });
+ }
+ }
+ };
+
+ $scope.submitUpdatePriority = function($event) {
+ $event.preventDefault();
+ var $form = $($event.currentTarget);
+ var priorityId = $form.attr('data-priority-id');
+ var typeId = $form.parents('div[data-ticket-type-id]').attr('data-ticket-type-id');
+ if ($form && priorityId) {
+ var $priorityNameInput = $form.find('input[name="p-' + priorityId + '-name"]');
+ var $priorityHtmlColor = $form.find('input[name="p-' + priorityId + '-htmlColor"]');
+ var $priorityOverdueIn = $form.find('input[name="p-' + priorityId + '-overdueIn"]');
+ var priorityName = $priorityNameInput.val();
+ var htmlColor = $priorityHtmlColor.val();
+ var overdueIn = $priorityOverdueIn.val();
+
+ $http.put('/api/v1/tickets/priority/' + priorityId, {
+ name: priorityName,
+ htmlColor: htmlColor,
+ overdueIn: overdueIn
+ }, {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then(function successCallback(response) {
+ helpers.UI.showSnackbar('Priority updated successfully', false);
+ var $body = $('body');
+ $body.find('.p-' + priorityId + '-name').css({color: htmlColor}).text(priorityName);
+ $body.find('.p-' + priorityId + '-overdueIn').text(response.data.priority.durationFormatted);
+ $body.find('input[name="p-' + priorityId + '-htmlColor"]').val(htmlColor);
+ if (typeId)
+ $scope.cancelEditTicketTypePriority(typeId, priorityId);
+ else
+ $scope.cancelEditPriority(priorityId);
+ }, function errorCallback(err) {
+ helpers.UI.showSnackbar(err, true);
+ });
+ }
+ };
+
+ $scope.generateRandomColor = function(id, $event) {
+ $event.preventDefault();
+ var $currentTarget = $($event.currentTarget);
+ if ($currentTarget.length > 0) {
+ var color = getRandomColor();
+ $currentTarget.css({background: color});
+ $currentTarget.next().find('input').val(color);
+ }
+ };
+
+ function getRandomColor() {
+ var letters = '0123456789ABCDEF';
+ var color = '#';
+ for (var i = 0; i < 6; i++) {
+ color += letters[Math.floor(Math.random() * 16)];
+ }
+ return color;
+ }
+
$scope.editTag = function($event) {
if (_.isNull($event.target) || _.isUndefined($event.target) ||
$event.target.tagName.toLowerCase() === 'label' ||
diff --git a/src/public/js/angularjs/controllers/singleTicket.js b/src/public/js/angularjs/controllers/singleTicket.js
index 952aca7da..e15519092 100644
--- a/src/public/js/angularjs/controllers/singleTicket.js
+++ b/src/public/js/angularjs/controllers/singleTicket.js
@@ -173,7 +173,7 @@ define(['angular', 'underscore', 'jquery', 'uikit', 'modules/socket', 'modules/n
$scope.priorities = _.sortBy($scope.priorities, 'name');
$scope.selected_priority = _.findWhere($scope.priorities, {_id: $scope.ticketPriority});
if (!$scope.selected_priority) {
- alert('Selected Priority does not exit for this ticket type. Please select a new priority');
+ UIkit.modal.alert('Selected Priority does not exit for this ticket type.Please select a new priority ');
}
});
@@ -199,7 +199,7 @@ define(['angular', 'underscore', 'jquery', 'uikit', 'modules/socket', 'modules/n
$scope.priorities = _.sortBy($scope.priorities, 'name');
$scope.selected_priority = _.findWhere($scope.priorities, {_id: $scope.ticketPriority});
if (_.isUndefined($scope.selected_priority)) {
- alert('Selected Priority does not exit for this ticket type. Please select a new priority');
+ UIkit.modal.alert('Selected Priority does not exit for this ticket type.Please select a new priority ');
}
}
};
diff --git a/src/public/js/modules/helpers.js b/src/public/js/modules/helpers.js
index 2cc0ed99c..5869b7dde 100644
--- a/src/public/js/modules/helpers.js
+++ b/src/public/js/modules/helpers.js
@@ -397,6 +397,12 @@ function($, _, moment, UIkit, CountUp, Waves, Selectize, Snackbar, ROLES, Cookie
});
};
+ helpers.UI.reRenderInputs = function() {
+ $('.md-input').each(function() {
+ updateInput($(this));
+ });
+ };
+
function updateInput(object) {
// clear wrapper classes
object.closest('.uk-input-group').removeClass('uk-input-group-danger uk-input-group-success uk-input-group-nocolor');
diff --git a/src/routes/index.js b/src/routes/index.js
index f7981dd86..8a6ea1112 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -135,10 +135,17 @@ function mainRoutes(router, middleware, controllers) {
router.get('/api/v1/tickets/search', middleware.api, controllers.api.tickets.search);
router.post('/api/v1/tickets/create', middleware.api, controllers.api.tickets.create);
router.get('/api/v1/tickets/type/:id', middleware.api, controllers.api.tickets.getType);
+ router.post('/api/v1/tickets/type/:id/removepriority', middleware.api, controllers.api.tickets.typeRemovePriority);
+ router.post('/api/v1/tickets/type/:id/addpriority', middleware.api, controllers.api.tickets.typeAddPriority);
router.get('/api/v1/tickets/types', middleware.api, controllers.api.tickets.getTypes);
router.post('/api/v1/tickets/types/create', middleware.api, controllers.api.tickets.createType);
router.put('/api/v1/tickets/types/:id', middleware.api, controllers.api.tickets.updateType);
router.delete('/api/v1/tickets/types/:id', middleware.api, controllers.api.tickets.deleteType);
+ router.post('/api/v1/tickets/priority/create', middleware.api, controllers.api.tickets.createPriority);
+ router.post('/api/v1/tickets/priority/:id/delete', middleware.api, controllers.api.tickets.deletePriority);
+ router.get('/api/v1/tickets/priorities', middleware.api, controllers.api.tickets.getPriorities);
+ router.put('/api/v1/tickets/priority/:id', middleware.api, controllers.api.tickets.updatePriority);
+
router.post('/api/v1/tickets/addtag', middleware.api, controllers.api.tickets.addTag);
router.get('/api/v1/tickets/overdue', middleware.api, controllers.api.tickets.getOverdue);
router.post('/api/v1/tickets/addcomment', middleware.api, controllers.api.tickets.postComment);
diff --git a/src/sass/partials/common.sass b/src/sass/partials/common.sass
index e41137fb1..7bc2d60dd 100644
--- a/src/sass/partials/common.sass
+++ b/src/sass/partials/common.sass
@@ -37,18 +37,31 @@
.nomargin-top,
.nm-t
margin-top: 0 !important
-.marginright20
+.marginright20,
+.mr-20
margin-right: 20px !important
-.marginright30
+.marginright30,
+.mr-30
margin-right: 30px !important
-.marginleft5
+.marginleft5,
+.ml-5
margin-left: 5px !important
-.marginright5
+.marginright5,
+.mr-5
margin-right: 5px !important
+.mt-5
+ margin-top: 5px !important
+.mt-10
+ margin-top: 10px !important
.mb-10
margin-bottom: 10px !important
.mb-5
margin-bottom: 5px !important
+.mr-10
+ margin-right: 10px !important
+.mr-15
+ margin-right: 15px !important
+
.padding-left-right-15
padding-left: 15px !important
padding-right: 15px !important
diff --git a/src/sass/partials/ui.sass b/src/sass/partials/ui.sass
index 2c31d7db2..8ee2bf4d8 100644
--- a/src/sass/partials/ui.sass
+++ b/src/sass/partials/ui.sass
@@ -380,6 +380,16 @@ label.md-label
color: white
background: lighten($accent_color, 5%)
+.uk-color-button
+ padding: 0
+ float: left
+ display: inline-block
+ i.material-icons
+ font-size: 22px
+ vertical-align: middle
+ padding: 3px 4px
+ margin: 0
+
.uk-tooltip-left:after
display: block !important
left: 100%
diff --git a/src/settings/defaults.js b/src/settings/defaults.js
index 437832530..afe1d879b 100644
--- a/src/settings/defaults.js
+++ b/src/settings/defaults.js
@@ -258,6 +258,7 @@ function addedDefaultPrioritesToTicketTypes(callback) {
.catch(next);
},
function(priorities, next) {
+ priorities = _.sortBy(priorities, 'migrationNum');
var ticketTypeSchema = require('../models/tickettype');
ticketTypeSchema.getTypes(function(err, types) {
if (err) return next(err);
@@ -267,14 +268,18 @@ function addedDefaultPrioritesToTicketTypes(callback) {
if (!type.priorities) {
type.priorities = [];
prioritiesToAdd = _.map(priorities, '_id');
- } else {
- _.each(priorities, function(priority) {
- if (!_.find(type.priorities, {'_id': priority._id})) {
- winston.debug('Adding default priority %s to ticket type %s', priority.name, type.name);
- prioritiesToAdd.push(priority._id);
- }
- });
+ } else if (type.priorities.length < 1) {
+ type.priorities = [];
+ prioritiesToAdd = _.map(priorities, '_id');
}
+ // } else {
+ // _.each(priorities, function(priority) {
+ // if (!_.find(type.priorities, {'_id': priority._id})) {
+ // winston.debug('Adding default priority %s to ticket type %s', priority.name, type.name);
+ // prioritiesToAdd.push(priority._id);
+ // }
+ // });
+ // }
if (prioritiesToAdd.length < 1)
return done();
diff --git a/src/views/partials/addPriorityToTypeWindow.hbs b/src/views/partials/addPriorityToTypeWindow.hbs
new file mode 100644
index 000000000..6047b9d70
--- /dev/null
+++ b/src/views/partials/addPriorityToTypeWindow.hbs
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/src/views/partials/createPriorityWindow.hbs b/src/views/partials/createPriorityWindow.hbs
new file mode 100644
index 000000000..72c5743fe
--- /dev/null
+++ b/src/views/partials/createPriorityWindow.hbs
@@ -0,0 +1,50 @@
+
\ No newline at end of file
diff --git a/src/views/partials/deletePriorityWindow.hbs b/src/views/partials/deletePriorityWindow.hbs
new file mode 100644
index 000000000..a01a335c0
--- /dev/null
+++ b/src/views/partials/deletePriorityWindow.hbs
@@ -0,0 +1,31 @@
+
+
+
+
+
+
Remove Priority
+ Please select the priority you wish to reassign tickets to in order to delete the this priority.
+
+
+
+
+ Priority
+
+ {{#each @root.data.common.priorities}}
+ {{#isnot name ../name}}
+ {{name}}
+ {{/isnot}}
+ {{/each}}
+
+
+
+
+ WARNING: This will change all tickets with a priority of: {{name}} to the selected priority above. This is permanent!
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/partials/deleteTicketTypeWindow.hbs b/src/views/partials/deleteTicketTypeWindow.hbs
index 8c715b35a..8933f9c49 100644
--- a/src/views/partials/deleteTicketTypeWindow.hbs
+++ b/src/views/partials/deleteTicketTypeWindow.hbs
@@ -1,16 +1,18 @@
-
+
-
-
+
+
- There're currently tickets assigned to this Ticket Type. Please select the ticket type you wish to reassign those tickets to in order to delete the ticket type.
+
Remove Ticket Type
+ Please select the ticket type you wish to reassign tickets to in order to delete the ticket type.
+
- Type
-
- {{#each data.common.ticketTypes}}
- {{#isnot name ../data.tickettype.name}}
+ Type
+
+ {{#each @root.data.common.ticketTypes}}
+ {{#isnot name ../name}}
{{name}}
{{/isnot}}
{{/each}}
@@ -18,11 +20,11 @@
- WARNING: This will change all tickets with type: {{data.tickettype.name}} to the selected ticket type above. This is permanent!
+ WARNING: This will change all tickets with type: {{name}} to the selected ticket type above. This is permanent!
diff --git a/src/views/partials/nav.hbs b/src/views/partials/nav.hbs
index 1845c7148..d21079813 100644
--- a/src/views/partials/nav.hbs
+++ b/src/views/partials/nav.hbs
@@ -113,13 +113,10 @@
style Legal
-
style Tags
-
text_fields Ticket Types
{{#canUser data.user "settings:logs"}}
remove_from_queue Logs
{{/canUser}}
-
gavel Legal
{{/canUser}}
diff --git a/src/views/settings.hbs b/src/views/settings.hbs
index 5aec60832..d4ffaddb8 100644
--- a/src/views/settings.hbs
+++ b/src/views/settings.hbs
@@ -1,4 +1,4 @@
-
-
-
-
{{title}}
+
+
-
-
-
-
-
-
-
Default Ticket Type
-
- Default ticket type for newly created tickets.
-
-
-
-
-
- {{#each data.common.ticketTypes}}
- {{name}}
- {{/each}}
-
+
+
+
+
+
+
+
+
+
+
+
Show Tour - Beta
+
+ Tour the user interface on initial login.
+
+
+
-
-
-
-
-
Show Tour - Beta
-
- Tour the user interface on initial login.
-
-
-
-
-
-
- Enable
-
-
-
+
+
+
+
Allow User Registration
+
+ Allow users to create accounts on the login screen.
+
+
+
-
-
-
-
Show Overdue Tickets
-
- Flash tickets that have been idle for a length of time. (Configure Priorities )
-
-
-
-
-
-
- Enable
-
-
-
+
+
+
+
+
+ Default Ticket Type
+
+
+ Default ticket type for newly created tickets.
+
+
+
+
+
+ {{#each data.common.ticketTypes}}
+ {{name}}
+ {{/each}}
+
+
-
-
-
-
-
-
-
-
-
-
-
Allow User Registration
-
- Allow users to create accounts on the login screen.
-
-
-
-
-
-
- Enable
-
-
-
+
+
+
+
Show Overdue Tickets
+ help
+
+
+ Enable/Disable flashing of tickets based on SLA time of type priority.
+
+
+
-
-
-
-
-
Mailer
-
- Preferences for trudesk to send email notifications to users.
-
-
-
-
-
-
- Enable
-
-
-
+
+
+
+
+
Ticket Types
+
+ Create / Modify Ticket Types
+
-
-
-
-
-
-
-
-
- Use SSLv3
-
-
-
-
+
+
+
+
+
-
Mail Server
-
+
+ {{#each data.ticketTypes}}
+
+
+
+
+
Priorities
+ help
+
+
+ Add
+
+
+
+ {{#forEach priorities}}
+
+
+
{{name}}
+
SLA Overdue: {{durationFormat overdueIn 'minutes'}}
+
+
+
+
+
+
+
+
+ Priority Name
+
+
+
+ SLA Overdue (minutes)
+
+
+
+
refresh
+
+ Color
+
+
+
+
+
+
+
+
+ {{/forEach}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Danger Zone
+
+
+
+
Delete this type
+
Once you delete a ticket type, there is no going back. Please be certain.
+
+
+ Delete
+
+
+
+
+
+ {{> addPriorityToTypeWindow}}
+ {{> deleteTicketTypeWindow}}
+ {{/each}}
+
-
- Port
-
-
-
- Auth Username
-
-
-
- Auth Password
-
+
+
+ {{> createTicketTypeWindow}}
+
+
+
+
+
+
+
Ticket Priorities
+
+ Ticket priorities set the level of SLAs for each ticket.
+
+
+
+
+ Create
-
- From Address
-
+
+
+
+
+
+ {{#each data.priorities}}
+
+
+
{{name}}
+
SLA Overdue: {{durationFormat overdueIn 'minutes'}}
+
+
+
+
+
+
+
+
+ Priority Name
+
+
+
+ SLA Overdue (minutes)
+
+
+
+
refresh
+
+ Color
+
+
+
+
+
+
+
+
+
+ {{> deletePriorityWindow}}
+ {{/each}}
+
+
+
-
- Test Settings
- Apply
+ {{> createPriorityWindow}}
+
+
+
+
+
+
Ticket Tags
+
+ Create / Modify Ticket Tags
+
+
+
+
+
+
+
+
-
-
-
-
Mailer Check
-
- Trudesk will periodically check a mailbox for emails to convert to tickets. (Over IMAP) - Settings are applied after server restart
-
-
-
-
-
-
- Enable
-
-
-
+
+
+
+
+
+
Mailer
+
+ Preferences for trudesk to send email notifications to users.
+
-
-
-
-
-
-
Mail Server
-
+
+
+
+
+ Enable
+
+
+
-
- Port
-
+
+
+
+
+
+
+
+
+ Use SSLv3
+
+
+
+
+
+
Mail Server
+
+
+
+
+ Port
+
+
+
+ Auth Username
+
+
+
+ Auth Password
+
+
+
+ From Address
+
+
+
+
+ Test Settings
+ Apply
+
-
- Username
-
+
+
+
+
+
+
+
Mailer Check
+
+ Trudesk will periodically check a mailbox for emails to convert to tickets. (Over IMAP) - Settings are applied after server restart
+
+
+
+
+
+
+ Enable
+
+
+
-
- Password
-
+
+
+
+
+
+ Mail Server
+
+
+
+ Port
+
+
+
+ Username
+
+
+
+ Password
+
+
+
+ Default Ticket Type
+
+ {{#each data.common.ticketTypes}}
+ {{name}}
+ {{/each}}
+
+
+
+ Apply
+
-
- Default Ticket Type
-
- {{#each data.common.ticketTypes}}
- {{name}}
- {{/each}}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TPS
+
+ Trudesk Push Server authentication for push notifications. Get API Key
+
+
+
+
+
+
+ Enable
+
+
+
-
- Apply
+
+
+
+
+
+ Username
+
+
+
+ API Key
+
+
+
+ Apply
+
-
+
-
TPS
+
Privacy Policy
- Trudesk Push Server authentication for push notifications. Get API Key
+ Paste in HTML / Text of your privacy policy.
-
+
-
diff --git a/src/views/subviews/settings/settings-tickets.hbs b/src/views/subviews/settings/settings-tickets.hbs
deleted file mode 100644
index 90bf26d3d..000000000
--- a/src/views/subviews/settings/settings-tickets.hbs
+++ /dev/null
@@ -1,474 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
Show Tour - Beta
-
- Tour the user interface on initial login.
-
-
-
-
-
-
-
-
-
-
Allow User Registration
-
- Allow users to create accounts on the login screen.
-
-
-
-
-
-
-
-
-
-
-
-
- Default Ticket Type
-
-
- Default ticket type for newly created tickets.
-
-
-
-
-
- {{#each data.common.ticketTypes}}
- {{name}}
- {{/each}}
-
-
-
-
-
-
-
-
-
-
-
-
Show Overdue Tickets
-
- Flash tickets that have been idle for a length of time.
-
-
-
-
-
-
-
-
-
-
Ticket Types
-
- Create / Modify Ticket Types
-
-
-
-
-
-
-
-
- {{#each data.ticketTypes}}
-
-
-
-
-
Priorities
- help
-
-
- Add
-
-
-
- {{#forEach priorities}}
-
-
-
{{name}}
-
SLA Overdue: {{durationFormat overdueIn 'minutes'}}
-
-
-
- {{/forEach}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Danger Zone
-
-
-
-
Delete this type
-
Once you delete a ticket type, there is no going back. Please be certain.
-
-
- Delete
-
-
-
-
-
- {{/each}}
-
-
-
-
- {{> createTicketTypeWindow}}
-
-
-
-
-
-
-
-
-
Mailer
-
- Preferences for trudesk to send email notifications to users.
-
-
-
-
-
-
-
-
-
-
- Use SSLv3
-
-
-
-
-
-
Mail Server
-
-
-
-
- Port
-
-
-
- Auth Username
-
-
-
- Auth Password
-
-
-
- From Address
-
-
-
-
- Test Settings
- Apply
-
-
-
-
-
-
-
-
-
Mailer Check
-
- Trudesk will periodically check a mailbox for emails to convert to tickets. (Over IMAP) - Settings are applied after server restart
-
-
-
-
-
-
-
- Mail Server
-
-
-
- Port
-
-
-
- Username
-
-
-
- Password
-
-
-
- Default Ticket Type
-
- {{#each data.common.ticketTypes}}
- {{name}}
- {{/each}}
-
-
-
- Apply
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TPS
-
- Trudesk Push Server authentication for push notifications. Get API Key
-
-
-
-
-
-
-
- Username
-
-
-
- API Key
-
-
-
- Apply
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{{#contentFor 'js-plugins'}}
-
-{{/contentFor}}
\ No newline at end of file
diff --git a/src/views/tickets.hbs b/src/views/tickets.hbs
index f5a294472..79bbd5f31 100644
--- a/src/views/tickets.hbs
+++ b/src/views/tickets.hbs
@@ -116,7 +116,7 @@
{{#each data.tickets}}
{{#if_eq status compare=0}}
-
+
@@ -144,7 +144,7 @@
{{/if_eq}}
{{#is status 1}}
-
+