Messing up with Jira's UI ;)
Updated: Aug 13, 2021
Announcement banner in Jira is a in-built DIV that is embedded to each page of the its UI.
The DIV allows you to stuff HTML/script/css that can used further to add/suppress/highlight new/existing style, content, behavior of rendering component. Below are some examples on what you could do to UI by adding style/scripts:
How to disable user/assignable and mention/search call until user has already keyed in 3/4 letters in comments or user picker:
<script type="text/javascript">
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
if (options.url && options.url.includes('user/assignable')) {
let url = new URLSearchParams('?' + options.data);
if (url.get('username').length < 3) {
jqXHR.abort();
}
}else if(options.url && options.url.includes('mention/search')){
if (getQueryVariable(options.data)!='empty' & getQueryVariable(options.data).length<4) {
jqXHR.abort();
}
}
});
function getQueryVariable(data) {
var query = data
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
console.log("pair == "+pair);
if (decodeURIComponent(pair[0]) == 'query') {
return decodeURIComponent(pair[1]);
}
}
return 'empty';
}
</script>
How to hide passed/specified groups on edit subscription and manage filter page:
<script type="text/javascript">
jQuery(document).ready(removeGrp);
function removeGrpFromEditSubscription () {
if($('#filter-subscription > div.form-body > div.field-group > select > option').length>0){
$('#filter-subscription > div.form-body > div.field-group > select > option').each(function() {
if($(this).text().trim()=="jira-software-users" || $(this).text().trim()=="jira-administrators" || $(this).text().trim()=="jira-servicedesk-users"){
$(this).remove()
}
});
} else {
setTimeout(removeGrpFromEditSubscription, 2000);
}
}
function removeGrp(){
var currentURL = window.location.href;
if(currentURL.indexOf('ManageFilters.jsp')>0){
$( document ).ajaxComplete(function( event, xhr, settings ) {
if ( settings.url.indexOf("EditSubscription!default.jspa") > 0 ) {
$('#filter-subscription > div.form-body > div.field-group > select > option').each(function() {
if($(this).text().trim()=="jira-software-users" || $(this).text().trim()=="jira-administrators" || $(this).text().trim()=="jira-servicedesk-users"){
$(this).remove()
}
});
}
});
} else if(currentURL.indexOf('EditSubscription!default.jspa?filterId')>0){
removeGrpFromEditSubscription();
}
}
</script>
Set the heading of create issue dialog to custom:
<script type="text/javascript">
jQuery(document).ready(checkIssueDetailContainer);
function checkIssueDetailContainer () {
if($('#create-issue-dialog > div.jira-dialog-heading > h2').is(':visible')){
console.log("Setting the heading now!!")
$('#create-issue-dialog > div.jira-dialog-heading > h2')[0].innerHTML="Create Assessment Request"
} else {
setTimeout(checkIssueDetailContainer, 2000);
}
}
</script>
Since color change of text and default blue strip on top allowed by Jira is not automatically adopted by quick search bar styles:
<script type="text/javascript">
function rgb2hex(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
if(rgb2hex($('#header > nav').css('background-color'))=='#ffffff'){
$('#quickSearchInput').css('background-color','#ccc');
}
else{
console.log('current color is '+$('#header > nav').css('background-color'));
}
</script>
How to make sure script is only applicable to particular project:
<script type="text/javascript">
var currentURL = window.location.href;
var projectKey = currentURL.substr(currentURL.indexOf('projects/')+9).substr(0,currentURL.substr(currentURL.indexOf('projects/')+9).indexOf('/'));
if(projectKey =='YOUR_PROJECT_KEY')
console.log('------Do you stuff in this IF block!------');
</script>
How to sort board drop down, if it does not appear to be sorted:
var options = $('select[name="board-type"] > option');
var arr = options.map(function(_, o) { return { t: $(o).text(), v: o.value }; }).get();
arr.sort(function(o1, o2) { return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0; });
options.each(function(i, o) {
o.value = arr[i].v;
$(o).text(arr[i].t);
});
Change badges on scrum board to include story points of each issues on board(including backlog):
if(document.referrer.indexOf('RapidBoard.jspa')>0 && !$('.ghx-badge-group.ghx-right').length!=0)
if($('div.ghx-meta').find('div.ghx-issues.js-issue-list.ghx-has-issues').length!=0)
var issues = $('div.ghx-meta').find('div.ghx-issues.js-issue-list.ghx-has-issues')[0].childNodes;
var sumremainingEstimateSeconds=0, sumtimeSpentSeconds=0;
$.each( issues, function( index, value ){ var issuekey;
if(issues[index].dataset.issueKey!=undefined){
issuekey=issues[index].dataset.issueKey;
console.log( "getting time traking for issue "+ issues[index].dataset.issueKey );
var url = 'http://JIRA_BASE_URL/rest/api/2/issue/'+issuekey+'?fields=timetracking'
$.ajax(url,
{
url: url,
type: "GET",
dataType: 'json',
contentType:'application/json',
async:false,
success: function (data, status, xhr) {
console.log("success");
}
}).always(sum);
}});
function sum(a,b,c){ if(a.fields.timetracking.remainingEstimateSeconds!= undefined){
sumremainingEstimateSeconds = sumremainingEstimateSeconds+parseInt(a.fields.timetracking.remainingEstimateSeconds);
}
if(a.fields.timetracking.timeSpentSeconds!= undefined){
sumtimeSpentSeconds = sumtimeSpentSeconds+parseInt(a.fields.timetracking.timeSpentSeconds);
}
}
if(sumremainingEstimateSeconds!=0){sumremainingEstimateSeconds=sumremainingEstimateSeconds/3600;}
if(sumtimeSpentSeconds!=0){sumtimeSpentSeconds=sumtimeSpentSeconds/3600;}
console.log("consolidated value sumremainingEstimateSeconds: "+sumremainingEstimateSeconds+" sumtimeSpentSeconds: "+ sumtimeSpentSeconds);
var sumremainingEstimateSecondsbadge= "<aui-badge class='ghx-not-started' title='remaining estimate hours'>"+sumremainingEstimateSeconds+"</aui-badge>"
var sumtimeSpentSeconds= "<aui-badge class='ghx-not-started' title='time spent hours'>"+sumtimeSpentSeconds+"</aui-badge>"
$('.ghx-badge-group.ghx-right').prepend(sumtimeSpentSeconds);
$('.ghx-badge-group.ghx-right').prepend(sumremainingEstimateSecondsbadge);