Added ts file for bun testing
Added http to text area box Moved CoD column to match query Alignment
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -339,6 +339,9 @@ ASALocalRun/ | |||||||
| !**/.vscode/tasks.json | !**/.vscode/tasks.json | ||||||
| !**/.vscode/mklink.md | !**/.vscode/mklink.md | ||||||
| !**/.vscode/*.http | !**/.vscode/*.http | ||||||
|  | **/.vscode/2025-*.http | ||||||
|  | **/.vscode/2026-*.http | ||||||
|  |  | ||||||
|  |  | ||||||
| *.lnk | *.lnk | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								Adaptation/.vscode/download-work-items.http
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								Adaptation/.vscode/download-work-items.http
									
									
									
									
										vendored
									
									
								
							| @ -1,21 +0,0 @@ | |||||||
| @host = https://tfs.intra.infineon.com |  | ||||||
| @pat = asdf |  | ||||||
| @ids = 126018, 224543 |  | ||||||
|  |  | ||||||
| GET {{host}}/tfs/FactoryIntegration/_apis/wit/workitems?ids={{ids}}&$expand=Relations |  | ||||||
| Accept: application/json |  | ||||||
| Authorization: Basic {{pat}} |  | ||||||
|  |  | ||||||
| ### |  | ||||||
|  |  | ||||||
| GET {{host}}/tfs/FactoryIntegration/_apis/wit/workitems/{{ids}}/updates |  | ||||||
| Accept: application/json |  | ||||||
| Authorization: Basic {{pat}} |  | ||||||
|  |  | ||||||
| ### Iterations |  | ||||||
|  |  | ||||||
| GET {{host}}/tfs/FactoryIntegration/ART%20SPS/cea9f426-6fb1-4d65-93d5-dbf471056212/_apis/work/teamsettings/iterations? |  | ||||||
| Accept: application/json |  | ||||||
| Authorization: Basic {{pat}} |  | ||||||
|  |  | ||||||
| ### |  | ||||||
							
								
								
									
										22
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -11,6 +11,26 @@ | |||||||
|       "request": "launch", |       "request": "launch", | ||||||
|       "name": "node Launch Current Opened File", |       "name": "node Launch Current Opened File", | ||||||
|       "program": "${file}" |       "program": "${file}" | ||||||
|     } |     }, | ||||||
|  |     { | ||||||
|  |       "type": "bun", | ||||||
|  |       "internalConsoleOptions": "neverOpen", | ||||||
|  |       "request": "launch", | ||||||
|  |       "name": "Debug File", | ||||||
|  |       "program": "${file}", | ||||||
|  |       "cwd": "${workspaceFolder}", | ||||||
|  |       "stopOnEntry": false, | ||||||
|  |       "watchMode": false | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "bun", | ||||||
|  |       "internalConsoleOptions": "neverOpen", | ||||||
|  |       "request": "launch", | ||||||
|  |       "name": "Run File", | ||||||
|  |       "program": "${file}", | ||||||
|  |       "cwd": "${workspaceFolder}", | ||||||
|  |       "noDebug": true, | ||||||
|  |       "watchMode": false | ||||||
|  |     }, | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
							
								
								
									
										5
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -22,9 +22,12 @@ | |||||||
|         "Rcpe", |         "Rcpe", | ||||||
|         "RESIMAPCDE", |         "RESIMAPCDE", | ||||||
|         "Rsens", |         "Rsens", | ||||||
|  |         "signalr", | ||||||
|         "Smpl", |         "Smpl", | ||||||
|         "Villach", |         "Villach", | ||||||
|         "Vrng" |         "Vrng", | ||||||
|  |         "Weightest", | ||||||
|  |         "WSJF" | ||||||
|     ], |     ], | ||||||
|     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", |     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", | ||||||
|     "workbench.colorCustomizations": { |     "workbench.colorCustomizations": { | ||||||
|  | |||||||
							
								
								
									
										160
									
								
								Adaptation/.vscode/tfs.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								Adaptation/.vscode/tfs.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | |||||||
|  | @Manufacturing-IT = https://tfs.intra.infineon.com/tfs/ManufacturingIT | ||||||
|  | @Factory-Integration = https://tfs.intra.infineon.com/tfs/FactoryIntegration | ||||||
|  | @userId = phares | ||||||
|  | @ids = 126018, 224543 | ||||||
|  | @Unauthorized-Chase = asdf | ||||||
|  | @Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E = asdf | ||||||
|  |  | ||||||
|  | ### Work Items Expand Relations | ||||||
|  |  | ||||||
|  | GET {{Factory-Integration}}/_apis/wit/workitems?ids={{ids}}&$expand=Relations | ||||||
|  | Accept: application/json | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  |  | ||||||
|  | ### Work Items Updates | ||||||
|  |  | ||||||
|  | GET {{Factory-Integration}}/_apis/wit/workitems/{{ids}}/updates | ||||||
|  | Accept: application/json | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  |  | ||||||
|  | ### Iterations | ||||||
|  |  | ||||||
|  | GET {{Factory-Integration}}/ART%20SPS/cea9f426-6fb1-4d65-93d5-dbf471056212/_apis/work/teamsettings/iterations? | ||||||
|  | Accept: application/json | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  |  | ||||||
|  | ### User Entitlements | ||||||
|  |  | ||||||
|  | GET {{Factory-Integration}}/_apis/userEntitlements/{{userId}}?api-version=6.0-preview.3 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Accept: application/json | ||||||
|  |  | ||||||
|  | ### User Entitlements | ||||||
|  |  | ||||||
|  | GET {{Factory-Integration}}/_apis/userEntitlements?api-version=5.1-preview.2 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Accept: application/json | ||||||
|  |  | ||||||
|  | ### Work Item Patch | ||||||
|  |  | ||||||
|  | patch {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382290?api-version=7.0 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Content-Type: application/json-patch+json | ||||||
|  |  | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "op": "test", | ||||||
|  |     "path": "/rev", | ||||||
|  |     "value": 1 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "test", | ||||||
|  |     "path": "/fields/System.CreatedDate", | ||||||
|  |     "value": "2023-10-07T18:51:52.783Z" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/System.CreatedDate", | ||||||
|  |     "value": "2023-10-07T18:41:52.783Z" | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | ### Post Comment | ||||||
|  |  | ||||||
|  | POST {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382005/comments?api-version=5.1-preview.3 | ||||||
|  | Authorization: Basic {{Unauthorized-Chase}} | ||||||
|  | Content-Type: application/json | ||||||
|  |  | ||||||
|  | { | ||||||
|  |   "text": "Force updated by" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ### Delete Comment | ||||||
|  |  | ||||||
|  | DELETE {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382005/comments?api-version=5.1-preview.3 | ||||||
|  | Authorization: Basic {{Unauthorized-Chase}} | ||||||
|  | Content-Type: application/json | ||||||
|  |  | ||||||
|  | ### Work Item Patch WSJF | ||||||
|  |  | ||||||
|  | patch {{Factory-Integration}}/_apis/wit/workitems/292309?api-version=7.0 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Content-Type: application/json-patch+json | ||||||
|  |  | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Custom.WSJF", | ||||||
|  |     "value": "5" | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | ### Work Item Patch WSJF-B 100+300+400=800 800/200=4 | ||||||
|  |  | ||||||
|  | patch {{Factory-Integration}}/_apis/wit/workitems/292309?api-version=7.0 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Content-Type: application/json-patch+json | ||||||
|  |  | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||||
|  |     "value": "100" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||||
|  |     "value": "200" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Custom.RRminusOE", | ||||||
|  |     "value": "300" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||||
|  |     "value": "400" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Custom.WSJF", | ||||||
|  |     "value": "4" | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | ### Work Item Patch WSJF-B 400+400+400=1200 1200/200=6 | ||||||
|  |  | ||||||
|  | patch {{Factory-Integration}}/_apis/wit/workitems/110781?api-version=7.0 | ||||||
|  | Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||||
|  | Content-Type: application/json-patch+json | ||||||
|  |  | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||||
|  |     "value": "400" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||||
|  |     "value": "200" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Custom.RRminusOE", | ||||||
|  |     "value": "400" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||||
|  |     "value": "400" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "op": "replace", | ||||||
|  |     "path": "/fields/Custom.WSJF", | ||||||
|  |     "value": "6" | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | ### | ||||||
| @ -128,7 +128,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -153,7 +153,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             MoveArchive(reportFullPath, dateTime); |             MoveArchive(reportFullPath, dateTime); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -127,7 +127,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -126,7 +126,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); |             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -137,7 +137,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             SendData(reportFullPath, dateTime, descriptions); |             SendData(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -154,7 +154,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             PostOpenInsightMetrologyViewerAttachments(descriptions); |             PostOpenInsightMetrologyViewerAttachments(descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -173,7 +173,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); |         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); | ||||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); |         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             DirectoryMove(reportFullPath, dateTime, descriptions); |             DirectoryMove(reportFullPath, dateTime, descriptions); | ||||||
|         else if (!_IsEAFHosted) |         else if (!_IsEAFHosted) | ||||||
|  | |||||||
| @ -125,7 +125,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										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 weightedShortestJobFirst = workItem.WeightedShortestJobFirst.toFixed(2); | ||||||
|  |             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||||
|  |             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)); | ||||||
| @ -31,16 +31,16 @@ function compareFunctionWeightedShortestJobFirst(a, b) { | |||||||
| function getState(state) { | function getState(state) { | ||||||
|     let result; |     let result; | ||||||
|     if (state == undefined) |     if (state == undefined) | ||||||
|         result = "9-Null"; |         result = '9-Null'; | ||||||
|     else if (state === "New") |     else if (state === 'New') | ||||||
|         result = `1-${state}`; |         result = `1-${state}`; | ||||||
|     else if (state === "Active") |     else if (state === 'Active') | ||||||
|         result = `2-${state}`; |         result = `2-${state}`; | ||||||
|     else if (state === "Resolved") |     else if (state === 'Resolved') | ||||||
|         result = `3-${state}`; |         result = `3-${state}`; | ||||||
|     else if (state === "Closed") |     else if (state === 'Closed') | ||||||
|         result = `4-${state}`; |         result = `4-${state}`; | ||||||
|     else if (state === "Removed") |     else if (state === 'Removed') | ||||||
|         result = `5-${state}`; |         result = `5-${state}`; | ||||||
|     else |     else | ||||||
|         result = `8-${state}`; |         result = `8-${state}`; | ||||||
| @ -49,10 +49,10 @@ function getState(state) { | |||||||
|  |  | ||||||
| function getPriority(workItemType, priority, sortPriorityGroup) { | function getPriority(workItemType, priority, sortPriorityGroup) { | ||||||
|     let result; |     let result; | ||||||
|     if (workItemType === "Bug") |     if (workItemType === 'Bug') | ||||||
|         result = "0-Bug {0}"; |         result = '0-Bug {0}'; | ||||||
|     else if (priority == undefined || priority === 0) |     else if (priority == undefined || priority === 0) | ||||||
|         result = "9-Null {0}"; |         result = '9-Null {0}'; | ||||||
|     else if (priority === 1) |     else if (priority === 1) | ||||||
|         result = `${priority}-High {${sortPriorityGroup}}`; |         result = `${priority}-High {${sortPriorityGroup}}`; | ||||||
|     else if (priority === 2) |     else if (priority === 2) | ||||||
| @ -62,31 +62,31 @@ function getPriority(workItemType, priority, sortPriorityGroup) { | |||||||
|     else if (priority === 4) |     else if (priority === 4) | ||||||
|         result = `${priority}-TBD {4}`; |         result = `${priority}-TBD {4}`; | ||||||
|     else |     else | ||||||
|         result = "8-Not {0}"; |         result = '8-Not {0}'; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| function getNotifications(x, aggregation) { | function getNotifications(x, aggregation) { | ||||||
|     let result; |     let result; | ||||||
|     if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) |     if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) | ||||||
|         result = " "; |         result = ' '; | ||||||
|     else { |     else { | ||||||
|         result = ''; |         result = ''; | ||||||
|         aggregation.Notifications.forEach(element => { |         aggregation.Notifications.forEach(element => { | ||||||
|             const username = element.username == null ? 'user' : element.username; |             const username = element.username == null ? 'user' : element.username; | ||||||
|             if (element.value === "1") { |             if (element.value === '1') { | ||||||
|                 result += 'Highest:' + username + ';|'; |                 result += 'Highest:' + username + ';|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === "2") { |             else if (element.value === '2') { | ||||||
|                 result += 'High:' + username + ';|'; |                 result += 'High:' + username + ';|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === "3") { |             else if (element.value === '3') { | ||||||
|                 result += 'Medium:' + username + ';|'; |                 result += 'Medium:' + username + ';|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === "4") { |             else if (element.value === '4') { | ||||||
|                 result += 'Low:' + username + ';|'; |                 result += 'Low:' + username + ';|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === "5") { |             else if (element.value === '5') { | ||||||
|                 result += 'Lowest:' + username + ';|'; |                 result += 'Lowest:' + username + ';|'; | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
| @ -103,6 +103,10 @@ function round(value, factor) { | |||||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); |     return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function roundMultiply(value, factor, multiply) { | ||||||
|  |     return (Math.round((value + Number.EPSILON) * factor) / factor) * multiply; | ||||||
|  | } | ||||||
|  |  | ||||||
| function sum(collection) { | function sum(collection) { | ||||||
|     let sum = 0; |     let sum = 0; | ||||||
|     if (collection != undefined) { |     if (collection != undefined) { | ||||||
| @ -117,38 +121,91 @@ function updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, da | |||||||
|     if (workItem != undefined) { |     if (workItem != undefined) { | ||||||
|         let data = dataB == undefined ? undefined : dataB[workItem.Id]; |         let data = dataB == undefined ? undefined : dataB[workItem.Id]; | ||||||
|         if (data == undefined) { |         if (data == undefined) { | ||||||
|             workItem.CumulativeStoryPoints = " "; |             workItem.api = ''; | ||||||
|             workItem.TotalStoryPoints = " "; |             workItem.CumulativeStoryPoints = ' '; | ||||||
|             workItem.AbsoluteDelta = " "; |             workItem.TotalStoryPoints = ' '; | ||||||
|             workItem.Effort = " "; |             workItem.AbsoluteDelta = ' '; | ||||||
|             workItem.BusinessValue = " "; |             workItem.Effort = ' '; | ||||||
|             workItem.TimeCriticality = " "; |             workItem.BusinessValue = ' '; | ||||||
|             workItem.RiskReductionMinusOpportunityEnablement = " "; |             workItem.TimeCriticality = ' '; | ||||||
|             workItem.CoD = " "; |             workItem.RiskReductionMinusOpportunityEnablement = ' '; | ||||||
|             workItem.WeightedShortestJobFirst = " "; |             workItem.CoD = ' '; | ||||||
|  |             workItem.WeightedShortestJobFirst = ' '; | ||||||
|             workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); |             workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); | ||||||
|             workItem.EffortNotifications = " "; |             workItem.EffortNotifications = ' '; | ||||||
|             workItem.BusinessValueNotifications = " "; |             workItem.BusinessValueNotifications = ' '; | ||||||
|             workItem.TimeCriticalityNotifications = " "; |             workItem.TimeCriticalityNotifications = ' '; | ||||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = " "; |             workItem.RiskReductionMinusOpportunityEnablementNotifications = ' '; | ||||||
|             workItem.SortOrder = 0; |             workItem.SortOrder = 0; | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             workItem.CumulativeStoryPoints = " "; |             let effort = workItem.Effort; | ||||||
|  |             let businessValue = workItem.BusinessValue; | ||||||
|  |             let timeCriticality = workItem.TimeCriticality; | ||||||
|  |             let weightedShortestJobFirst = workItem.WeightedShortestJobFirst.toFixed(2); | ||||||
|  |             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||||
|  |             workItem.CumulativeStoryPoints = ' '; | ||||||
|             workItem.TotalStoryPoints = totalStoryPoints + ' User Story Point(s)'; |             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.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.Effort = data.Effort == undefined || data.Effort.FibonacciAverage == undefined ? ' ' : roundMultiply(data.Effort.FibonacciAverage, 100, 100); | ||||||
|             workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? " " : round(data.BusinessValue.FibonacciAverage, 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 ? " " : round(data.TimeCriticality.FibonacciAverage, 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 ? " " : round(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100); |             workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? ' ' : roundMultiply(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100, 100); | ||||||
|             workItem.CoD = data.CostOfDelay == undefined ? " " : round(data.CostOfDelay, 100); |             workItem.CoD = data.CostOfDelay == undefined ? ' ' : roundMultiply(data.CostOfDelay, 100, 100); | ||||||
|             workItem.WeightedShortestJobFirst = data.WeightedShortestJobFirst == undefined ? " " : round(data.WeightedShortestJobFirst, 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.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.EffortNotifications = data.Effort == undefined ? ' ' : getNotifications(e, data.Effort); | ||||||
|             workItem.BusinessValueNotifications = data.BusinessValue == undefined ? " " : getNotifications(b, data.BusinessValue); |             workItem.BusinessValueNotifications = data.BusinessValue == undefined ? ' ' : getNotifications(b, data.BusinessValue); | ||||||
|             workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? " " : getNotifications(t, data.TimeCriticality); |             workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? ' ' : getNotifications(t, data.TimeCriticality); | ||||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? " " : getNotifications(r, data.RiskReductionOpportunityEnablement); |             workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? ' ' : getNotifications(r, data.RiskReductionOpportunityEnablement); | ||||||
|             workItem.SortOrder = data.SortOrder == undefined ? 0 : data.SortOrder; |             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}" | ||||||
|  |                     } | ||||||
|  |                 ]`; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -181,7 +238,7 @@ function getRecords(b, r, t, c, e, w, data, dataB, workItems) { | |||||||
|             continue; |             continue; | ||||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') |         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||||
|             continue; |             continue; | ||||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) |         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||||
|             continue; |             continue; | ||||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); |         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||||
|         totalStoryPoints = sum(storyPoints); |         totalStoryPoints = sum(storyPoints); | ||||||
| @ -195,7 +252,7 @@ function getRecords(b, r, t, c, e, w, data, dataB, workItems) { | |||||||
|             continue; |             continue; | ||||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') |         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||||
|             continue; |             continue; | ||||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) |         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||||
|             continue; |             continue; | ||||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); |         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||||
|         totalStoryPoints = sum(storyPoints); |         totalStoryPoints = sum(storyPoints); | ||||||
| @ -236,12 +293,12 @@ function sendValue(fromHtml, element, page, id) { | |||||||
|         username: _username, |         username: _username, | ||||||
|         value: element.value, |         value: element.value, | ||||||
|     }; |     }; | ||||||
|     if (fromHtml && notification.value !== "9") { |     if (fromHtml && notification.value !== '9') { | ||||||
|         $("#AllTextarea").hide(); |         $('#AllTextarea').hide(); | ||||||
|         document.getElementById('AllTextarea').value = ''; |         document.getElementById('AllTextarea').value = ''; | ||||||
|         $.post(_apiUrl, notification) |         $.post(_apiUrl, notification) | ||||||
|             .done(function (msg) { |             .done(function (msg) { | ||||||
|                 console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); |                 console.log('Posted value of ' + notification.value + ' for ' + id + ' on page ' + page + ' ' + msg); | ||||||
|             }) |             }) | ||||||
|             .fail(function (_, textStatus, _) { |             .fail(function (_, textStatus, _) { | ||||||
|                 warn(textStatus); |                 warn(textStatus); | ||||||
| @ -249,22 +306,26 @@ function sendValue(fromHtml, element, page, id) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function setRecords(fromHtml, b, r, t, c, e, w, records) { | function getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records) { | ||||||
|     let record; |     let record; | ||||||
|     let lineA = ""; |     let http = ''; | ||||||
|     let lineB = ""; |     let lineA = ''; | ||||||
|     let lineC = ""; |     let lineB = ''; | ||||||
|     let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tCoD\tEffort\tWSJF\tFeature Total Story Points\tAbsolute Delta\tState\tRequester\tAssigned To\tIteration Path\tSystem\tTitle\r\n'; |     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>'; |     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++) { |     for (let i = 0; i < records.length; i++) { | ||||||
|         record = records[i]; |         record = records[i]; | ||||||
|  |         if (record.api !== '') { | ||||||
|  |             http += record.api + '\r\n'; | ||||||
|  |         } | ||||||
|         text += record.Id + '\t' + |         text += record.Id + '\t' + | ||||||
|             record.RiskReductionMinusOpportunityEnablement + '\t' + |             record.RiskReductionMinusOpportunityEnablement + '\t' + | ||||||
|             record.TimeCriticality + '\t' + |             record.TimeCriticality + '\t' + | ||||||
|             record.BusinessValue + '\t' + |             record.BusinessValue + '\t' + | ||||||
|             record.CoD + '\t' + |  | ||||||
|             record.Effort + '\t' + |             record.Effort + '\t' + | ||||||
|             record.WeightedShortestJobFirst + '\t' + |             record.WeightedShortestJobFirst + '\t' + | ||||||
|  |             record.CoD + '\t' + | ||||||
|             record.TotalStoryPoints.split(' ')[0] + '\t' + |             record.TotalStoryPoints.split(' ')[0] + '\t' + | ||||||
|             record.AbsoluteDelta + '\t' + |             record.AbsoluteDelta + '\t' + | ||||||
|             record.State.split('-')[0] + '\t' + |             record.State.split('-')[0] + '\t' + | ||||||
| @ -331,17 +392,7 @@ function setRecords(fromHtml, b, r, t, c, e, w, records) { | |||||||
|             console.log(text); |             console.log(text); | ||||||
|         html += lineA + lineB + lineC; |         html += lineA + lineB + lineC; | ||||||
|     } |     } | ||||||
|     if (fromHtml) { |     return { html, text, http }; | ||||||
|         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) { | function updateSite(c, w) { | ||||||
| @ -379,25 +430,36 @@ function setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems) { | |||||||
|     console.log(dataA.length); |     console.log(dataA.length); | ||||||
|     if (dataA.length > 0) |     if (dataA.length > 0) | ||||||
|         console.log(dataA[0]); |         console.log(dataA[0]); | ||||||
|     setRecords(fromHtml, b, r, t, c, e, w, records); |     let result = getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records); | ||||||
|     $("#toggle").click(function () { |     if (fromHtml) { | ||||||
|  |         document.getElementById('HeaderGrid').innerHTML = result.html.replaceAll('>null<', '> <'); | ||||||
|  |         if (_windowLocationHRef.indexOf('=WSJF') === -1) { | ||||||
|  |             document.getElementById('AllTextarea').value = result.text.replaceAll('null', '').replaceAll(' ', '') + result.http; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             _toggle = !_toggle; | ||||||
|  |             $('.select').hide(); | ||||||
|  |             $('#AllTextarea').hide(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     $('#toggle').click(function () { | ||||||
|         if (_toggle) |         if (_toggle) | ||||||
|             $(".select").hide(); |             $('.select').hide(); | ||||||
|         else |         else | ||||||
|             $(".select").show(); |             $('.select').show(); | ||||||
|         _toggle = !_toggle; |         _toggle = !_toggle; | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function highlight(el, i) { | function highlight(el, i) { | ||||||
|     el.before("<tr/>") |     el.before('<tr/>') | ||||||
|     el.prev() |     el.prev() | ||||||
|         .width(el.width()) |         .width(el.width()) | ||||||
|         .height(el.height()) |         .height(el.height()) | ||||||
|         .css({ |         .css({ | ||||||
|             "position": "absolute", |             'position': 'absolute', | ||||||
|             "background-color": "#ffff99", |             'background-color': '#ffff99', | ||||||
|             "opacity": ".9" |             'opacity': '.9' | ||||||
|         }) |         }) | ||||||
|         .fadeOut(1000 * i); |         .fadeOut(1000 * i); | ||||||
| } | } | ||||||
| @ -423,9 +485,9 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|         aggregation = workItem.Effort; |         aggregation = workItem.Effort; | ||||||
|     } |     } | ||||||
|     if (x == undefined) |     if (x == undefined) | ||||||
|         warn("Error with page!"); |         warn('Error with page!'); | ||||||
|     else if (aggregation.FibonacciAverage == undefined) |     else if (aggregation.FibonacciAverage == undefined) | ||||||
|         warn("FibonacciAverage not set!"); |         warn('FibonacciAverage not set!'); | ||||||
|     else { |     else { | ||||||
|         $('#' + x.page + workItem.Id).text('!' + round(aggregation.FibonacciAverage, 100)); |         $('#' + x.page + workItem.Id).text('!' + round(aggregation.FibonacciAverage, 100)); | ||||||
|         if (workItem.WeightedShortestJobFirst != undefined) { |         if (workItem.WeightedShortestJobFirst != undefined) { | ||||||
| @ -437,7 +499,7 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|             if (_windowLocationHRef.indexOf('=LIVE') > -1) { |             if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||||
|                 if (workItem.SortBeforeId != undefined) { |                 if (workItem.SortBeforeId != undefined) { | ||||||
|                     let found = 0; |                     let found = 0; | ||||||
|                     let row = element.parents("tr:first"); |                     let row = element.parents('tr:first'); | ||||||
|                     let next = row; |                     let next = row; | ||||||
|                     for (let i = 0; i < 150; i++) { |                     for (let i = 0; i < 150; i++) { | ||||||
|                         next = next.next(); |                         next = next.next(); | ||||||
| @ -445,7 +507,7 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|                             break; |                             break; | ||||||
|                         if (next.attr('id') != 'tr' + workItem.SortBeforeId) |                         if (next.attr('id') != 'tr' + workItem.SortBeforeId) | ||||||
|                             continue; |                             continue; | ||||||
|                         console.log("Moved " + i + " down"); |                         console.log('Moved ' + i + ' down'); | ||||||
|                         row.insertAfter(next); |                         row.insertAfter(next); | ||||||
|                         found = i; |                         found = i; | ||||||
|                         break; |                         break; | ||||||
| @ -458,7 +520,7 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|                                 break; |                                 break; | ||||||
|                             if (prev.attr('id') != 'tr' + workItem.SortBeforeId) |                             if (prev.attr('id') != 'tr' + workItem.SortBeforeId) | ||||||
|                                 continue; |                                 continue; | ||||||
|                             console.log("Moved " + i + " up"); |                             console.log('Moved ' + i + ' up'); | ||||||
|                             row.insertAfter(prev); |                             row.insertAfter(prev); | ||||||
|                             found = i; |                             found = i; | ||||||
|                             break; |                             break; | ||||||
| @ -468,7 +530,7 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|                         highlight(row, found); |                         highlight(row, found); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         console.log("Not found!"); |                         console.log('Not found!'); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -519,7 +581,7 @@ function initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, | |||||||
|         console.log(r); |         console.log(r); | ||||||
|         console.log(t); |         console.log(t); | ||||||
|         console.log(c); |         console.log(c); | ||||||
|         console.log("Done :)"); |         console.log('Done :)'); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         updateSite(c, w); |         updateSite(c, w); | ||||||
| @ -550,40 +612,40 @@ if (typeof document == 'undefined') { | |||||||
|         timeout: 3000, |         timeout: 3000, | ||||||
|     }; |     }; | ||||||
|     const b = { |     const b = { | ||||||
|         page: "business", |         page: 'business', | ||||||
|         description: "Value", |         description: 'Value', | ||||||
|         th: "Business 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?" |         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 = { |     const r = { | ||||||
|         page: "risk", |         page: 'risk', | ||||||
|         description: "Risk", |         description: 'Risk', | ||||||
|         th: "Risk Reduction and/or Opportunity Enablement", |         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?" |         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 = { |     const t = { | ||||||
|         page: "time", |         page: 'time', | ||||||
|         description: "Critical", |         description: 'Critical', | ||||||
|         th: "Time Criticality", |         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?" |         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 = { |     const c = { | ||||||
|         page: "cod", |         page: 'cod', | ||||||
|         description: "CoD", |         description: 'CoD', | ||||||
|         th: "Cost of Delay (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." |         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 = { |     const e = { | ||||||
|         page: "effort", |         page: 'effort', | ||||||
|         description: "Effort", |         description: 'Effort', | ||||||
|         th: "Effort", |         th: 'Effort', | ||||||
|         span: "Effort" |         span: 'Effort' | ||||||
|     }; |     }; | ||||||
|     const w = { |     const w = { | ||||||
|         page: "wsjf", |         page: 'wsjf', | ||||||
|         description: "WSJF", |         description: 'WSJF', | ||||||
|         th: "Weightest Shortest Job First calculation (WSJF)", |         th: 'Weightest Shortest Job First calculation (WSJF)', | ||||||
|         span: "Weightest Shortest Job First calculation (see @SCALE formula)" |         span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||||
|     }; |     }; | ||||||
|     _windowLocationHRef = windowLocationHRef; |     _windowLocationHRef = windowLocationHRef; | ||||||
|     fetch(workItems.b, { _: new Date().getTime() }) |     fetch(workItems.b, { _: new Date().getTime() }) | ||||||
| @ -597,7 +659,8 @@ if (typeof document == 'undefined') { | |||||||
|                     if (dataA.length > 0) |                     if (dataA.length > 0) | ||||||
|                         console.log(dataA[0]); |                         console.log(dataA[0]); | ||||||
|                     const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); |                     const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||||
|                     setRecords(fromHtml, b, r, t, c, e, w, records); |                     let result = getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records); | ||||||
|  |                     if (result == undefined) { } | ||||||
|                     initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); |                     initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||||
|                 }) |                 }) | ||||||
|                 .catch((e) => console.error(e)); |                 .catch((e) => console.error(e)); | ||||||
|  | |||||||
| @ -41,6 +41,24 @@ stages: | |||||||
|             displayName: "Nuget Clear" |             displayName: "Nuget Clear" | ||||||
|             enabled: false |             enabled: false | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy GhostPCL Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\GhostPCL' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy LincPDFC Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\LincPDFC' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|           - script: | |           - script: | | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init |               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" |               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||||
| @ -184,6 +202,24 @@ stages: | |||||||
|             displayName: "Nuget Clear" |             displayName: "Nuget Clear" | ||||||
|             enabled: false |             enabled: false | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy GhostPCL Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\GhostPCL' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy LincPDFC Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\LincPDFC' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|           - script: | |           - script: | | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init |               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" |               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||||
|  | |||||||
| @ -478,27 +478,14 @@ public class FileRead : Properties.IFileRead | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) |     protected static void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) | ||||||
|     { |     { | ||||||
|         string directory; | #pragma warning disable CA1510 | ||||||
|         string day = $"{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; |         if (fileRead is null) | ||||||
|         string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); |             throw new ArgumentNullException(nameof(fileRead)); | ||||||
|         string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; |         if (jsonElements is null) | ||||||
|         if (!_CellInstanceConnectionName.StartsWith(_CellInstanceName) && _CellInstanceConnectionNameBase == _EquipmentType) |             throw new ArgumentNullException(nameof(jsonElements)); | ||||||
|             directory = Path.Combine(_TracePath, _EquipmentType, "Target", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); | #pragma warning restore CA1510 | ||||||
|         else |  | ||||||
|             directory = Path.Combine(_TracePath, _EquipmentType, "Source", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); |  | ||||||
|         if (!Directory.Exists(directory)) |  | ||||||
|             _ = Directory.CreateDirectory(directory); |  | ||||||
|         string file = Path.Combine(directory, string.Concat(_Logistics.MesEntity, "_", _Logistics.Sequence, ".ipdsf")); |  | ||||||
|         string lines = ProcessDataStandardFormat.GetPDSFText(fileRead, _Logistics, jsonElements, logisticsText: string.Empty); |  | ||||||
|         File.WriteAllText(file, lines); |  | ||||||
|         if (_Logistics.TotalSecondsSinceLastWriteTimeFromSequence > 600) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { File.SetLastWriteTime(file, _Logistics.DateTimeFromSequence); } |  | ||||||
|             catch (Exception) { } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected void WaitForThread(Thread thread, List<Exception> threadExceptions) |     protected void WaitForThread(Thread thread, List<Exception> threadExceptions) | ||||||
|  | |||||||
| @ -136,6 +136,7 @@ internal class ProcessDataStandardFormat | |||||||
|     internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, string[]? lines = null, int columnsLine = 6) |     internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, string[]? lines = null, int columnsLine = 6) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormat result; |         ProcessDataStandardFormat result; | ||||||
|  |         long? sequence; | ||||||
|         string segment; |         string segment; | ||||||
|         string[] segments; |         string[] segments; | ||||||
|         bool addToFooter = false; |         bool addToFooter = false; | ||||||
| @ -186,13 +187,25 @@ internal class ProcessDataStandardFormat | |||||||
|         } |         } | ||||||
|         string? linesOne = lines.Length > 0 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; |         string? linesOne = lines.Length > 0 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; | ||||||
|         logistics = GetLogistics(footer, linesOne: linesOne); |         logistics = GetLogistics(footer, linesOne: linesOne); | ||||||
|  |         if (logistics.Count == 0) | ||||||
|  |             sequence = null; | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); | ||||||
|  |             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? null : s; | ||||||
|  |         } | ||||||
|  |         if (sequence is null && !string.IsNullOrEmpty(reportFullPath)) | ||||||
|  |         { | ||||||
|  |             FileInfo fileInfo = new(reportFullPath); | ||||||
|  |             sequence = fileInfo.LastWriteTime.Ticks; | ||||||
|  |         } | ||||||
|         result = new(body: body.AsReadOnly(), |         result = new(body: body.AsReadOnly(), | ||||||
|                      columns: columns.AsReadOnly(), |                      columns: columns.AsReadOnly(), | ||||||
|                      footer: footer.AsReadOnly(), |                      footer: footer.AsReadOnly(), | ||||||
|                      header: header.AsReadOnly(), |                      header: header.AsReadOnly(), | ||||||
|                      inputPDSF: null, |                      inputPDSF: null, | ||||||
|                      logistics: logistics, |                      logistics: logistics, | ||||||
|                      sequence: null); |                      sequence: sequence); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -236,7 +249,7 @@ internal class ProcessDataStandardFormat | |||||||
|     private static ProcessDataStandardFormat GetProcessDataStandardFormat(DateTime lastWriteTime, int columnsLine, string path, string[]? lines) |     private static ProcessDataStandardFormat GetProcessDataStandardFormat(DateTime lastWriteTime, int columnsLine, string path, string[]? lines) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormat result; |         ProcessDataStandardFormat result; | ||||||
|         long sequence; |         long? sequence; | ||||||
|         string[] segments; |         string[] segments; | ||||||
|         bool addToFooter = false; |         bool addToFooter = false; | ||||||
|         List<string> body = new(); |         List<string> body = new(); | ||||||
| @ -268,12 +281,13 @@ internal class ProcessDataStandardFormat | |||||||
|         } |         } | ||||||
|         logistics = GetLogistics(footer, linesOne: null); |         logistics = GetLogistics(footer, linesOne: null); | ||||||
|         if (logistics.Count == 0) |         if (logistics.Count == 0) | ||||||
|             sequence = lastWriteTime.Ticks; |             sequence = null; | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); |             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); | ||||||
|             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s; |             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? null : s; | ||||||
|         } |         } | ||||||
|  |         sequence ??= lastWriteTime.Ticks; | ||||||
|         result = new(body: body.AsReadOnly(), |         result = new(body: body.AsReadOnly(), | ||||||
|                      columns: new(columns), |                      columns: new(columns), | ||||||
|                      footer: footer.AsReadOnly(), |                      footer: footer.AsReadOnly(), | ||||||
| @ -302,7 +316,7 @@ internal class ProcessDataStandardFormat | |||||||
|                 segments = bodyLine.Split('\t').ToList(); |                 segments = bodyLine.Split('\t').ToList(); | ||||||
|                 for (int c = 0; c < segments.Count; c++) |                 for (int c = 0; c < segments.Count; c++) | ||||||
|                 { |                 { | ||||||
|                     value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                     value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                     _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); |                     _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); | ||||||
|                 } |                 } | ||||||
|                 _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); |                 _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); | ||||||
| @ -378,12 +392,19 @@ internal class ProcessDataStandardFormat | |||||||
|                 break; |                 break; | ||||||
|             for (int c = 0; c < segments.Length; c++) |             for (int c = 0; c < segments.Length; c++) | ||||||
|             { |             { | ||||||
|                 value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                 value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                 line += string.Concat('"', processDataStandardFormat.InputPDSF.Columns[c].Trim('"'), '"', ':', '"', value, '"', ','); |                 line += string.Concat('"', processDataStandardFormat.InputPDSF.Columns[c].Trim('"'), '"', ':', '"', value, '"', ','); | ||||||
|             } |             } | ||||||
|             line = string.Concat(line.Substring(0, line.Length - 1), '}'); |             line = string.Concat(line.Substring(0, line.Length - 1), '}'); | ||||||
|             lines.Add(line); |             lines.Add(line); | ||||||
|         } |         } | ||||||
|  |         string? json = null; | ||||||
|  |         if (processDataStandardFormat.Footer is not null && processDataStandardFormat.Footer.Count > 0) { | ||||||
|  |             Dictionary<string, string> footerKeyValuePairs = GetFooterKeyValuePairs(processDataStandardFormat.Footer); | ||||||
|  |             Dictionary<string, Dictionary<string, string>> logisticKeyValuePairs = GetLogisticKeyValuePairs(processDataStandardFormat.Footer, footerKeyValuePairs); | ||||||
|  |             json = JsonSerializer.Serialize(logisticKeyValuePairs, DictionaryStringDictionaryStringStringSourceGenerationContext.Default.DictionaryStringDictionaryStringString); | ||||||
|  |         } | ||||||
|  |         string footerText = string.IsNullOrEmpty(json) || json == "{}" ? string.Empty : $",{Environment.NewLine}\"PDSF\":{Environment.NewLine}{json}"; | ||||||
|         result = string.Concat( |         result = string.Concat( | ||||||
|             '{', |             '{', | ||||||
|             Environment.NewLine, |             Environment.NewLine, | ||||||
| @ -412,9 +433,64 @@ internal class ProcessDataStandardFormat | |||||||
|             ": ", |             ": ", | ||||||
|             processDataStandardFormat.Sequence, |             processDataStandardFormat.Sequence, | ||||||
|             Environment.NewLine, |             Environment.NewLine, | ||||||
|  |             footerText, | ||||||
|  |             Environment.NewLine, | ||||||
|             '}'); |             '}'); | ||||||
|         return result; |         return result; | ||||||
| #pragma warning restore CA1845, IDE0057 |     } | ||||||
|  |  | ||||||
|  |     private static Dictionary<string, string> GetFooterKeyValuePairs(ReadOnlyCollection<string> footerLines) { | ||||||
|  |         Dictionary<string, string> results = new(); | ||||||
|  |         string[] segments; | ||||||
|  |         foreach (string footerLine in footerLines) { | ||||||
|  |             segments = footerLine.Split('\t'); | ||||||
|  |             if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (segments[1].Contains(';')) { | ||||||
|  |                 continue; | ||||||
|  |             } else { | ||||||
|  |                 results.Add(segments[0], segments[1]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return results; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Dictionary<string, Dictionary<string, string>> GetLogisticKeyValuePairs(ReadOnlyCollection<string> footerLines, Dictionary<string, string> footerKeyValuePairs) { | ||||||
|  |         Dictionary<string, Dictionary<string, string>> results = new(); | ||||||
|  |         string[] segments; | ||||||
|  |         string[] subSegments; | ||||||
|  |         string[] subSubSegments; | ||||||
|  |         Dictionary<string, string>? keyValue; | ||||||
|  |         results.Add("Footer", footerKeyValuePairs); | ||||||
|  |         foreach (string footerLine in footerLines) { | ||||||
|  |             segments = footerLine.Split('\t'); | ||||||
|  |             if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (!segments[1].Contains(';') || !segments[1].Contains('=')) { | ||||||
|  |                 continue; | ||||||
|  |             } else { | ||||||
|  |                 subSegments = segments[1].Split(';'); | ||||||
|  |                 if (subSegments.Length < 1) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 if (!results.TryGetValue(segments[0], out keyValue)) { | ||||||
|  |                     results.Add(segments[0], new()); | ||||||
|  |                     if (!results.TryGetValue(segments[0], out keyValue)) { | ||||||
|  |                         throw new Exception(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 foreach (string segment in subSegments) { | ||||||
|  |                     subSubSegments = segment.Split('='); | ||||||
|  |                     if (subSubSegments.Length != 2) { | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                     keyValue.Add(subSubSegments[0], subSubSegments[1]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal static void Write(string path, ProcessDataStandardFormat processDataStandardFormat, List<Metrology.WS.Results>? wsResults) |     internal static void Write(string path, ProcessDataStandardFormat processDataStandardFormat, List<Metrology.WS.Results>? wsResults) | ||||||
| @ -518,7 +594,7 @@ internal class ProcessDataStandardFormat | |||||||
|                 { |                 { | ||||||
|                     for (int c = 1; c < segments.Length; c++) |                     for (int c = 1; c < segments.Length; c++) | ||||||
|                     { |                     { | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                         value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                         _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); |                         _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @ -526,7 +602,7 @@ internal class ProcessDataStandardFormat | |||||||
|                 { |                 { | ||||||
|                     for (int c = 1; c < segments.Length; c++) |                     for (int c = 1; c < segments.Length; c++) | ||||||
|                     { |                     { | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                         value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                         if (string.IsNullOrEmpty(value)) |                         if (string.IsNullOrEmpty(value)) | ||||||
|                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); |                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); | ||||||
|                         else if (value.All(char.IsDigit)) |                         else if (value.All(char.IsDigit)) | ||||||
| @ -764,3 +840,8 @@ internal class ProcessDataStandardFormat | |||||||
| internal partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext | internal partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | [JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] | ||||||
|  | [JsonSerializable(typeof(Dictionary<string, Dictionary<string, string>>))] | ||||||
|  | internal partial class DictionaryStringDictionaryStringStringSourceGenerationContext : JsonSerializerContext { | ||||||
|  | } | ||||||
| @ -1,4 +1,14 @@ | |||||||
| { | { | ||||||
|  |     "name": "adaptation", | ||||||
|  |     "module": "index.ts", | ||||||
|  |     "type": "module", | ||||||
|  |     "private": true, | ||||||
|  |     "devDependencies": { | ||||||
|  |         "@types/bun": "latest" | ||||||
|  |     }, | ||||||
|  |     "peerDependencies": { | ||||||
|  |         "typescript": "^5" | ||||||
|  |     }, | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "AA-CreateSelfDescription.Staging.v2_43_0-BACKLOG_EQPT": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG_EQPT\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", |         "AA-CreateSelfDescription.Staging.v2_43_0-BACKLOG_EQPT": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG_EQPT\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", | ||||||
|         "BA-CreateSelfDescription.Staging.v2_43_0-BACKLOG": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", |         "BA-CreateSelfDescription.Staging.v2_43_0-BACKLOG": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								Adaptation/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Adaptation/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     // Environment setup & latest features | ||||||
|  |     "lib": ["ESNext"], | ||||||
|  |     "target": "ESNext", | ||||||
|  |     "module": "Preserve", | ||||||
|  |     "moduleDetection": "force", | ||||||
|  |     "jsx": "react-jsx", | ||||||
|  |     "allowJs": true, | ||||||
|  |  | ||||||
|  |     // Bundler mode | ||||||
|  |     "moduleResolution": "bundler", | ||||||
|  |     "allowImportingTsExtensions": true, | ||||||
|  |     "verbatimModuleSyntax": true, | ||||||
|  |     "noEmit": true, | ||||||
|  |  | ||||||
|  |     // Best practices | ||||||
|  |     "strict": true, | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     "noFallthroughCasesInSwitch": true, | ||||||
|  |     "noUncheckedIndexedAccess": true, | ||||||
|  |     "noImplicitOverride": true, | ||||||
|  |  | ||||||
|  |     // Some stricter flags (disabled by default) | ||||||
|  |     "noUnusedLocals": false, | ||||||
|  |     "noUnusedParameters": false, | ||||||
|  |     "noPropertyAccessFromIndexSignature": false | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user