I've recently switched process models from XML to Inherited, to allow for easier customization of Work Item Types, etc.
Under the old XML model we could modify, for example, a PBI's Effort
field to create a pick list of numbers for easier data entry. I'm not seeing how to do this with the Inheritance model:
The documentation for doing so under XML is here, but there doesn't seem to be an equivalent under Inheritance.
For example, here's the Effort
field in my XML-modeled collection:
Is it possible to modify a PBI to this extent under the Inheritance model? If so, how does one go about doing it?
It can't be done using in-built methods. So say Microsoft Support Engineers.
Tossing together this clunky workaround wasn't pleasant, but at least it accomplishes the goal (I say that because I loathe working in JavaScript).
Install the TamperMonkey extension in your browser and load up the script below. Replace example
, host
, collection
and project
in the URLs with your own values. Edit a PBI and feel the love.
Note that this only addresses PBIs and their Effort and Business Value fields under the Scrum template; that's all I needed to cover at this point. The script will need to be adjusted to support other Work Item Types and fields.
// ==UserScript==
// @name PBI PickLists
// @namespace https://example.com/
// @version 0.1
// @description Try to take over the world!
// @author You
// @match http://host/collection/*
// @icon none
// @grant none
// ==/UserScript==
(function() {
"use strict";
// Your code here...
function setSelected(item) {
item.setAttribute("aria-selected", "true");
item.classList.add("selected");
item.style.backgroundColor = "#deecf8";
item.style.border = "1px solid #c7dff3";
}
function clearSelected(item) {
item.setAttribute("aria-selected", "false");
item.classList.remove("selected");
item.style.backgroundColor = "white";
item.style.border = "1px solid white";
}
function getFibonacciList(textBox, container) {
var pickList = document.createElement("ul");
var items = ["1", "2", "3", "5", "8", "13"];
pickList.setAttribute("role", "listbox");
pickList.classList.add("items");
pickList.style.marginBottom = "0px";
pickList.style.marginTop = "0px";
for (var i = 0; i < items.length; i++) {
var item = document.createElement("li");
item.setAttribute("role", "option");
item.setAttribute("aria-posinset", i + 1);
item.setAttribute("aria-setsize", items.length);
item.setAttribute("data-id", i);
item.style.padding = "3px";
item.style.cursor = "pointer";
item.textContent = items[i];
if (item.textContent == textBox.value) {
setSelected(item);
} else {
clearSelected(item);
}
pickList.appendChild(item);
}
pickList.childNodes.forEach(function(item) {
item.addEventListener("mouseenter", function() {
setSelected(item);
});
item.addEventListener("mouseleave", function() {
clearSelected(item);
});
});
return pickList;
}
function clearList(textBox, uniqueId) {
var container = document.getElementById(uniqueId);
if (container) {
var items = container.querySelectorAll("li");
var item = container.querySelector("li.selected");
if (item) {
textBox.value = item.textContent;
textBox.dispatchEvent(new Event("change"));
}
items.forEach(function(item) {
item.removeEventListener("mouseenter", function() {
setSelected(item);
});
item.removeEventListener("mouseleave", function() {
clearSelected(item);
});
});
container.remove();
}
}
function buildList(textBox, uniqueId) {
var container = document.getElementById(uniqueId);
if (!container) {
var rect = textBox.getBoundingClientRect();
var width = rect.width + 5
var x = rect.left - 3;
var y = rect.top + rect.height + 1;
container = document.createElement("div");
container.setAttribute("aria-label", textBox.getAttribute("aria-label"));
container.setAttribute("id", uniqueId);
container.classList.add("combo-drop-popup");
container.style.backgroundColor = "#fff";
container.style.transition = 'height 0.25s ease';
container.style.overflow = 'hidden';
container.style.opacity = "1";
container.style.zIndex = "1910887";
container.style.border = "1px solid #c8c8c8";
container.style.height = '0';
container.style.width = width + "px";
container.style.left = x + "px";
container.style.top = y + "px";
var pickList = getFibonacciList(textBox, container);
container.appendChild(pickList);
textBox.parentNode.parentNode.appendChild(container);
setTimeout(function() {
container.style.height = "auto"
}, 250);
}
}
function addPickList(textBox, uniqueId) {
if (textBox) {
var arrow = textBox.parentNode.nextSibling
arrow.style.marginLeft = textBox.offsetWidth - 23 + "px";
arrow.style.marginTop = "3px";
arrow.style.display = "block";
if (!document.getElementById(uniqueId)) {
textBox.addEventListener("focus", function() { buildList(textBox, uniqueId); });
textBox.addEventListener("blur", function() { clearList(textBox, uniqueId); });
arrow.addEventListener("click", function() { buildList(textBox, uniqueId); });
};
}
}
function isPbiEditor() {
var isPbiEditor = false;
var anchors = document.querySelectorAll("a");
for (var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if (anchor.href.startsWith("http://host/collection/project/_workitems/edit/")) {
if (anchor.textContent.startsWith("Product Backlog Item")) {
isPbiEditor = true;
break;
}
}
}
return isPbiEditor;
}
var observer = new MutationObserver(function(mutations) {
var effort = document.querySelector("input[aria-label='Effort']");
var value = document.querySelector("input[aria-label='Business Value']");
for (var mutation of mutations) {
if (mutation.type === "childList") {
if (isPbiEditor()) {
addPickList(effort, "58KJ76F");
addPickList(value, "37L9Q9P");
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
})();