Added ts file for bun testing
Added http to text area box Moved CoD column to match query Alignment
This commit is contained in:
433
Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
Normal file
433
Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
Normal file
@ -0,0 +1,433 @@
|
||||
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: any, b: any) {
|
||||
return a.SortOrder - b.SortOrder;
|
||||
}
|
||||
|
||||
function compareFunctionParentId(a: any, b: any) {
|
||||
return a.ParentId - b.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareFunctionWeightedShortestJobFirst(a: any, b: any) {
|
||||
if (b.WeightedShortestJobFirst === ' ') {
|
||||
return -1;
|
||||
}
|
||||
return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst;
|
||||
}
|
||||
|
||||
function getState(state: any) {
|
||||
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: any, priority: any, sortPriorityGroup: any) {
|
||||
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: any, aggregation: any) {
|
||||
let result: any;
|
||||
if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0)
|
||||
result = ' ';
|
||||
else {
|
||||
result = '';
|
||||
aggregation.Notifications.forEach((element: any) => {
|
||||
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('|', '<br />');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function round(value: any, factor: number) {
|
||||
return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2);
|
||||
}
|
||||
|
||||
function roundMultiply(value: any, factor: number, multiply: number) {
|
||||
return (Math.round((value + Number.EPSILON) * factor) / factor) * multiply;
|
||||
}
|
||||
|
||||
function sum(collection: any) {
|
||||
let sum = 0;
|
||||
if (collection != undefined) {
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
sum += collection[i];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
function updateRecordCoD(b: any, r: any, t: any, c: any, e: any, w: any, workItem: any, highestTotalStoryPoints: any, dataB: any, totalStoryPoints: any) {
|
||||
if (workItem != undefined) {
|
||||
let data = dataB == undefined ? undefined : dataB[workItem.Id];
|
||||
if (data == undefined) {
|
||||
workItem.api = '';
|
||||
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 {
|
||||
let effort = workItem.Effort;
|
||||
let businessValue = workItem.BusinessValue;
|
||||
let timeCriticality = workItem.TimeCriticality;
|
||||
let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement;
|
||||
let weightedShortestJobFirst = workItem.WeightedShortestJobFirst == undefined ? null : workItem.WeightedShortestJobFirst.toFixed(2);
|
||||
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 ? ' ' : roundMultiply(data.Effort.FibonacciAverage, 100, 100);
|
||||
workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? ' ' : roundMultiply(data.BusinessValue.FibonacciAverage, 100, 100);
|
||||
workItem.TimeCriticality = data.TimeCriticality == undefined || data.TimeCriticality.FibonacciAverage == undefined ? ' ' : roundMultiply(data.TimeCriticality.FibonacciAverage, 100, 100);
|
||||
workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? ' ' : roundMultiply(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100, 100);
|
||||
workItem.CoD = data.CostOfDelay == undefined ? ' ' : roundMultiply(data.CostOfDelay, 100, 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;
|
||||
let check = effort == workItem.Effort
|
||||
&& businessValue === workItem.BusinessValue
|
||||
&& timeCriticality === workItem.TimeCriticality
|
||||
&& riskReductionMinusOpportunityEnablement === workItem.RiskReductionMinusOpportunityEnablement;
|
||||
if (check && weightedShortestJobFirst == workItem.WeightedShortestJobFirst) {
|
||||
workItem.api = '';
|
||||
} else {
|
||||
workItem.api = `
|
||||
### Work Item Patch ${check} WSJF ${workItem.Id} ${weightedShortestJobFirst} != ${workItem.WeightedShortestJobFirst}
|
||||
|
||||
patch {{Factory-Integration}}/_apis/wit/workitems/${workItem.Id}?api-version=7.0
|
||||
Authorization: Basic {{PAT}}
|
||||
Content-Type: application/json-patch+json
|
||||
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Microsoft.VSTS.Common.BusinessValue",
|
||||
"value": "${workItem.BusinessValue}"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Microsoft.VSTS.Scheduling.Effort",
|
||||
"value": "${workItem.Effort}"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Custom.RRminusOE",
|
||||
"value": "${workItem.RiskReductionMinusOpportunityEnablement}"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Microsoft.VSTS.Common.TimeCriticality",
|
||||
"value": "${workItem.TimeCriticality}"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Custom.WSJF",
|
||||
"value": "${workItem.WeightedShortestJobFirst}"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/fields/Custom.WSJFFib",
|
||||
"value": "${workItem.WeightedShortestJobFirst}"
|
||||
}
|
||||
]`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateRecordParent(parent: any, workItem: any) {
|
||||
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: any, r: any, t: any, c: any, e: any, w: any, data: any, dataB: any, workItems: any) {
|
||||
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 getHtmlTextAndHttp(fromHtml: any, b: any, r: any, t: any, c: any, e: any, w: any, records: any) {
|
||||
let record;
|
||||
let http = '';
|
||||
let lineA = '';
|
||||
let lineB = '';
|
||||
let lineC = '';
|
||||
let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tEffort\tWSJF\tCoD\tFeature Total Story Points\tAbsolute Delta\tState\tRequester\tAssigned To\tIteration Path\tSystem\tTitle-123\r\n';
|
||||
let html = '<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>Cost of Delay (CoD)</th><th>Effort</th><th>WSJF</th></tr>';
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
record = records[i];
|
||||
if (record.api !== '') {
|
||||
http += record.api + '\r\n';
|
||||
}
|
||||
text += record.Id + '\t' +
|
||||
record.RiskReductionMinusOpportunityEnablement + '\t' +
|
||||
record.TimeCriticality + '\t' +
|
||||
record.BusinessValue + '\t' +
|
||||
record.Effort + '\t' +
|
||||
record.WeightedShortestJobFirst + '\t' +
|
||||
record.CoD + '\t' +
|
||||
record.TotalStoryPoints.split(' ')[0] + '\t' +
|
||||
record.AbsoluteDelta + '\t' +
|
||||
record.State.split('-')[0] + '\t' +
|
||||
record.Requester + '\t' +
|
||||
record.AssignedTo + '\t' +
|
||||
record.IterationPath + '\t' +
|
||||
record.Tags + '\t' +
|
||||
record.Title + '\r\n';
|
||||
lineA = '<tr id="tr' + record.Id + '"><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
'</td><td>' + record.ParentTitle +
|
||||
'</td><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
'</td><td>' + record.Requester +
|
||||
'</td><td>' + record.Title +
|
||||
'</td><td>' + record.AssignedTo +
|
||||
'</td><td>' + record.Tags +
|
||||
'</td><td>' + record.State +
|
||||
'</td><td>' + record.Priority +
|
||||
'</td><td><span id=' + r.page + record.Id + '>' + record.RiskReductionMinusOpportunityEnablementNotifications + '</span><br />' +
|
||||
'<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + r.page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">Highest (Most ' + r.description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
'</select>' +
|
||||
'</td><td><span id=' + t.page + record.Id + '>' + record.TimeCriticalityNotifications + '</span><br />' +
|
||||
'<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + t.page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">Highest (Most ' + t.description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
'</select>' +
|
||||
'</td><td><span id=' + b.page + record.Id + '>' + record.BusinessValueNotifications + '</span><br />' +
|
||||
'<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + b.page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">Highest (Most ' + b.description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
'</select>' +
|
||||
'</td><td><span id=' + c.page + record.Id + '>' + record.CoD + '</span>' +
|
||||
'</td><td><span id=' + e.page + record.Id + '>' + record.EffortNotifications + '</span><br />';
|
||||
if (!fromHtml || _windowLocationHRef.indexOf('=EFFORT') === -1) {
|
||||
lineB = '';
|
||||
}
|
||||
else {
|
||||
lineB = '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + e.page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">Highest (Most ' + e.description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
'</select><br />';
|
||||
}
|
||||
lineC = '<span>' + record.TotalStoryPoints + '</span></td>' +
|
||||
'<td><span id=' + w.page + record.Id + '>' + record.WeightedShortestJobFirst + '<br /><span>' + record.CumulativeStoryPoints + '</span></span>' +
|
||||
'</td></tr>';
|
||||
if (!fromHtml)
|
||||
console.log(text);
|
||||
html += lineA + lineB + lineC;
|
||||
}
|
||||
return { html, text, http };
|
||||
}
|
||||
|
||||
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?<br>• Do our users prefer this over that?<br>• What is the revenue impact on our business?<br>• 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?<br>• Reduce the risk of this or future delivery?<br>• Is there value in the information we will receive?<br>• Enable new business opportunities?'
|
||||
};
|
||||
const t = {
|
||||
page: 'time',
|
||||
description: 'Critical',
|
||||
th: 'Time Criticality',
|
||||
span: 'How does user/business value decay over time?<br>• Is there a fixed deadline?<br>• Will they wait for us or move to another Solution?<br>• 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)
|
||||
.then((res) => res.text())
|
||||
.then((textB) => {
|
||||
fetch(workItems.a)
|
||||
.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);
|
||||
let result = getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records);
|
||||
if (result == undefined) { }
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
})
|
||||
.catch((e) => console.error(e));
|
Reference in New Issue
Block a user