Characterization Data
FI Backlog with Ignore Tag
This commit is contained in:
parent
b824c4ba36
commit
4c2bef71ec
4
.gitignore
vendored
4
.gitignore
vendored
@ -343,4 +343,6 @@ ASALocalRun/
|
|||||||
/wwwroot/lib/*
|
/wwwroot/lib/*
|
||||||
|
|
||||||
.kanbn
|
.kanbn
|
||||||
Tests/.kanbn
|
Tests/.kanbn
|
||||||
|
|
||||||
|
/Wafer-Counter/.vscode/.UserSecrets/secrets.json
|
@ -100,4 +100,7 @@ public class FileShareRepository : IFileShareRepository
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<CharacterizationInfo> IFileShareRepository.GetArchiveData(CharacterizationParameters archiveParameters) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
}
|
}
|
5
Shared/Models/CharacterizationInfo.cs
Normal file
5
Shared/Models/CharacterizationInfo.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace OI.Metrology.Shared.Models;
|
||||||
|
|
||||||
|
public record CharacterizationInfo(string? Lot,
|
||||||
|
DateTime LastWriteTime,
|
||||||
|
string[] Lines);
|
16
Shared/Models/CharacterizationParameters.cs
Normal file
16
Shared/Models/CharacterizationParameters.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace OI.Metrology.Shared.Models;
|
||||||
|
|
||||||
|
public record CharacterizationParameters([property: JsonPropertyName("area")] string? Area,
|
||||||
|
[property: JsonPropertyName("equipment-id")] string? EquipmentId,
|
||||||
|
[property: JsonPropertyName("search-pattern")] string? SearchPattern,
|
||||||
|
[property: JsonPropertyName("start-time")] string? StartTime,
|
||||||
|
[property: JsonPropertyName("end-time")] string? EndTime,
|
||||||
|
[property: JsonPropertyName("wafer-size")] string? WaferSize);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(CharacterizationParameters))]
|
||||||
|
public partial class CharacterizationParametersSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -10,6 +10,6 @@ public interface IFileShareRepository
|
|||||||
HttpResponseMessage ReadFile(HttpClient httpClient, Uri uri);
|
HttpResponseMessage ReadFile(HttpClient httpClient, Uri uri);
|
||||||
void CopyFile(HttpClient httpClient, string from, string to);
|
void CopyFile(HttpClient httpClient, string from, string to);
|
||||||
void MoveFile(HttpClient httpClient, string from, string to);
|
void MoveFile(HttpClient httpClient, string from, string to);
|
||||||
|
List<CharacterizationInfo> GetArchiveData(CharacterizationParameters characterizationParameters);
|
||||||
List<NginxFileSystemSortable> GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith);
|
List<NginxFileSystemSortable> GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith);
|
||||||
|
|
||||||
}
|
}
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html" class="alert-info">Export</a></li>
|
<li><a href="/export.html" class="alert-info">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
161
Static/js/leo.js
Normal file
161
Static/js/leo.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
function compareFunction(a, b) {
|
||||||
|
return a.Priority[0] - b.Priority[0] || a.TimeCriticality[0] - b.TimeCriticality[0] || b.State[0] - a.State[0] || a.Id - b.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOne(rowData) {
|
||||||
|
if (rowData == null)
|
||||||
|
return;
|
||||||
|
var data = [];
|
||||||
|
data.push({ name: "ADO Edit", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">' + rowData["Id"] + '</a>' });
|
||||||
|
for (const property in rowData) {
|
||||||
|
if (rowData[property] == null)
|
||||||
|
continue;
|
||||||
|
data.push({ name: property, value: rowData[property].toString() });
|
||||||
|
}
|
||||||
|
$("#AllGrid").igGrid({
|
||||||
|
autoGenerateColumns: true,
|
||||||
|
dataSource: data,
|
||||||
|
width: "100%",
|
||||||
|
showHeader: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadOne() {
|
||||||
|
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||||
|
if (selectedRow == null)
|
||||||
|
return;
|
||||||
|
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||||
|
showOne(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function detailSelectionChangedRunInfo(evt, ui) {
|
||||||
|
if (ui.row.index === 0)
|
||||||
|
return;
|
||||||
|
var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index];
|
||||||
|
showOne(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getState(state) {
|
||||||
|
var result;
|
||||||
|
if (state == null)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (state === "New")
|
||||||
|
result = `1-${state}`;
|
||||||
|
else if (state === "Active")
|
||||||
|
result = `2-${state}`;
|
||||||
|
else if (state === "Resolved")
|
||||||
|
result = `3-${state}`;
|
||||||
|
else if (state === "Closed")
|
||||||
|
result = `4-${state}`;
|
||||||
|
else if (state === "Removed")
|
||||||
|
result = `5-${state}`;
|
||||||
|
else
|
||||||
|
result = `8-${state}`;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPriority(workItemType, priority) {
|
||||||
|
var result;
|
||||||
|
if (workItemType === "Bug")
|
||||||
|
result = "0-Bug";
|
||||||
|
else if (priority == null || priority === 0)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (priority === 1)
|
||||||
|
result = `${priority}-High`;
|
||||||
|
else if (priority === 2)
|
||||||
|
result = `${priority}-Med`;
|
||||||
|
else if (priority === 3)
|
||||||
|
result = `${priority}-Low`;
|
||||||
|
else if (priority === 4)
|
||||||
|
result = `${priority}-TBD`;
|
||||||
|
else
|
||||||
|
result = "8-Not";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimeCriticality(workItemType, timeCriticality) {
|
||||||
|
var result;
|
||||||
|
if (workItemType === "Bug")
|
||||||
|
result = "0-Bug";
|
||||||
|
else if (timeCriticality == null || timeCriticality === 0)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (timeCriticality === 1)
|
||||||
|
result = `${timeCriticality}-QSM`;
|
||||||
|
else if (timeCriticality === 2)
|
||||||
|
result = `${timeCriticality}-Qual`;
|
||||||
|
else if (timeCriticality === 3)
|
||||||
|
result = `${timeCriticality}-Eff`;
|
||||||
|
else
|
||||||
|
result = "8-Not";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkItems(data) {
|
||||||
|
var workItems = [];
|
||||||
|
var workItem;
|
||||||
|
for (var i = data.length - 1; i > -1; i--) {
|
||||||
|
workItem = data[i];
|
||||||
|
if (workItem.AreaPath !== 'ART SPS\\LEO')
|
||||||
|
continue;
|
||||||
|
if (workItem.Tags != null && workItem.Tags.includes("Ignore"))
|
||||||
|
continue;
|
||||||
|
if (workItem.WorkItemType !== 'Feature' && workItem.WorkItemType !== 'Bug')
|
||||||
|
continue;
|
||||||
|
workItem["State"] = getState(workItem["State"])
|
||||||
|
workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"])
|
||||||
|
workItem["TimeCriticality"] = getTimeCriticality(workItem["WorkItemType"], workItem["TimeCriticality"])
|
||||||
|
workItems.push(workItem);
|
||||||
|
}
|
||||||
|
workItems.sort(compareFunction);
|
||||||
|
return workItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initIndex(url) {
|
||||||
|
$.getJSON(url, { _: new Date().getTime() }, function (data) {
|
||||||
|
var workItems = getWorkItems(data);
|
||||||
|
console.log(data.length);
|
||||||
|
if (data.length > 0)
|
||||||
|
console.log(data[0]);
|
||||||
|
$("#HeaderGrid").igGrid({
|
||||||
|
autoGenerateColumns: false,
|
||||||
|
dataSource: workItems,
|
||||||
|
height: "100%",
|
||||||
|
primaryKey: "Id",
|
||||||
|
width: "100%",
|
||||||
|
columns: [
|
||||||
|
{ key: "Id", dataType: "number" },
|
||||||
|
{ key: "Requester", dataType: "string" },
|
||||||
|
{ headerText: "Assigned To", key: "AssignedTo", dataType: "string" },
|
||||||
|
{ key: "Title", dataType: "string", width: "20%" },
|
||||||
|
{ headerText: "System(s)", key: "Tags", dataType: "string" },
|
||||||
|
{ key: "Priority", dataType: "string" },
|
||||||
|
{ headerText: "Qual/Eff", key: "TimeCriticality", dataType: "string" },
|
||||||
|
{ key: "State", dataType: "string" },
|
||||||
|
{ headerText: "Effort in Days", key: "Effort", dataType: "number" },
|
||||||
|
{ headerText: "UAT as of", key: "ResolvedDate", dataType: "date", format: "date" },
|
||||||
|
{ headerText: "CMP Date", key: "ClosedDate", dataType: "date", format: "date" },
|
||||||
|
{ headerText: "Target", key: "TargetDate", dataType: "date", format: "date" },
|
||||||
|
{ key: "AreaPath", dataType: "string", hidden: true },
|
||||||
|
{ key: "AssignedTo", dataType: "string", hidden: true },
|
||||||
|
{ key: "BusinessValue", dataType: "number", hidden: true },
|
||||||
|
{ key: "ChangedDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "CommentCount", dataType: "number", hidden: true },
|
||||||
|
{ key: "CreatedDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "Description", dataType: "string", hidden: true },
|
||||||
|
{ key: "IterationPath", dataType: "string", hidden: true },
|
||||||
|
{ key: "Revision", dataType: "number", hidden: true },
|
||||||
|
{ key: "RiskReductionMinusOpportunityEnablement", dataType: "string", hidden: true },
|
||||||
|
{ key: "StartDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "WorkItemType", dataType: "string", hidden: true },
|
||||||
|
{ key: "WeightedShortestJobFirst", dataType: "number", hidden: true },
|
||||||
|
],
|
||||||
|
features: [
|
||||||
|
{ name: "Sorting", type: "local" },
|
||||||
|
{ name: "Filtering", type: "local" },
|
||||||
|
{ name: "Selection", mode: "row", multipleSelection: false, rowSelectionChanging: detailSelectionChangedRunInfo },
|
||||||
|
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 10, pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page", showPageSizeDropDown: true },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#HeaderGrid").on("dblclick", "tr", loadOne);
|
||||||
|
}
|
161
Static/js/mes.js
Normal file
161
Static/js/mes.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
function compareFunction(a, b) {
|
||||||
|
return a.Priority[0] - b.Priority[0] || a.TimeCriticality[0] - b.TimeCriticality[0] || b.State[0] - a.State[0] || a.Id - b.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOne(rowData) {
|
||||||
|
if (rowData == null)
|
||||||
|
return;
|
||||||
|
var data = [];
|
||||||
|
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||||
|
for (const property in rowData) {
|
||||||
|
if (rowData[property] == null)
|
||||||
|
continue;
|
||||||
|
data.push({ name: property, value: rowData[property].toString() });
|
||||||
|
}
|
||||||
|
$("#AllGrid").igGrid({
|
||||||
|
autoGenerateColumns: true,
|
||||||
|
dataSource: data,
|
||||||
|
width: "100%",
|
||||||
|
showHeader: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadOne() {
|
||||||
|
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||||
|
if (selectedRow == null)
|
||||||
|
return;
|
||||||
|
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||||
|
showOne(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function detailSelectionChangedRunInfo(evt, ui) {
|
||||||
|
if (ui.row.index === 0)
|
||||||
|
return;
|
||||||
|
var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index];
|
||||||
|
showOne(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getState(state) {
|
||||||
|
var result;
|
||||||
|
if (state == null)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (state === "New")
|
||||||
|
result = `1-${state}`;
|
||||||
|
else if (state === "Active")
|
||||||
|
result = `2-${state}`;
|
||||||
|
else if (state === "Resolved")
|
||||||
|
result = `3-${state}`;
|
||||||
|
else if (state === "Closed")
|
||||||
|
result = `4-${state}`;
|
||||||
|
else if (state === "Removed")
|
||||||
|
result = `5-${state}`;
|
||||||
|
else
|
||||||
|
result = `8-${state}`;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPriority(workItemType, priority) {
|
||||||
|
var result;
|
||||||
|
if (workItemType === "Bug")
|
||||||
|
result = "0-Bug";
|
||||||
|
else if (priority == null || priority === 0)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (priority === 1)
|
||||||
|
result = `${priority}-High`;
|
||||||
|
else if (priority === 2)
|
||||||
|
result = `${priority}-Med`;
|
||||||
|
else if (priority === 3)
|
||||||
|
result = `${priority}-Low`;
|
||||||
|
else if (priority === 4)
|
||||||
|
result = `${priority}-TBD`;
|
||||||
|
else
|
||||||
|
result = "8-Not";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimeCriticality(workItemType, timeCriticality) {
|
||||||
|
var result;
|
||||||
|
if (workItemType === "Bug")
|
||||||
|
result = "0-Bug";
|
||||||
|
else if (timeCriticality == null || timeCriticality === 0)
|
||||||
|
result = "9-Null";
|
||||||
|
else if (timeCriticality === 1)
|
||||||
|
result = `${timeCriticality}-QSM`;
|
||||||
|
else if (timeCriticality === 2)
|
||||||
|
result = `${timeCriticality}-Qual`;
|
||||||
|
else if (timeCriticality === 3)
|
||||||
|
result = `${timeCriticality}-Eff`;
|
||||||
|
else
|
||||||
|
result = "8-Not";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkItems(data) {
|
||||||
|
var workItems = [];
|
||||||
|
var workItem;
|
||||||
|
for (var i = data.length - 1; i > -1; i--) {
|
||||||
|
workItem = data[i];
|
||||||
|
if (workItem.AreaPath !== 'ART SPS\\MES')
|
||||||
|
continue;
|
||||||
|
if (workItem.Tags != null && workItem.Tags.includes("Ignore"))
|
||||||
|
continue;
|
||||||
|
if (workItem.WorkItemType !== 'Feature' && workItem.WorkItemType !== 'Bug')
|
||||||
|
continue;
|
||||||
|
workItem["State"] = getState(workItem["State"])
|
||||||
|
workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"])
|
||||||
|
workItem["TimeCriticality"] = getTimeCriticality(workItem["WorkItemType"], workItem["TimeCriticality"])
|
||||||
|
workItems.push(workItem);
|
||||||
|
}
|
||||||
|
workItems.sort(compareFunction);
|
||||||
|
return workItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initIndex(url) {
|
||||||
|
$.getJSON(url, { _: new Date().getTime() }, function (data) {
|
||||||
|
var workItems = getWorkItems(data);
|
||||||
|
console.log(data.length);
|
||||||
|
if (data.length > 0)
|
||||||
|
console.log(data[0]);
|
||||||
|
$("#HeaderGrid").igGrid({
|
||||||
|
autoGenerateColumns: false,
|
||||||
|
dataSource: workItems,
|
||||||
|
height: "100%",
|
||||||
|
primaryKey: "Id",
|
||||||
|
width: "100%",
|
||||||
|
columns: [
|
||||||
|
{ key: "Id", dataType: "number" },
|
||||||
|
{ key: "Requester", dataType: "string" },
|
||||||
|
{ headerText: "Assigned To", key: "AssignedTo", dataType: "string" },
|
||||||
|
{ key: "Title", dataType: "string", width: "20%" },
|
||||||
|
{ headerText: "System(s)", key: "Tags", dataType: "string" },
|
||||||
|
{ key: "Priority", dataType: "string" },
|
||||||
|
{ headerText: "Qual/Eff", key: "TimeCriticality", dataType: "string" },
|
||||||
|
{ key: "State", dataType: "string" },
|
||||||
|
{ headerText: "Effort in Days", key: "Effort", dataType: "number" },
|
||||||
|
{ headerText: "UAT as of", key: "ResolvedDate", dataType: "date", format: "date" },
|
||||||
|
{ headerText: "CMP Date", key: "ClosedDate", dataType: "date", format: "date" },
|
||||||
|
{ headerText: "Target", key: "TargetDate", dataType: "date", format: "date" },
|
||||||
|
{ key: "AreaPath", dataType: "string", hidden: true },
|
||||||
|
{ key: "AssignedTo", dataType: "string", hidden: true },
|
||||||
|
{ key: "BusinessValue", dataType: "number", hidden: true },
|
||||||
|
{ key: "ChangedDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "CommentCount", dataType: "number", hidden: true },
|
||||||
|
{ key: "CreatedDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "Description", dataType: "string", hidden: true },
|
||||||
|
{ key: "IterationPath", dataType: "string", hidden: true },
|
||||||
|
{ key: "Revision", dataType: "number", hidden: true },
|
||||||
|
{ key: "RiskReductionMinusOpportunityEnablement", dataType: "string", hidden: true },
|
||||||
|
{ key: "StartDate", dataType: "string", hidden: true },
|
||||||
|
{ key: "WorkItemType", dataType: "string", hidden: true },
|
||||||
|
{ key: "WeightedShortestJobFirst", dataType: "number", hidden: true },
|
||||||
|
],
|
||||||
|
features: [
|
||||||
|
{ name: "Sorting", type: "local" },
|
||||||
|
{ name: "Filtering", type: "local" },
|
||||||
|
{ name: "Selection", mode: "row", multipleSelection: false, rowSelectionChanging: detailSelectionChangedRunInfo },
|
||||||
|
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 10, pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page", showPageSizeDropDown: true },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#HeaderGrid").on("dblclick", "tr", loadOne);
|
||||||
|
}
|
43
Static/leo.html
Normal file
43
Static/leo.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>FI Backlog HiRel (Leominster)</title>
|
||||||
|
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-09-07-08-19" rel="stylesheet" />
|
||||||
|
<link href="/igniteui/css/structure/infragistics.css?v=2024-09-07-08-19" rel="stylesheet" />
|
||||||
|
<script src="/js/jquery-3.6.0.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/js/jquery-ui.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/js/leo.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.core.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.lob.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.dv.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="float: right;">
|
||||||
|
<a target="_blank" href="/json/Feature.html">Feature(s)</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>FI Backlog HiRel (Leominster)</h2>
|
||||||
|
|
||||||
|
<div style="height: 550px;" id="HeaderGridDiv">
|
||||||
|
<table id="HeaderGrid"></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div id="AllGridDiv">
|
||||||
|
<table id="AllGrid"></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
initIndex("/json/work-items.json?v=2024-09-07-08-19");
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
43
Static/mes.html
Normal file
43
Static/mes.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>FI Backlog Mesa</title>
|
||||||
|
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-09-07-08-19" rel="stylesheet" />
|
||||||
|
<link href="/igniteui/css/structure/infragistics.css?v=2024-09-07-08-19" rel="stylesheet" />
|
||||||
|
<script src="/js/jquery-3.6.0.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/js/jquery-ui.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/js/mes.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.core.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.lob.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
<script src="/igniteui/js/infragistics.dv.js?v=2024-09-07-08-19" type="text/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="float: right;">
|
||||||
|
<a target="_blank" href="/json/Feature.html">Feature(s)</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>FI Backlog Mesa</h2>
|
||||||
|
|
||||||
|
<div style="height: 550px;" id="HeaderGridDiv">
|
||||||
|
<table id="HeaderGrid"></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div id="AllGridDiv">
|
||||||
|
<table id="AllGrid"></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
initIndex("/json/work-items.json?v=2024-09-07-08-19");
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -50,6 +50,7 @@
|
|||||||
<li><a href="/export.html">Export</a></li>
|
<li><a href="/export.html">Export</a></li>
|
||||||
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
<li><a href="https://oi-metrology-viewer-archive.mes.infineon.com/" target="_blank">Archive</a></li>
|
||||||
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
<li><a href="https://goto.infineon.com/oiwizard" target="_blank">OI Web Services</a></li>
|
||||||
|
<li><a href="/mes.html" target="_blank">FI Backlog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="navbar-text navbar-right">
|
<p class="navbar-text navbar-right">
|
||||||
|
|
||||||
|
@ -26,19 +26,20 @@
|
|||||||
<DefineConstants>Linux</DefineConstants>
|
<DefineConstants>Linux</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
<PackageReference Include="coverlet.collector" Version="6.0.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
<PackageReference Include="MSTest.TestAdapter" Version="3.5.2" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
<PackageReference Include="MSTest.TestFramework" Version="3.5.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />
|
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />
|
||||||
<ProjectReference Include="..\Server\OI.Metrology.Server.csproj" />
|
<ProjectReference Include="..\Server\OI.Metrology.Server.csproj" />
|
||||||
|
<ProjectReference Include="..\Wafer-Counter\OI.Metrology.Wafer.Counter.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\.Data\RdsMaxRepo.json">
|
<None Include="..\.Data\RdsMaxRepo.json">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using OI.Metrology.Shared.Models;
|
||||||
using OI.Metrology.Shared.Models.Stateless;
|
using OI.Metrology.Shared.Models.Stateless;
|
||||||
|
|
||||||
namespace OI.Metrology.Tests;
|
namespace OI.Metrology.Tests;
|
||||||
@ -14,7 +15,7 @@ public class UnitTestFileShareController
|
|||||||
private static ILogger? _Logger;
|
private static ILogger? _Logger;
|
||||||
private static string _ControllerName;
|
private static string _ControllerName;
|
||||||
private static TestContext _TestContext;
|
private static TestContext _TestContext;
|
||||||
private static WebApplicationFactory<Server.Program>? _WebApplicationFactory;
|
private static WebApplicationFactory<Wafer.Counter.Program>? _WebApplicationFactory;
|
||||||
|
|
||||||
#pragma warning restore
|
#pragma warning restore
|
||||||
|
|
||||||
@ -22,10 +23,11 @@ public class UnitTestFileShareController
|
|||||||
public static void ClassInitAsync(TestContext testContext)
|
public static void ClassInitAsync(TestContext testContext)
|
||||||
{
|
{
|
||||||
_TestContext = testContext;
|
_TestContext = testContext;
|
||||||
_WebApplicationFactory = new WebApplicationFactory<Server.Program>();
|
_WebApplicationFactory = new WebApplicationFactory<Wafer.Counter.Program>();
|
||||||
IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider;
|
IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider;
|
||||||
_Logger = serviceProvider.GetRequiredService<ILogger<Server.Program>>();
|
_Logger = serviceProvider.GetRequiredService<ILogger<Wafer.Counter.Program>>();
|
||||||
_ControllerName = nameof(Server.ApiControllers.FileShareController)[..^10];
|
// _ControllerName = nameof(Server.ApiControllers.FileShareController)[..^10];
|
||||||
|
_ControllerName = nameof(Wafer.Counter.ApiControllers.FileShareController)[..^10];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NonThrowTryCatch()
|
private static void NonThrowTryCatch()
|
||||||
@ -82,4 +84,37 @@ public class UnitTestFileShareController
|
|||||||
NonThrowTryCatch();
|
NonThrowTryCatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetArchiveData()
|
||||||
|
{
|
||||||
|
_Logger?.LogInformation("Starting Web Application");
|
||||||
|
List<CharacterizationInfo>? result;
|
||||||
|
CharacterizationParameters characterizationParameters;
|
||||||
|
IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider;
|
||||||
|
IFileShareRepository? fileShareRepository = serviceProvider?.GetRequiredService<IFileShareRepository>();
|
||||||
|
characterizationParameters = new("FQA", "FQA-8INCH", "*.wc", null, null, "8INCH");
|
||||||
|
result = fileShareRepository?.GetArchiveData(characterizationParameters);
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
characterizationParameters = new(string.Empty, "BIORAD4", "BIO*.json", null, null, "8INCH");
|
||||||
|
result = fileShareRepository?.GetArchiveData(characterizationParameters);
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
characterizationParameters = new(string.Empty, "CDE5", "CDE*.json", null, null, "8INCH");
|
||||||
|
result = fileShareRepository?.GetArchiveData(characterizationParameters);
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ArchiveDataApi()
|
||||||
|
{
|
||||||
|
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
|
||||||
|
_Logger?.LogInformation("Starting Web Application");
|
||||||
|
Assert.IsTrue(httpClient is not null);
|
||||||
|
string? response = await httpClient.GetStringAsync($"api/v1/file-share/archive-data/?area=FQA&equipment-id=FQA-8INCH&search-pattern=*.wc&wafer-size=8INCH");
|
||||||
|
Assert.IsNotNull(response);
|
||||||
|
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
74
Tests/UnitTestWaferCounterController.cs
Normal file
74
Tests/UnitTestWaferCounterController.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using OI.Metrology.Shared.DataModels;
|
||||||
|
using OI.Metrology.Shared.Models.Stateless;
|
||||||
|
|
||||||
|
namespace OI.Metrology.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class UnitTestWaferCounterController
|
||||||
|
{
|
||||||
|
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
|
||||||
|
private static ILogger? _Logger;
|
||||||
|
private static string _ControllerName;
|
||||||
|
private static TestContext _TestContext;
|
||||||
|
private static WebApplicationFactory<Wafer.Counter.Program>? _WebApplicationFactory;
|
||||||
|
|
||||||
|
#pragma warning restore
|
||||||
|
|
||||||
|
[ClassInitialize]
|
||||||
|
public static void ClassInitAsync(TestContext testContext)
|
||||||
|
{
|
||||||
|
_TestContext = testContext;
|
||||||
|
_WebApplicationFactory = new WebApplicationFactory<Wafer.Counter.Program>();
|
||||||
|
IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider;
|
||||||
|
_Logger = serviceProvider.GetRequiredService<ILogger<Wafer.Counter.Program>>();
|
||||||
|
_ControllerName = nameof(Wafer.Counter.ApiControllers.WaferCounterController)[..^10];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void NonThrowTryCatch()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{ throw new Exception(); }
|
||||||
|
catch (Exception) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestControllerName()
|
||||||
|
{
|
||||||
|
_Logger?.LogInformation("Starting Web Application");
|
||||||
|
Assert.AreEqual(IFileShareController<string>.GetRouteName(), _ControllerName);
|
||||||
|
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Ignore]
|
||||||
|
[TestMethod]
|
||||||
|
public void GetLastQuantityAndSlotMap()
|
||||||
|
{
|
||||||
|
_Logger?.LogInformation("Starting Web Application");
|
||||||
|
IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider;
|
||||||
|
IWaferCounterRepository? waferCounterRepository = serviceProvider?.GetRequiredService<IWaferCounterRepository>();
|
||||||
|
WaferCounter? result = waferCounterRepository?.GetLastQuantityAndSlotMap(area: "FQA", waferSize: "8INCH", text: "Test");
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Ignore]
|
||||||
|
[TestMethod]
|
||||||
|
public async Task LastQuantityAndSlotMapApi()
|
||||||
|
{
|
||||||
|
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
|
||||||
|
_Logger?.LogInformation("Starting Web Application");
|
||||||
|
Assert.IsTrue(httpClient is not null);
|
||||||
|
string? response = await httpClient.GetStringAsync($"api/v1/{_ControllerName}/FQA/last-quantity-and-slot-map/?waferSize=8INCH&text=Test");
|
||||||
|
Assert.IsNotNull(response);
|
||||||
|
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
Wafer-Counter/.vscode/mklink.md
vendored
Normal file
5
Wafer-Counter/.vscode/mklink.md
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# mklink
|
||||||
|
|
||||||
|
```bash Thu Aug 29 2024 09:47:22 GMT-0700 (Mountain Standard Time)
|
||||||
|
mklink /J "L:\DevOps\Mesa_FI\OI-Metrology\Wafer-Counter\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\2a0acd34-8f61-47a3-8818-73fa8fe04902"
|
||||||
|
```
|
@ -1,5 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using OI.Metrology.Shared.Models;
|
||||||
using OI.Metrology.Shared.Models.Stateless;
|
using OI.Metrology.Shared.Models.Stateless;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace OI.Metrology.Wafer.Counter.ApiControllers;
|
namespace OI.Metrology.Wafer.Counter.ApiControllers;
|
||||||
|
|
||||||
@ -33,4 +37,39 @@ public class FileShareController : Controller, IFileShareController<IResult>
|
|||||||
return Results.Ok();
|
return Results.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, string?> GetKeyValuePairs(QueryString queryString)
|
||||||
|
{
|
||||||
|
Dictionary<string, string?> results = [];
|
||||||
|
if (queryString.HasValue)
|
||||||
|
{
|
||||||
|
NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(queryString.Value);
|
||||||
|
foreach (string? key in nameValueCollection.AllKeys)
|
||||||
|
{
|
||||||
|
if (key is null)
|
||||||
|
continue;
|
||||||
|
results.Add(key, nameValueCollection[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CharacterizationParameters? GetCharacterizationParameters(QueryString queryString)
|
||||||
|
{
|
||||||
|
CharacterizationParameters? result;
|
||||||
|
Dictionary<string, string?> keyValuePairs = GetKeyValuePairs(queryString);
|
||||||
|
string json = JsonSerializer.Serialize(keyValuePairs);
|
||||||
|
result = string.IsNullOrEmpty(json) ? null : JsonSerializer.Deserialize(json, CharacterizationParametersSourceGenerationContext.Default.CharacterizationParameters);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("archive-data")]
|
||||||
|
public IActionResult ArchiveData()
|
||||||
|
{
|
||||||
|
List<CharacterizationInfo> results;
|
||||||
|
CharacterizationParameters? characterizationParameters = GetCharacterizationParameters(Request.QueryString);
|
||||||
|
ArgumentNullException.ThrowIfNull(characterizationParameters);
|
||||||
|
results = _FileShareRepository.GetArchiveData(characterizationParameters);
|
||||||
|
return Json(results);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
using OI.Metrology.Shared.Models;
|
using OI.Metrology.Shared.Models;
|
||||||
using OI.Metrology.Shared.Models.Stateless;
|
using OI.Metrology.Shared.Models.Stateless;
|
||||||
|
using OI.Metrology.Wafer.Counter.Models;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Globalization;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace OI.Metrology.Wafer.Counter.Repository;
|
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||||
@ -7,6 +10,11 @@ namespace OI.Metrology.Wafer.Counter.Repository;
|
|||||||
public class FileShareRepository : IFileShareRepository
|
public class FileShareRepository : IFileShareRepository
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private readonly AppSettings _AppSettings;
|
||||||
|
|
||||||
|
public FileShareRepository(AppSettings appSettings) =>
|
||||||
|
_AppSettings = appSettings;
|
||||||
|
|
||||||
Uri IFileShareRepository.Append(Uri uri, params string[] paths) =>
|
Uri IFileShareRepository.Append(Uri uri, params string[] paths) =>
|
||||||
new(paths.Aggregate(uri.AbsoluteUri, (current, path) =>
|
new(paths.Aggregate(uri.AbsoluteUri, (current, path) =>
|
||||||
string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
|
string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
|
||||||
@ -96,4 +104,140 @@ public class FileShareRepository : IFileShareRepository
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<string> GetValidDirectories(string equipmentDirectory, DateTime startDateTime, DateTime endDateTime)
|
||||||
|
{
|
||||||
|
List<string> results = [equipmentDirectory];
|
||||||
|
DateTime dateTime;
|
||||||
|
string weekOfYear;
|
||||||
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||||
|
for (int i = 0; i < int.MaxValue; i++)
|
||||||
|
{
|
||||||
|
dateTime = startDateTime.AddDays(i);
|
||||||
|
if (dateTime > endDateTime)
|
||||||
|
break;
|
||||||
|
weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
||||||
|
results.Add(Path.Combine(equipmentDirectory, weekOfYear, dateTime.ToString("yyyy-MM-dd")));
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<FileInfo> GetCollection(CharacterizationParameters characterizationParameters, string searchPattern, DateTime startDateTime, DateTime endDateTime, ReadOnlyCollection<string> validDirectories)
|
||||||
|
{
|
||||||
|
FileInfo[] results;
|
||||||
|
string[] directories;
|
||||||
|
List<FileInfo> collection = [];
|
||||||
|
string startDateTimeTicks = startDateTime.Ticks.ToString();
|
||||||
|
string delta = (endDateTime.Ticks - startDateTime.Ticks).ToString();
|
||||||
|
string ticksSearchPattern = $"{startDateTime.Ticks.ToString()[..(startDateTimeTicks.Length - delta.Length + 1)]}*";
|
||||||
|
foreach (string validDirectory in validDirectories)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(validDirectory) || !Directory.Exists(validDirectory))
|
||||||
|
continue;
|
||||||
|
if (characterizationParameters.SearchPattern is null || searchPattern == characterizationParameters.SearchPattern)
|
||||||
|
collection.AddRange(Directory.GetFiles(validDirectory, searchPattern, SearchOption.AllDirectories).Select(l => new FileInfo(l)));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directories = Directory.GetDirectories(validDirectory, ticksSearchPattern, SearchOption.AllDirectories);
|
||||||
|
foreach (string directory in directories)
|
||||||
|
collection.AddRange(Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly).Select(l => new FileInfo(l)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results = (from l in collection where l.LastWriteTime >= startDateTime && l.LastWriteTime <= endDateTime orderby l.LastWriteTime descending select l).ToArray();
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<string> GetDirectoryNames(string directory)
|
||||||
|
{
|
||||||
|
List<string> results = new();
|
||||||
|
string? fileName;
|
||||||
|
string? checkDirectory = directory;
|
||||||
|
string? pathRoot = Path.GetPathRoot(directory);
|
||||||
|
string extension = Path.GetExtension(directory);
|
||||||
|
if (string.IsNullOrEmpty(pathRoot))
|
||||||
|
throw new NullReferenceException(nameof(pathRoot));
|
||||||
|
if (Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
fileName = Path.GetFileName(directory);
|
||||||
|
if (!string.IsNullOrEmpty(fileName))
|
||||||
|
results.Add(fileName);
|
||||||
|
}
|
||||||
|
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))
|
||||||
|
{
|
||||||
|
fileName = Path.GetFileName(directory);
|
||||||
|
if (!string.IsNullOrEmpty(fileName))
|
||||||
|
results.Add(fileName);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < int.MaxValue; i++)
|
||||||
|
{
|
||||||
|
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||||
|
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
||||||
|
break;
|
||||||
|
fileName = Path.GetFileName(checkDirectory);
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
continue;
|
||||||
|
results.Add(fileName);
|
||||||
|
}
|
||||||
|
results.Add(pathRoot);
|
||||||
|
results.Reverse();
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<CharacterizationInfo> GetCharacterizationData(CharacterizationParameters characterizationParameters, string equipmentDirectory, string searchPattern)
|
||||||
|
{
|
||||||
|
List<CharacterizationInfo> results = [];
|
||||||
|
string[] lines;
|
||||||
|
string? directoryName;
|
||||||
|
string? checkDirectory;
|
||||||
|
CharacterizationInfo archiveInfo;
|
||||||
|
ReadOnlyCollection<string> directoryNames;
|
||||||
|
DateTime endDateTime = characterizationParameters.EndTime is null ? DateTime.Now : DateTime.Parse(characterizationParameters.EndTime).ToLocalTime();
|
||||||
|
DateTime startDateTime = characterizationParameters.StartTime is null ? DateTime.Now.AddHours(-6) : DateTime.Parse(characterizationParameters.StartTime).ToLocalTime();
|
||||||
|
ReadOnlyCollection<string> validDirectories = GetValidDirectories(equipmentDirectory, startDateTime, endDateTime);
|
||||||
|
ReadOnlyCollection<FileInfo> collection = GetCollection(characterizationParameters, searchPattern, startDateTime, endDateTime, validDirectories);
|
||||||
|
foreach (FileInfo fileInfo in collection)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||||
|
continue;
|
||||||
|
checkDirectory = fileInfo.DirectoryName;
|
||||||
|
directoryName = Path.GetFileName(fileInfo.DirectoryName);
|
||||||
|
directoryNames = GetDirectoryNames(fileInfo.DirectoryName);
|
||||||
|
foreach (string _ in directoryNames)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(checkDirectory))
|
||||||
|
continue;
|
||||||
|
if (validDirectories.Contains(checkDirectory))
|
||||||
|
{
|
||||||
|
directoryName = Path.GetFileName(checkDirectory);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines = File.ReadAllLines(fileInfo.FullName);
|
||||||
|
archiveInfo = new(directoryName, fileInfo.LastWriteTime, lines);
|
||||||
|
results.Add(archiveInfo);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CharacterizationInfo> IFileShareRepository.GetArchiveData(CharacterizationParameters characterizationParameters)
|
||||||
|
{
|
||||||
|
List<CharacterizationInfo> results = [];
|
||||||
|
string searchPattern;
|
||||||
|
string equipmentDirectory;
|
||||||
|
if (!string.IsNullOrEmpty(characterizationParameters.Area) && !string.IsNullOrEmpty(characterizationParameters.WaferSize))
|
||||||
|
{
|
||||||
|
searchPattern = characterizationParameters.SearchPattern is null ? "*" : characterizationParameters.SearchPattern;
|
||||||
|
equipmentDirectory = Path.Combine(_AppSettings.EcCharacterizationSi, "WaferCounter", characterizationParameters.Area, characterizationParameters.WaferSize);
|
||||||
|
if (Directory.Exists(equipmentDirectory))
|
||||||
|
results.AddRange(GetCharacterizationData(characterizationParameters, equipmentDirectory, searchPattern));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(characterizationParameters.EquipmentId))
|
||||||
|
{
|
||||||
|
searchPattern = "*.json";
|
||||||
|
equipmentDirectory = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive", characterizationParameters.EquipmentId);
|
||||||
|
if (Directory.Exists(equipmentDirectory))
|
||||||
|
results.AddRange(GetCharacterizationData(characterizationParameters, equipmentDirectory, searchPattern));
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
11
Wafer-Counter/Repositories/RegexHelper.cs
Normal file
11
Wafer-Counter/Repositories/RegexHelper.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||||
|
|
||||||
|
public partial class RegexHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[\\,\/,\:,\*,\?,\"",\<,\>,\|]")]
|
||||||
|
internal static partial Regex WindowsFileSystem();
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,8 @@ using OI.Metrology.Shared.Models;
|
|||||||
using OI.Metrology.Shared.Models.Stateless;
|
using OI.Metrology.Shared.Models.Stateless;
|
||||||
using OI.Metrology.Wafer.Counter.Models;
|
using OI.Metrology.Wafer.Counter.Models;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace OI.Metrology.Wafer.Counter.Repository;
|
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||||
|
|
||||||
@ -13,6 +15,7 @@ public class WaferCounterRepository : IWaferCounterRepository
|
|||||||
int Total,
|
int Total,
|
||||||
string? SlotMap);
|
string? SlotMap);
|
||||||
|
|
||||||
|
private readonly Regex _Regex;
|
||||||
private readonly string _MockRoot;
|
private readonly string _MockRoot;
|
||||||
private readonly string _RepositoryName;
|
private readonly string _RepositoryName;
|
||||||
private readonly AppSettings _AppSettings;
|
private readonly AppSettings _AppSettings;
|
||||||
@ -24,19 +27,25 @@ public class WaferCounterRepository : IWaferCounterRepository
|
|||||||
_AppSettings = appSettings;
|
_AppSettings = appSettings;
|
||||||
_MockRoot = appSettings.MockRoot;
|
_MockRoot = appSettings.MockRoot;
|
||||||
_HttpClientFactory = httpClientFactory;
|
_HttpClientFactory = httpClientFactory;
|
||||||
|
_Regex = RegexHelper.WindowsFileSystem();
|
||||||
_FileShareRepository = fileShareRepository;
|
_FileShareRepository = fileShareRepository;
|
||||||
_RepositoryName = nameof(WaferCounterRepository)[..^10];
|
_RepositoryName = nameof(WaferCounterRepository)[..^10];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MoveFile(string area, string waferSize, string text, string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable)
|
private void MoveFile(string area, string waferSize, string windowsFileSystemSafeText, string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable)
|
||||||
{
|
{
|
||||||
|
string equipmentId = $"{area}-{waferSize}";
|
||||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||||
string from = Path.Combine(waferSizeDirectory, nginxFileSystemSortable.Name);
|
string from = Path.Combine(waferSizeDirectory, nginxFileSystemSortable.Name);
|
||||||
string archive = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive", $"{area}-{waferSize}");
|
string archive = Path.Combine(_AppSettings.EcCharacterizationSi, "Archive", equipmentId);
|
||||||
|
HeaderCommon headerCommon = new() { RDS = windowsFileSystemSafeText, MesEntity = equipmentId };
|
||||||
string weekOfYear = $"{nginxFileSystemSortable.DateTime:yyyy}_Week_{calendar.GetWeekOfYear(nginxFileSystemSortable.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
string weekOfYear = $"{nginxFileSystemSortable.DateTime:yyyy}_Week_{calendar.GetWeekOfYear(nginxFileSystemSortable.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
||||||
string to = Path.Combine(archive, weekOfYear, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd"), nginxFileSystemSortable.Name);
|
string directory = Path.Combine(archive, weekOfYear, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd"), windowsFileSystemSafeText);
|
||||||
|
string file = Path.Combine(directory, nginxFileSystemSortable.DateTime.Ticks.ToString(), $"{nginxFileSystemSortable.Name}.json");
|
||||||
|
string json = JsonSerializer.Serialize(headerCommon, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
_FileShareRepository.FileWrite(file, json);
|
||||||
|
string to = Path.Combine(directory, nginxFileSystemSortable.Name);
|
||||||
_FileShareRepository.MoveFile(from, to);
|
_FileShareRepository.MoveFile(from, to);
|
||||||
_FileShareRepository.FileWrite($"{to}.txt", text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Record GetRecord(string line1, string line2)
|
private static Record GetRecord(string line1, string line2)
|
||||||
@ -185,9 +194,10 @@ public class WaferCounterRepository : IWaferCounterRepository
|
|||||||
result = WaferCounter.GetWaferCounter("No files!");
|
result = WaferCounter.GetWaferCounter("No files!");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
string windowsFileSystemSafeText = _Regex.Replace(text, ".");
|
||||||
result = GetLastQuantityAndSlotMap(waferSize, httpClient, nginxFileSystemSortableCollection[0]);
|
result = GetLastQuantityAndSlotMap(waferSize, httpClient, nginxFileSystemSortableCollection[0]);
|
||||||
for (int i = 0; i < nginxFileSystemSortableCollection.Count; i++)
|
for (int i = 0; i < nginxFileSystemSortableCollection.Count; i++)
|
||||||
MoveFile(area, waferSize, text, waferSizeDirectory, nginxFileSystemSortableCollection[i]);
|
MoveFile(area, waferSize, windowsFileSystemSafeText, waferSizeDirectory, nginxFileSystemSortableCollection[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user