Skip to content

Instantly share code, notes, and snippets.

@cmatheson
Forked from ryankshaw/instructurezendesk.js
Created July 26, 2012 19:40
Show Gist options
  • Save cmatheson/3184070 to your computer and use it in GitHub Desktop.
Save cmatheson/3184070 to your computer and use it in GitHub Desktop.
Instructure Zendesk Agent-only mods
previousjQuery = jQuery;
jQuery(function($){
// only run in browsers that can do localStorage (not IE) and only on the tickets page
if ('localStorage' in window && $('body').hasClass('tickets-show')) {
// I want to make sure that this always runs with my version of jquery, not zendesk's
$.getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js', function(){
jQuery(function($){
function getThisZendeskTicketFromRestApi(callback){
var UrlToThisTicket = window.location.protocol + "//" + window.location.host + window.location.port + window.location.pathname;
$.getJSON(UrlToThisTicket + '.json', callback);
}
function updateZendeskIdsInRedmine() {
function error(){
alert("ERROR: something went wrong updating Zendesk Ids In Redmine, see console");
debugger;
console && console.log('failure', this, arguments);
}
var redmineIssueId = $.trim($redmineIssue.val()),
url = 'https://redmine.instructure.com/issues/' + redmineIssueId + '.json';
if (!redmineIssueId) {
alert('no redmine issue to update');
return;
}
getThisZendeskTicketFromRestApi(function(zenTicket){
console && console.log('updating Zendesk Ids In Redmine', redmineIssueId, zenTicket);
$.ajax({
url: url,
headers: {"X-Requested-With" : "XMLHttpRequest"},
xhrFields: { withCredentials: true },
success: function(res){
var zendeskIds = $.grep(res.issue.custom_fields, function(field){
return field.id == 10;
})[0].value;
zendeskIds = (zendeskIds || '').split(',');
console && console.log('found ZendeskIds', zendeskIds);
var newZendeskIds = $.map(zendeskIds, function(id) {
var trimmed = $.trim(id)
if ( trimmed && trimmed != zenTicket.nice_id) return trimmed;
});
newZendeskIds.push(zenTicket.nice_id);
jQuery.ajax({
type: 'PUT',
url: url,
headers: {"X-Requested-With" : "XMLHttpRequest"},
xhrFields: { withCredentials: true },
data: {
issue: {
custom_field_values: {
"10" : newZendeskIds.join(', ')
},
tags: res.issue.tags
}
},
// this is because redmine will return ' ' which is invald JSON, so dont try to $.parseJSON it
dataType: 'text',
success: function(){
alert("this zendesk ticket was added to redmine #"+ redmineIssueId + " make sure you save this page to have it stick here.");
},
error: error
});
},
error: error
});
});
}
// hide time_open, time_pending, first_response_time, account_id, and 'need more info from support?'
$('#ticket_fields_20485213, #ticket_fields_20485208, #ticket_fields_20510153, #ticket_fields_20485203, #ticket_fields_20687897').each(function(index) {
$(this).closest('.select').hide();
});
var $divToAppendAfter = $('<hr style="clear:both;" />').insertAfter('.selects:last');
$("#ticket_fields_340637, #ticket_fields_339688").each(function(){
$divToAppendAfter.after('<div class="debug-info"><strong>' + $(this).prev('label').text() + ':</strong> ' + $(this).val() + '</div>');
$(this).parents('.select').hide();
});
$("#ticket_fields_340638, #ticket_fields_339456").each(function() {
$divToAppendAfter.after('<div><strong>' + $(this).prev('label').text() + ':</strong> ' +
'<a href="' + $(this).val() + '" target="_blank">' + $(this).val() + '</a>' +
'</div>');
$(this).parents('.select').hide();
});
var $redmineIssue = $('#ticket_fields_349517').css({width: '45px', padding: '1px'});
$redmineIssue.one('change', function(){
$('<button>update on redmine</button>')
.insertAfter($redmineIssue)
.click(function(event){
event.preventDefault();
updateZendeskIdsInRedmine();
});
});
if ($redmineIssue.val()) {
$redmineIssue.prev('label').html("<a href='https://redmine.instructure.com/issues/"+ $redmineIssue.val() +"' rel='iframe' title='Redmine Ticket Preview :: :: fullscreen: true' class='lightview'>Redmine #</a>");
}
var $httpEnv = $("#ticket_fields_339428");
if ($httpEnv.val()) {
$divToAppendAfter.after("<div class='debug-info'><label><strong>HTTP-env</strong></label><div style='border: 1px solid #ccc; max-height: 100px; overflow: auto; white-space: nowrap; margin-bottom: 0.5em'>" + $httpEnv.val().replace(/\n/g, '<br />') + "</div></div>");
}
$httpEnv.closest('.select').hide();
var $stacktrace = $("#ticket_fields_339429"),
newHtml = [],
headerAndLines = $stacktrace.val().split('-----------------------------------------');
$stacktrace.closest('.select').hide();
// if there is some stuff in a stack trace, linkifiy it. otherwise hide it completely.
if (headerAndLines[1]) {
var $stacktraceDiv = $('<div style="border: 1px solid #ccc; max-height: 80px; overflow: auto; white-space: nowrap; margin-bottom: 0.5em;">')
.append($('<h4 />').text(headerAndLines[0]));
$('<div class="debug-info">')
.append('<label><strong>Stacktrace</strong></label>')
.append($stacktraceDiv.append('<pre>'+headerAndLines[1]+'/<pre>'))
.insertAfter($divToAppendAfter);
}
if ($('.debug-info').length) {
var $hideShowDebugInfo = $('<a href="#" style="float:right">Hide Debug Info</a>').click(function(){
if ( $(this).text() == 'Hide Debug Info' ) {
$(this).text('Show Debug Info');
$('.debug-info').hide();
} else {
$(this).text('Hide Debug Info');
$('.debug-info').show();
}
return false;
}).insertAfter($divToAppendAfter);
var hideDebugInfo = window.localStorage.getItem('hideDebugInfo');
if (!hideDebugInfo) {
hideDebugInfo = confirm('hide stack trace and HTTP-env by default (unless you are a programmer, you probably want to say yes)?') ? 'yes' : 'no';
window.localStorage.setItem('hideDebugInfo', hideDebugInfo);
}
if (hideDebugInfo == 'yes') {
$hideShowDebugInfo.click();
}
}
if (!$redmineIssue.val()) {
function sendToRedmine(){
getThisZendeskTicketFromRestApi(function(zenTicket) {
var zendeskPriorities = {
"1": "Low",
"2": "Normal",
"3": "High",
"4": "Urgent"
},
redminePriorities = {
"Low": 3,
"Normal": 4,
"High": 5,
"Urgent": 6,
"Immediate": 7
},
customFieldsMap = {
339652: 'Institution',
339428: 'Http Env',
339429: 'Stack Trace',
340637: 'User ID',
339688: 'Request Context Id',
340638: 'URL',
339456: 'become_user_id_uri'
};
// go through each of the custom ticket fields and,
// if its one we want to keep track of, add it the description
// $.each(zenTicket.ticket_field_entries, function(index, val) {
// if (customFieldsMap[this.ticket_field_id] && this.value) {
// description += '<div><strong>' + customFieldsMap[this.ticket_field_id] + ':</strong> ';
// if (this.value.length > 200) { // if its a big field like Stack Trace
// //redmine's markdown filter chokes on "`"
// description += '<pre>' + this.value.replace(/`/g, "'").replace(/\n- /g, "\n").replace(/_/g, '\\_') + '</pre>';
// } else {
// description += this.value;
// }
// description += '</div>';
// }
// });
// description += "<hr /> <h2>Original Zendesk Comments</h2>" + $("#history").html();
window.redmineIssue = {
project_id: 1, //id of the canvas project
// redmine can't handle setting custom fields yet, probably can, just need to look into it.
custom_field_values: {
'2' : zenTicket.nice_id, //Zendesk ID
'10' : zenTicket.nice_id
},
fixed_version_id: 20
};
var dialogHTML = '' +
'<form style="padding:15px" title="Ticket Options">'+
'<fieldset style="border:1px solid #ccc; padding:10px"><legend>Redmine Issue Options</legend>'+
'<table cellspacing="7">' +
'<tr><td><label for="assign_to_myself">Assign to me:</td><td><input id="assign_to_myself" type="checkbox" /></td></tr>' +
'<tr class="assignee_row"><td><label for="assignee">Assign to:</td><td><select id="assignee">' +
'<option></option>' +
'<option value="66">Chris Calvert</option>' +
'<option value="90">Rachel Wolthius</option>' +
'<option value="130">Mysti Sadler</option>' +
'</select></td></tr>' +
'<tr><td><label for="target_version">Target Version :</td><td><select id="target_version">' +
'<option></option>' +
'<option value="58">Support Week</option>' +
'<option value="20">Bug Review</option>' +
'</select></td></tr>' +
'<tr><td><label for="priority_id">Priority: </label></td><td><select id="priority_id">'+
'<option value="3">Low</option>'+
'<option value="4">Normal</option>'+
'<option value="5">High</option>'+
'<option value="6">Urgent</option>'+
'<option value="7">Immediate</option>'+
'</select></td></tr>'+
'</table>'+
'<div><label for="subject">Subject</label><div>' +
'<input style="width: 98%" id="subject" value="' + zenTicket.subject + '" />' +
'<div><label for="description">Description</label></div>' +
'<textarea id="description" style="height:300px; width: 98%">' +
'User- or Course-specific or Global?\n\n' +
'\n' +
'Summary of issue:\n\n' +
'\n' +
'Course URL tested:\n\n' +
'\n' +
'Steps to Reproduce:\n' +
' - \n\n' +
' - \n\n' +
' - \n\n' +
' - \n\n' +
' - \n\n' +
'\n' +
'Troubleshooting Steps Performed:\n\n' +
'\n' +
'User Expected Behavior:\n\n' +
'\n' +
'Workaround Possible? (Y/N):\n\n' +
'\n' +
'</textarea>' +
'</fieldset>'+
'<button type="submit">Send to Redmine</button>' +
'</form>';
var dialog = previousjQuery(dialogHTML).dialog({ resizable: false,
modal: true,
width: 800
})
dialog.find('#assign_to_myself').change(function() {
if ($(this).is(':checked')) {
$('.assignee_row').hide()
} else {
$('.assignee_row').show()
}
});
dialog.submit(function(event){
event.preventDefault();
previousjQuery(this).dialog('close');
// set stuff for the redmine ticket
if (priorityId = $(this).find('#priority_id').val()) {
window.redmineIssue.priority_id = priorityId;
}
if (assignedToId = $(this).find('#assignee').val()) {
window.redmineIssue.assigned_to_id = assignedToId;
}
window.redmineIssue.fixed_version_id = $(this).find('#target_version').val();
window.redmineIssue.subject = $(this).find('#subject').val();
window.redmineIssue.description = $(this).find('#description').val() + '\n\nImported from <a href="http://help.instructure.com/tickets/'+zenTicket.nice_id+'">zendesk #'+zenTicket.nice_id+'</a>';
$.ajax({
type: 'GET',
url: 'https://redmine.instructure.com/users/current.json',
dataType: 'json',
headers: {"X-Requested-With" : "XMLHttpRequest"},
xhrFields: { withCredentials: true },
success: function(res){
// the submitter wants to watch the issue
window.redmineIssue.watcher_user_ids = [res.user.id];
if ($(this).find('#assign_to_myself').is(':checked')) {
window.redmineIssue.assigned_to_id = res.user.id;
}
sendRedmineIssueAPIRequest();
},
error: function(){
alert("ERROR: Could not determine your Zendesk User ID. Ticket not sent to Redmine (look at the console to see what happened)");
console && console.log('failure', this, arguments);
}
});
}).find('#priority_id').val(redminePriorities[zendeskPriorities[zenTicket.priority_id]]);
function sendRedmineIssueAPIRequest(){
console && console.log(redmineIssue);
// make the post request to the redmine REST api
$.ajax({
type: 'POST',
url: 'https://redmine.instructure.com/issues.json',
data: {issue: redmineIssue},
dataType: 'json',
// contentType: 'text/json',
headers: {"X-Requested-With" : "XMLHttpRequest"},
xhrFields: { withCredentials: true },
success: function(issue){
issue = issue.issue; //stupid rails prefixing of to_json with wrapper object.
console && console.log('success', this,arguments, issue);
$redmineIssue.val(issue.id);
$('#comment_value').val(window.redmineIssue.description);
$('#comment_is_public').attr('checked', false);
// add pending_fix tag to zendesk ticket
$('.search_field_item input').val('pending_fix');
if ( confirm("Issue " + issue.id +" Sent to redmine," + "Would you like me to save this page as is in order to save the Redmine Issue # automatically? if you say no, you can edit things yourself") ) {
// this is the function that zendesk uses to submit the form you cant just submit the form normally.
submitTicketForm();
}
},
error: function(){
alert("ERROR: The Ticket was not sent to Redmine! make sure you are logged in at redmine.instructure.com (look at the console to see what happened)");
console && console.log('failure', this, arguments);
}
});
}
});
}
$('<a style="color: red; float: right" href="#">File as Redmine Issue</a>')
.insertBefore('#_macro_list')
.click(function(){
sendToRedmine();
return false;
});
}
});
jQuery.noConflict(true);
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment