Separate, Sort & Align Scoped Labels to provide "Simple Custom Fields"
Proposal
Until custom fields arrive... We have decided scoped labels will go a long way to fill a gap (in turn allowing us to start using GitLab as our servicedesk/helpdesk/support ticketing system). Here are a few examples;
- Customer
- Category (Reporting/(Web) App/Training/Consulting)
- Type (Our Bug/3rd Party Bug/New Work/Modification/Notification)
- Priority
However, the big challenge we see with labels is the way they appear "randomly" in a "big bunch". Instead, if we could build in some sort of predictability/consistency (i.e. we know where we will find the customer, category, type & priority) it would make life a lot easier.
The simplest way to implement this seems to be sorting the labels; so scoped labels appear first and with a maximum of one per line.
In addition, ensuring we only ever have one scoped label on a line will help us to know exactly where to look.
For now I have thrown together some JavaScript I intend to deploy at my company through the use of a Google Chrome extension or by injecting into GitLab using Google Tag Manager. But if there is appetite, perhaps we could look at building this into the product?
The JavaScript;
- sorts (scoped labels first, then alphabetically)
- limits (maximum of one scoped label per line)
- aligns (all of the scoped label "keys" are the same width, so the "values" are aligned)
Of course, the ordering could be achieved without any customisation if we simply prefixed all of our scoped labels with an underscore. But without limiting them to one per row I think we will probably stick with the "hack" for now.
Very interesting note on one of the related issues, GitLab are already forcing prioritisation of certain labels by capitalising the first letter- so this could also work instead of the _
prefix.
Here are a few examples of running the script on GitLab.com issues before/after;
JavaScript Solution
var list = document.getElementsByClassName('issuable-show-labels')[0];
var items = list.children;
var itemsArr = [];
var maxWidth = 0;
for (var i = 0; i < items.length; i++) {
itemsArr.push(items[i]);
if (items[i].dataset.qaLabelName.includes('::')) {
var itemWidth = items[i].children[0].children[0].clientWidth;
if (itemWidth > maxWidth) maxWidth = itemWidth;
}
}
itemsArr.sort(function(a, b) {
var aLabel = a.dataset.qaLabelName.toLowerCase();
var bLabel = b.dataset.qaLabelName.toLowerCase();
aLabel = aLabel.includes('::') ? '_' + aLabel : aLabel;
bLabel = bLabel.includes('::') ? '_' + bLabel : bLabel;
return aLabel > bLabel ? 1 : -1;
});
maxWidth++;
for (i = 0; i < itemsArr.length; ++i) {
if (itemsArr[i].dataset.qaLabelName.includes('::')) itemsArr[i].children[0].children[0].style.width = maxWidth + 'px';
list.appendChild(itemsArr[i]);
if (itemsArr[i].dataset.qaLabelName.includes('::')) list.appendChild(document.createElement("div"));
}
Related;