var _b = {}; var _c = {}; var _e = {}; var _r = {}; var _t = {}; var _w = {}; var _page = ''; var _site = ''; var _apiUrl = ''; var _toggle = true; var _username = ''; var _machineId = ''; var _sessionId = ''; var _windowLocationHRef = ''; function compareFunctionSortOrder(a, b) { return a.SortOrder - b.SortOrder; } function compareFunctionParentId(a, b) { return a.ParentId - b.ParentId || a.Id - b.Id; } function compareFunctionWeightedShortestJobFirst(a, b) { if (b.WeightedShortestJobFirst === ' ') { return -1; } return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; } function getState(state) { let result; if (state == undefined) result = "9-Null"; else if (state === "New") result = `1-${state}`; else if (state === "Active") result = `2-${state}`; else if (state === "Resolved") result = `3-${state}`; else if (state === "Closed") result = `4-${state}`; else if (state === "Removed") result = `5-${state}`; else result = `8-${state}`; return result; } function getPriority(workItemType, priority, sortPriorityGroup) { let result; if (workItemType === "Bug") result = "0-Bug {0}"; else if (priority == undefined || priority === 0) result = "9-Null {0}"; else if (priority === 1) result = `${priority}-High {${sortPriorityGroup}}`; else if (priority === 2) result = `${priority}-Med {${sortPriorityGroup}}`; else if (priority === 3) result = `${priority}-Low {${sortPriorityGroup}}`; else if (priority === 4) result = `${priority}-TBD {4}`; else result = "8-Not {0}"; return result; } function getNotifications(x, aggregation) { let result; if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) result = " "; else { result = ''; aggregation.Notifications.forEach(element => { const username = element.username == null ? 'user' : element.username; if (element.value === "1") { result += 'Highest:' + username + ';|'; } else if (element.value === "2") { result += 'High:' + username + ';|'; } else if (element.value === "3") { result += 'Medium:' + username + ';|'; } else if (element.value === "4") { result += 'Low:' + username + ';|'; } else if (element.value === "5") { result += 'Lowest:' + username + ';|'; } else { result += element.value + ':' + username + ';|'; } }); result = result.substring(0, result.length - 1); result = result.replaceAll('|', '
'); } return result; } function round(value, factor) { return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); } function sum(collection) { let sum = 0; if (collection != undefined) { for (let i = 0; i < collection.length; i++) { sum += collection[i]; } } return sum; } function updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints) { if (workItem != undefined) { let data = dataB == undefined ? undefined : dataB[workItem.Id]; if (data == undefined) { workItem.CumulativeStoryPoints = " "; workItem.TotalStoryPoints = " "; workItem.AbsoluteDelta = " "; workItem.Effort = " "; workItem.BusinessValue = " "; workItem.TimeCriticality = " "; workItem.RiskReductionMinusOpportunityEnablement = " "; workItem.CoD = " "; workItem.WeightedShortestJobFirst = " "; workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); workItem.EffortNotifications = " "; workItem.BusinessValueNotifications = " "; workItem.TimeCriticalityNotifications = " "; workItem.RiskReductionMinusOpportunityEnablementNotifications = " "; workItem.SortOrder = 0; } else { workItem.CumulativeStoryPoints = " "; workItem.TotalStoryPoints = totalStoryPoints + ' User Story Point(s)'; workItem.AbsoluteDelta = data.Effort == undefined || data.Effort.FibonacciAverage == undefined || totalStoryPoints == undefined || totalStoryPoints === 0 ? " " : round(Math.abs(data.Effort.FibonacciAverage - ((totalStoryPoints / highestTotalStoryPoints) * 5)), 1); workItem.Effort = data.Effort == undefined || data.Effort.FibonacciAverage == undefined ? " " : round(data.Effort.FibonacciAverage, 100); workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? " " : round(data.BusinessValue.FibonacciAverage, 100); workItem.TimeCriticality = data.TimeCriticality == undefined || data.TimeCriticality.FibonacciAverage == undefined ? " " : round(data.TimeCriticality.FibonacciAverage, 100); workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? " " : round(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100); workItem.CoD = data.CostOfDelay == undefined ? " " : round(data.CostOfDelay, 100); workItem.WeightedShortestJobFirst = data.WeightedShortestJobFirst == undefined ? " " : round(data.WeightedShortestJobFirst, 100); workItem.Priority = data.SortPriority == undefined ? getPriority(workItem.WorkItemType, 4, 0) : getPriority(workItem.WorkItemType, data.SortPriority, data.SortPriorityGroup); workItem.EffortNotifications = data.Effort == undefined ? " " : getNotifications(e, data.Effort); workItem.BusinessValueNotifications = data.BusinessValue == undefined ? " " : getNotifications(b, data.BusinessValue); workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? " " : getNotifications(t, data.TimeCriticality); workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? " " : getNotifications(r, data.RiskReductionOpportunityEnablement); workItem.SortOrder = data.SortOrder == undefined ? 0 : data.SortOrder; } } } function updateRecordParent(parent, workItem) { if (parent == undefined) { workItem.ParentId = 9999999; workItem.ParentTitle = null; workItem.ParentState = null; workItem.ParentCoD = 9999999; } else { workItem.ParentId = parent.Id; workItem.ParentCoD = parent.CoD; workItem.ParentTitle = parent.Title; workItem.ParentState = getState(parent.State); } } function getRecords(b, r, t, c, e, w, data, dataB, workItems) { let parent; let workItem; let storyPoints; let records = []; let totalStoryPoints; let highestTotalStoryPoints = 0; for (let i = 0; i < data.length; i++) { workItem = data[i].WorkItem; if (workItem.WorkItemType !== 'Feature') continue; if (workItem.State !== 'Active' && workItem.State !== 'New') continue; if (workItem.Tags != null && workItem.Tags.includes("Ignore")) continue; storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); totalStoryPoints = sum(storyPoints); if (totalStoryPoints > highestTotalStoryPoints) highestTotalStoryPoints = totalStoryPoints; } for (let i = 0; i < data.length; i++) { parent = data[i].Parent; workItem = data[i].WorkItem; if (workItem.WorkItemType !== 'Feature') continue; if (workItem.State !== 'Active' && workItem.State !== 'New') continue; if (workItem.Tags != null && workItem.Tags.includes("Ignore")) continue; storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); totalStoryPoints = sum(storyPoints); if ((_windowLocationHRef.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (_windowLocationHRef.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES')) continue; updateRecordParent(parent, workItem); updateRecordCoD(b, r, t, c, e, w, parent, highestTotalStoryPoints, null, null); updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints); workItem.State = getState(workItem.State); records.push(workItem); } if (_windowLocationHRef.indexOf('=WSJF') > -1) { records.sort(compareFunctionWeightedShortestJobFirst); } else if (_windowLocationHRef.indexOf('=LIVE') > -1) { records.sort(compareFunctionSortOrder); } else { records.sort(compareFunctionParentId); } return records; } function warn(message) { if (typeof acquiredVsCodeApi === 'function') acquiredVsCodeApi.postMessage(message); console.warn(message); } function sendValue(fromHtml, element, page, id) { let notification = { id: id, machineId: _machineId, page: page, sessionId: _sessionId, site: _site, time: new Date().getTime(), username: _username, value: element.value, }; if (fromHtml && notification.value !== "9") { $("#AllTextarea").hide(); document.getElementById('AllTextarea').value = ''; $.post(_apiUrl, notification) .done(function (msg) { console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); }) .fail(function (_, textStatus, _) { warn(textStatus); }); } } function setRecords(fromHtml, b, r, t, c, e, w, records) { let record; let lineA = ""; let lineB = ""; let lineC = ""; let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tCoD\tEffort\tWSJF\tFeature Total Story Points\tAbsolute Delta\tState\tPriority\tRequester\tAssigned To\tSystem\r\n'; let html = 'Parent IdParent TitleIdRequesterTitleAssigned ToSystem(s)StatePriorityRisk Reduction and/or Opportunity EnablementTime CriticalityBusiness ValueCost of Delay (CoD)EffortWSJF'; for (let i = 0; i < records.length; i++) { record = records[i]; text += record.Id + '\t' + record.RiskReductionMinusOpportunityEnablement + '\t' + record.TimeCriticality + '\t' + record.BusinessValue + '\t' + record.CoD + '\t' + record.Effort + '\t' + record.WeightedShortestJobFirst + '\t' + record.TotalStoryPoints.split(' ')[0] + '\t' + record.AbsoluteDelta + '\t' + record.State.split('-')[0] + '\t' + record.Priority.split('-')[0] + '\t' + record.Requester + '\t' + record.AssignedTo + '\t' + record.Tags + '\r\n'; lineA = '' + '' + record.ParentId + "" + '' + record.ParentTitle + '' + '' + record.Id + "" + '' + record.Requester + '' + record.Title + '' + record.AssignedTo + '' + record.Tags + '' + record.State + '' + record.Priority + '' + record.RiskReductionMinusOpportunityEnablementNotifications + '
' + '' + '' + record.TimeCriticalityNotifications + '
' + '' + '' + record.BusinessValueNotifications + '
' + '' + '' + record.CoD + '' + '' + record.EffortNotifications + '
'; if (!fromHtml || _windowLocationHRef.indexOf('=EFFORT') === -1) { lineB = ''; } else { lineB = '
'; } lineC = '' + record.TotalStoryPoints + '' + '' + record.WeightedShortestJobFirst + '
' + record.CumulativeStoryPoints + '
' + ''; if (!fromHtml) console.log(text); html += lineA + lineB + lineC; } if (fromHtml) { document.getElementById('HeaderGrid').innerHTML = html.replaceAll('>null<', '> <'); if (_windowLocationHRef.indexOf('=WSJF') === -1) { document.getElementById('AllTextarea').value = text.replaceAll('null', '').replaceAll(' ', ''); } else { _toggle = !_toggle; $(".select").hide(); $("#AllTextarea").hide(); } } } function updateSite(c, w) { if (_windowLocationHRef.indexOf('=LEO') > -1) { _site = 'LEO'; document.title = document.title.replace('Infineon', 'HiRel (Leominster)'); document.getElementById('siteHeader').innerText = 'HiRel (Leominster)'; } else if (_windowLocationHRef.indexOf('=MES') > -1) { _site = 'MES'; document.title = document.title.replace('Infineon', 'Mesa'); document.getElementById('siteHeader').innerText = 'Mesa'; } else { _site = 'Infineon'; document.title = document.title.replace('Infineon', 'Infineon'); document.getElementById('siteHeader').innerText = 'Infineon'; } if (_windowLocationHRef.indexOf('=WSJF') > -1) { document.getElementById('th-span').innerHTML = w.th + ' sorted by WSJF'; } else if (_windowLocationHRef.indexOf('=LIVE') > -1) { document.getElementById('th-span').innerHTML = c.th + ' sorted by CoD'; } else if (_windowLocationHRef.indexOf('=EFFORT') > -1) { document.getElementById('th-span').innerHTML = c.th + ' sorted by Parent Id'; } else { document.getElementById('th-span').innerHTML = c.th + ' sorted by Parent Id'; } } function setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems) { let records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); console.log(dataA.length); if (dataA.length > 0) console.log(dataA[0]); setRecords(fromHtml, b, r, t, c, e, w, records); $("#toggle").click(function () { if (_toggle) $(".select").hide(); else $(".select").show(); _toggle = !_toggle; }); } function highlight(el, i) { el.before("") el.prev() .width(el.width()) .height(el.height()) .css({ "position": "absolute", "background-color": "#ffff99", "opacity": ".9" }) .fadeOut(1000 * i); } function updateWorkItem(b, r, t, c, e, w, page, workItem) { console.log(workItem); let x = null; let aggregation = null; if (page === b.page) { x = b; aggregation = workItem.BusinessValue; } else if (page === r.page) { x = r; aggregation = workItem.RiskReductionOpportunityEnablement; } else if (page === t.page) { x = t; aggregation = workItem.TimeCriticality; } else if (page === e.page) { x = e; aggregation = workItem.Effort; } if (x == undefined) warn("Error with page!"); else if (aggregation.FibonacciAverage == undefined) warn("FibonacciAverage not set!"); else { $('#' + x.page + workItem.Id).text('!' + round(aggregation.FibonacciAverage, 100)); if (workItem.WeightedShortestJobFirst != undefined) { $('#' + w.page + workItem.Id).text('!' + round(workItem.WeightedShortestJobFirst, 100)); } if (workItem.CostOfDelay != undefined) { let element = $('#' + c.page + workItem.Id); element.text('!' + round(workItem.CostOfDelay, 100)); if (_windowLocationHRef.indexOf('=LIVE') > -1) { if (workItem.SortBeforeId != undefined) { let found = 0; let row = element.parents("tr:first"); let next = row; for (let i = 0; i < 150; i++) { next = next.next(); if (next == undefined) break; if (next.attr('id') != 'tr' + workItem.SortBeforeId) continue; console.log("Moved " + i + " down"); row.insertAfter(next); found = i; break; } if (!found) { let prev = row; for (let i = 0; i < 150; i++) { prev = prev.prev(); if (prev == undefined) break; if (prev.attr('id') != 'tr' + workItem.SortBeforeId) continue; console.log("Moved " + i + " up"); row.insertAfter(prev); found = i; break; } } if (found != 0) { highlight(row, found); } else { console.log("Not found!"); } } } } } }; function setupPingPong() { let notification = { id: null, machineId: _machineId, page: _page, sessionId: _sessionId, site: _site, time: new Date().getTime(), username: _username, value: null, }; $.get(_apiUrl, notification) .done(function (data) { if (data != undefined && data.length > 0) { keyValuePair = JSON.parse(data); if (keyValuePair.Key != undefined && keyValuePair.Value.Id != undefined && keyValuePair.Value != undefined) { updateWorkItem(_b, _r, _t, _c, _e, _w, keyValuePair.Key, keyValuePair.Value); } } }) .fail(function (_, textStatus, _) { warn(textStatus); }); } function initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, _) { _b = b; _r = r; _t = t; _c = c; _e = e; _w = w; _page = _b.page; _apiUrl = apiUrl; _username = username; _machineId = machineId; _windowLocationHRef = windowLocationHRef; _sessionId = _windowLocationHRef.indexOf('=LIVE') > -1 ? self.crypto.randomUUID() : ''; if (!fromHtml) { console.log(b); console.log(r); console.log(t); console.log(c); console.log("Done :)"); } else { updateSite(c, w); $.getJSON(workItems.b, { _: new Date().getTime() }, function (dataB) { $.getJSON(workItems.a, { _: new Date().getTime() }, function (dataA) { setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems); if (_windowLocationHRef.indexOf('=LIVE') > -1) { _ = setInterval(setupPingPong, workItems.timeout); } }); }); } } // #region Test if (typeof document == 'undefined') { const username = ''; const machineId = ''; const fromHtml = false; const baseUri = 'http://eaf-dev.mes.infineon.com:5054'; const apiUrl = baseUri + '/api/v1/ado/'; const windowLocationHRef = baseUri + '/html/cod.html?site=MES'; const signalRUrl = baseUri + '/signalr'; const workItems = { a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', b: baseUri + '/markdown/{}.json?v=2025-04-14-08-10', timeout: 3000, }; const b = { page: "business", description: "Value", th: "Business Value", span: "What is the relative value to the Customer or business?
• Do our users prefer this over that?
• What is the revenue impact on our business?
• Is there a potential penalty or other negative effects if we delay?" }; const r = { page: "risk", description: "Risk", th: "Risk Reduction and/or Opportunity Enablement", span: "What else does this do for our business?
• Reduce the risk of this or future delivery?
• Is there value in the information we will receive?
• Enable new business opportunities?" }; const t = { page: "time", description: "Critical", th: "Time Criticality", span: "How does user/business value decay over time?
• Is there a fixed deadline?
• Will they wait for us or move to another Solution?
• What is the current effect on Customer satisfaction?" }; const c = { page: "cod", description: "CoD", th: "Cost of Delay (CoD)", span: "Cost of Delay (CoD) is the money lost by delaying or not doing a job for a specific time. It's a measure of the economic value of a job over time." }; const e = { page: "effort", description: "Effort", th: "Effort", span: "Effort" }; const w = { page: "wsjf", description: "WSJF", th: "Weightest Shortest Job First calculation (WSJF)", span: "Weightest Shortest Job First calculation (see @SCALE formula)" }; _windowLocationHRef = windowLocationHRef; fetch(workItems.b, { _: new Date().getTime() }) .then((res) => res.text()) .then((textB) => { fetch(workItems.a, { _: new Date().getTime() }) .then((res) => res.text()) .then((textA) => { const dataA = JSON.parse(textA); const dataB = JSON.parse(textB); if (dataA.length > 0) console.log(dataA[0]); const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); setRecords(fromHtml, b, r, t, c, e, w, records); initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); }) .catch((e) => console.error(e)); }) .catch((e) => console.error(e)); } // #endregion Test