Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ohaal/4362a4dfa10dcb86a4da to your computer and use it in GitHub Desktop.
Save ohaal/4362a4dfa10dcb86a4da to your computer and use it in GitHub Desktop.
A javascript hack for JIRA that allows resizing of RapidBoard columns and toggling their display on/off - just add to your Announcement Banner
/////////////////////
//
// DO NOT DELETE ME!
// Please take care when editing the announcement banner - it contains custom Javascript/CSS to improve Jira's UI.
//
/////////////////////
/////////////////////
// Inspired by
// https://jira.atlassian.com/browse/GHS-3690?focusedCommentId=693585&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-693585
/////////////////////
/////////////////////
// Helper Function to Add CSS to <head>
// Source: http://stackoverflow.com/questions/3922139/add-css-to-head-with-javascript
/////////////////////
function addCSS(id, css) {
var head = document.getElementsByTagName('head')[0];
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.setAttribute('id', id);
if (s.styleSheet) { // IE
s.styleSheet.cssText = css;
} else { // the world
s.appendChild(document.createTextNode(css));
}
head.appendChild(s);
}
/////////////////////
// Helper Function to remove CSS from <head>
// Source: http://stackoverflow.com/questions/3387427/remove-element-by-id
/////////////////////
function removeElement(id){
var trash = document.getElementById(id);
trash.parentNode.removeChild(trash);
}
/////////////////////
// Function to collapse columns
/////////////////////
function toggleColumn(col, column_short) {
var child_index = col + 1;
var css = '.ghx-zone-overlay-column:nth-child(' + child_index + '), .ghx-column:nth-child(' + child_index + ') { display: none; }'
+ '.column-toggle:nth-child(' + child_index + ') {background: #656060 none repeat scroll 0% 0%; color: silver; }';
if(document.getElementById('hidden-column-' + column_short)) {
removeElement('hidden-column-' + column_short);
localStorage.removeItem('hide-column-' + column_short);
} else {
addCSS('hidden-column-' + column_short, css);
localStorage.setItem('hide-column-' + column_short, 'TRUE');
}
}
/////////////////////
// Function to enable/disable automatic column width sizing - Work in Progress
/////////////////////
function toggleBreakWidth() {
var col_width = 350;
if (localStorage.getItem('col_width')) {
col_width = localStorage.getItem('col_width');
}
if(document.getElementById('col-width')) {
removeElement('col-width');
removeElement('width-button')
removeElement('colWidth');
removeElement('colRange');
localStorage.removeItem('break_width');
} else {
colAlter(col_width);
addCSS('width-button', '.width-button, .width-button:hover {background: #656060 none repeat scroll 0% 0%; color: silver; }')
localStorage.setItem('break_width', 'TRUE');
workspace = document.querySelector("#collapse-controls");
workspace.insertAdjacentHTML('beforeend', '<input type="range" id="colWidth" min="200" max="800" step="10" value="' + col_width + '" oninput="showValue(this.value); colAlter(this.value);" onchange="showValue(this.value); colAlter(this.value);"/>');
workspace.insertAdjacentHTML('beforeend', '<span id="colRange">' + col_width + 'px </span>');
}
}
/////////////////////
// Helper function for toggleBreakWidth() to update the CSS for the column width
/////////////////////
function colAlter(col_width){
localStorage.setItem('col_width', col_width);
if (document.getElementById('col-width')) {
removeElement('col-width');
}
addCSS('col-width', '.ghx-column, .ghx-column-headers, .ghx-zone-overlay-column { width:' + col_width + 'px !important;}');
}
//////////////
// Create Buttons for Every Column on The Board
// Source: http://stackoverflow.com/questions/16949443/get-contents-of-h1-convert-them-it-to-text-and-set-as-a-title-of-the-page
//////////////
function createButtons() {
var text = "textContent" in document.body ? "textContent" : "innerText";
var workspace = document.querySelector('.ghx-controls-work');
var columnNames = document.querySelectorAll('.ghx-column-headers h2');
//var col_width = 350;
cssAlter();
workspace.insertAdjacentHTML('beforeend', '<br>' + '<div id="collapse-controls">');
workspace = document.querySelector("#collapse-controls");
//Create buttons for each column - also look for local storage and set state if local storage exists.
for (var i = 0; i < columnNames.length; i++) {
var column_name = columnNames[i][text];
var column_short = column_name.replace(/[^A-Z0-9]+/ig, "_");
if (localStorage.getItem('hide-column-' + column_short)) {
toggleColumn(i, column_short);
}
workspace.insertAdjacentHTML('beforeend', '<input type="button" class="aui-button column-toggle" value="' + column_name + '" onclick="toggleColumn(' + i + ', \'' + column_short + '\' ); " />');
}
workspace.insertAdjacentHTML('beforeend', ' | ');
workspace.insertAdjacentHTML('beforeend', '<input type="button" class="aui-button width-button" value="Break Width" onclick="toggleBreakWidth();" />');
if (localStorage.getItem('break_width')) {
col_width = localStorage.getItem('col_width');
toggleBreakWidth(col_width);
}
}
/////////////////////
// Show Value of the Range Slider
// Source: http://webtutsdepot.com/2010/04/24/html-5-slider-input-tutorial/
/////////////////////
function showValue(newValue)
{
document.getElementById("colRange").innerHTML = newValue + 'px';
}
/////////////////////
// Trigger Button Creation after the Page Has Loaded
/////////////////////
// Create Buttons on Load - not working :( :( :(
// window.onLoad(createButtons());
// https://gist.github.com/blainesch/7532458
function waitCreateButtons(milliseconds) {
window.setTimeout(createButtons,milliseconds);
window.setTimeout(addDodFunctionality,milliseconds);
}
/////////////////////
// Alter the Page CSS for better display of the cards
// Script source: https://jira.atlassian.com/browse/GHS-5200
/////////////////////
function cssAlter(){
addCSS('css-alters', '.aui-button { font-size: small; } '
+ '.ghx-issue .ghx-avatar { top: 5px !important;}'
+ '.ghx-avatar-img { height:25px; line-height:25px; width:25px; }'
//+ '.ghx-type { display: none; }'
//+ '.ghx-type { left:6px !important; top:5px !important; }'
+ '.ghx-flags { display: none; }'
//+ '.ghx-flags { left:6px !important; }'
//+ '.ghx-flagged { background: #FFB2B2 none repeat scroll 0% 0%; }'
+ '.ghx-issue .ghx-issue-content { min-height:20px; }'
//+ '.ghx-issue .ghx-issue-content { padding:5px 5px 5px 25px; }'
+ '.ghx-issue-fields .ghx-summary .ghx-inner { display: block; font-size: 1.3em; line-height: 1.1; max-height: 6.5em; overflow: hidden; overflow-x: hidden; overflow-y: hidden; word-wrap: break-word; }'
//+ '.ghx-issue-fields { padding-right: 0; }'
+ '.ghx-issue .ghx-extra-fields .ghx-fa { display: none; }'
+ '.ghx-issue.ghx-has-avatar .ghx-issue-fields { padding-right: 0; }'
//+ '.ghx-issue { float:left; width:49%; font-size: .8em; }' // columns two cards wide
//+ '.ghx-key { font-size: 1em; }'
//+ '.ghx-key { display: none !important; }'
//+ ('.ghx-parent-group { float:left; width:100%; font-size: .8em;}' // columns two cards wide
+ '#ghx-operations { padding: 0px 0px 10px 10px; } '
+ '#ghx-board-name { display: none; } '
+ '#ghx-header { padding: 3px 20px; } '
+ '#ghx-modes-tools { position:relative; z-index: 1; } '
+ '#ghx-pool { padding-top: 10px !important;}'
+ '#ghx-column-header-group {position: initial !important;}' // Would like to fix the y but not x, can't do that without Jquery right now.
+ '#colRange {font-size: small;}'
+ '#js-swimlane-header-stalker {display: none !important;}');
}
/////////////////////
// Recreate the Buttons if a User Clicks on an Agile Board work link from another tab
//
// This is not yet working.
//
/////////////////////
//function workLink() {
// document.querySelectorAll('[data-link-id=com.pyxis.greenhopper.jira:project-sidebar-work-scrum]')[0].addEventListener("click", waitCreateButtons);
//}
// Specify with (rapidView=16|rapidView=7|etc)
if(window.location.href.match("(rapidView)")) {
waitCreateButtons(3000);
}
// Additional functionality for definition of done
function addDodFunctionality() {
var beforeNextColumn = {
'BACKLOG': [ // TRAD
'Technical: Uncertainties removed + investigation done',
'User Story: Requirements documented + link to user story in issue',
'User Story: Estimated by team',
'JIRA Change: Divided into smaller sub-tasks'
],
'FOR SPIKING': [ // OP
'Technical: Uncertainties removed + investigation done',
'User Story: Requirements documented + link to user story in issue'
],
'FOR GROOMING': [ // OP
'User Story: Estimated by team',
'JIRA Change: Divided into smaller sub-tasks'
],
'READY FOR DEV': [ // TRAD + OP
'JIRA Change: Approved by Product Owner (Exception: ERR/MAINT)',
'ServiceNow: CHG sent for approval'
],
'DEVELOPMENT': [ // TRAD + OP
'Code: Implemented + Developers test complete',
'Code: Reviewed + Review comments followed up',
'TestRail: Test run with relevant test cases created'
],
'IN SYSTEMTEST': [ // OP
'TestRail: Review Test Design',
'TestRail: Associated test scripts passed'
],
'SYSTEMTEST': [ // TRAD
'TestRail: Review Test Design',
'TestRail: Associated test scripts passed'
],
'SYSTEMTEST DONE': [ // TRAD + OP
'Systemtest done'
],
'PLANNED FOR UAT': [ // OP
'Get UAT commitment and risk assessment'
],
'READY FOR UAT': [ // TRAD
'Get UAT commitment and risk assessment'
],
'IN UAT': [ // TRAD + OP
'Test: Basic regression test on UAT build',
'Make sure issues reported by users are followed up',
'JIRA: Attach written confirmation from users that change is "good to go"',
'ServiceNow: Send for Deployment Approval',
'TestRail: Update Test Plan status'
],
'READY FOR DEPLOYMENT': [ // TRAD + OP
'Fast Track Wiki: Release note added to release',
'Task manager: Changes assigned release after release meeting'
],
'DONE': [ // TRAD + OP
'Test: Brief testing to see if everything is up and running',
'ServiceNow: All released changes in "review" status'
]
};
$('head').append('<style>li.ghx-column > h2 { cursor: pointer; }</style>');
$('li.ghx-column > h2').each((index, el) => {
var name = $(el).text();
var id = $(el).parent().data('id');
var title = "Definition of Done: " + name;
var bulletpoints = '';
if (beforeNextColumn[name.toUpperCase()]) {
bulletpoints = '<li>'+beforeNextColumn[name.toUpperCase()].join('</li><li>')+'</li>';
}
AJS.InlineDialog(
$(el),
'lane'+id,
function(content, trigger, showPopup) {
content
.css({ padding: '20px', width: '400px'})
.html(
'<h2>'+title+'</h2>' +
bulletpoints
);
showPopup();
return false;
}
);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment