-
-
Save cmatheson/3184070 to your computer and use it in GitHub Desktop.
Instructure Zendesk Agent-only mods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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