Ready to beta test
This commit is contained in:
42
blazorserver/Pages/Error.cshtml
Normal file
42
blazorserver/Pages/Error.cshtml
Normal file
@ -0,0 +1,42 @@
|
||||
@page
|
||||
@model Mesa_Backlog.Pages.ErrorModel
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Error</title>
|
||||
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="content px-4">
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
20
blazorserver/Pages/Error.cshtml.cs
Normal file
20
blazorserver/Pages/Error.cshtml.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Mesa_Backlog.Pages;
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[IgnoreAntiforgeryToken]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
private readonly ILogger<ErrorModel> _Logger;
|
||||
|
||||
public ErrorModel(ILogger<ErrorModel> logger) => _Logger = logger;
|
||||
|
||||
public void OnGet() => RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
}
|
97
blazorserver/Pages/FetchData.cshtml
Normal file
97
blazorserver/Pages/FetchData.cshtml
Normal file
@ -0,0 +1,97 @@
|
||||
@page
|
||||
@model Mesa_Backlog.Pages.FetchData
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Mesa Backlog - Data</title>
|
||||
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="~/css/site.css" rel="stylesheet" />
|
||||
<style>
|
||||
.BugFix {
|
||||
background-color: #ddd9c4;
|
||||
}
|
||||
|
||||
.High {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.Med {
|
||||
background-color: #c4d79b;
|
||||
}
|
||||
|
||||
.Low {
|
||||
background-color: #fabf8f;
|
||||
}
|
||||
|
||||
.TBD {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
td,
|
||||
a {
|
||||
color: #000000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="content px-4">
|
||||
<table border="1" style="min-width:900px;">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="@(nameof(Mesa_Backlog.Pages.FetchData))">View (from DevOps)</a><br />
|
||||
</td>
|
||||
<td>
|
||||
@if (!string.IsNullOrEmpty(Model.JSON))
|
||||
{
|
||||
<form method="post" action="@(nameof(Mesa_Backlog.Pages.UploadAndExtract))"
|
||||
asp-antiforgery="true">
|
||||
<input type="submit" value="Back" /><br />
|
||||
<input type="hidden" asp-for="@(Model.JSON)" />
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<a href="@(nameof(Mesa_Backlog.Pages.UploadAndExtract))">Upload and Extract</a>
|
||||
</td>
|
||||
<td>
|
||||
@if (Model.JsonFiles is not null && Model.JsonFiles.Any())
|
||||
{
|
||||
<form method="post" asp-antiforgery="true">
|
||||
<select asp-for="@(Model.JsonFileName)">
|
||||
@foreach (string jsonFile in Model.JsonFiles)
|
||||
{
|
||||
@(await Html.PartialAsync(nameof(Mesa_Backlog.Pages.Shared.FileOption), jsonFile))
|
||||
}
|
||||
</select><br />
|
||||
<input type="submit" value="View last uploaded" />
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table><br />
|
||||
@if (Model.WorkItems is not null && Model.WorkItems.Any())
|
||||
{
|
||||
<h2>@(Model.WorkItems.Count) Work Item(s)</h2>
|
||||
@(await Html.PartialAsync(nameof(Mesa_Backlog.Pages.Shared.WorkItemsTable), Model.WorkItems))
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Model.JSON))
|
||||
{
|
||||
<form method="post" asp-antiforgery="true">
|
||||
<input type="submit" value="And new to DevOps" /><br />
|
||||
<textarea cols="150" rows="25" asp-for="@(Model.JSON)">@Html.Raw(Model.JSON)</textarea><br />
|
||||
<input type="hidden" asp-for="@(Model.PageName)"
|
||||
value="@(nameof(Mesa_Backlog.Pages.FetchData.PageName))" />
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
281
blazorserver/Pages/FetchData.cshtml.cs
Normal file
281
blazorserver/Pages/FetchData.cshtml.cs
Normal file
@ -0,0 +1,281 @@
|
||||
using Mesa_Backlog.Library;
|
||||
using Mesa_Backlog.Library.WorkItems;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Http = System.Net.Http;
|
||||
using IO = System.IO;
|
||||
using WebApi = Microsoft.TeamFoundation.WorkItemTracking.WebApi;
|
||||
|
||||
namespace Mesa_Backlog.Pages;
|
||||
|
||||
public class FetchData : PageModel
|
||||
{
|
||||
|
||||
[BindProperty]
|
||||
public string? JSON { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string? PageName { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string? JsonFileName { get; set; }
|
||||
|
||||
public bool AreLoaded { init; get; }
|
||||
public List<string> JsonFiles { init; get; }
|
||||
|
||||
private readonly string _Directory;
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly bool _IsEnvironmentDevelopment;
|
||||
private readonly IHostEnvironment _HostEnvironment;
|
||||
private readonly IHttpClientFactory _HttpClientFactory;
|
||||
public List<ViewModels.WorkItem> WorkItems { init; get; }
|
||||
private readonly Dictionary<string, int?> _KeyValuePairs;
|
||||
private readonly WebApi.WorkItemTrackingHttpClient _WorkItemTrackingHttpClient;
|
||||
|
||||
public FetchData(IHostEnvironment hostEnvironment, AppSettings appSettings, IHttpClientFactory httpClientFactory, WebApi.WorkItemTrackingHttpClient workItemTrackingHttpClient, Dictionary<string, int?> keyValuePairs)
|
||||
{
|
||||
JsonFiles = new();
|
||||
WorkItems = new();
|
||||
_AppSettings = appSettings;
|
||||
_KeyValuePairs = keyValuePairs;
|
||||
_HostEnvironment = hostEnvironment;
|
||||
_HttpClientFactory = httpClientFactory;
|
||||
_WorkItemTrackingHttpClient = workItemTrackingHttpClient;
|
||||
_IsEnvironmentDevelopment = hostEnvironment.IsDevelopment();
|
||||
AreLoaded = (from l in keyValuePairs where l.Value is not null select true).Any();
|
||||
_Directory = Path.Combine(_HostEnvironment.ContentRootPath, ".vscode", "Uploads");
|
||||
if (!Directory.Exists(_Directory))
|
||||
_ = Directory.CreateDirectory(_Directory);
|
||||
}
|
||||
|
||||
private void UpdateKeyValuePairs(FIBacklogMesa[] fIBacklogMesaCollection)
|
||||
{
|
||||
foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection)
|
||||
{
|
||||
if (!_KeyValuePairs.ContainsKey(fIBacklogMesa.Req))
|
||||
_KeyValuePairs.Add(fIBacklogMesa.Req, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetWorkItems(FIBacklogMesa[] fIBacklogMesaCollection)
|
||||
{
|
||||
UpdateKeyValuePairs(fIBacklogMesaCollection);
|
||||
string project = _AppSettings.Client.Project;
|
||||
string workItemsAddress = $"{_AppSettings.Client.BaseAddress}{_AppSettings.Client.BasePage}{project}/_workItems/edit/";
|
||||
List<ViewModels.WorkItem> workItems = ViewModels.WorkItem.GetWorkItems(_KeyValuePairs, workItemsAddress, fIBacklogMesaCollection);
|
||||
WorkItems.AddRange(workItems);
|
||||
}
|
||||
|
||||
private IActionResult GetPage(string json)
|
||||
{
|
||||
IActionResult result;
|
||||
FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json);
|
||||
SetWorkItems(fIBacklogMesaCollection);
|
||||
JSON = ExcelReader.GetJson(fIBacklogMesaCollection);
|
||||
string fileName = Path.Combine(_Directory, $"{DateTime.Now.Ticks}.json");
|
||||
IO.File.WriteAllText(fileName, JSON);
|
||||
result = Page();
|
||||
return result;
|
||||
}
|
||||
|
||||
private IActionResult GetPage(List<string> jsonFiles, string jsonFileName)
|
||||
{
|
||||
IActionResult result;
|
||||
string json = IO.File.ReadAllText(jsonFileName);
|
||||
FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json);
|
||||
SetWorkItems(fIBacklogMesaCollection);
|
||||
if (!jsonFiles.Any())
|
||||
{
|
||||
jsonFiles.AddRange(Directory.GetFiles(_Directory, "*.json"));
|
||||
JsonFiles.AddRange(jsonFiles.OrderByDescending(l => l));
|
||||
}
|
||||
if (!jsonFiles.Contains(jsonFileName))
|
||||
{
|
||||
string fileName = Path.Combine(_Directory, $"{DateTime.Now.Ticks}.json");
|
||||
IO.File.WriteAllText(fileName, JSON);
|
||||
}
|
||||
JSON = json;
|
||||
result = Page();
|
||||
return result;
|
||||
}
|
||||
|
||||
private Dictionary<int, string> GetFlopped()
|
||||
{
|
||||
Dictionary<int, string> results = new();
|
||||
foreach (KeyValuePair<string, int?> keyValuePair in _KeyValuePairs)
|
||||
{
|
||||
if (keyValuePair.Value is null)
|
||||
continue;
|
||||
results.Add(keyValuePair.Value.Value, keyValuePair.Key);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void MergeBack(Dictionary<int, string> keyValuePairs)
|
||||
{
|
||||
foreach (KeyValuePair<int, string> keyValuePair in keyValuePairs)
|
||||
{
|
||||
if (_KeyValuePairs.ContainsKey(keyValuePair.Value))
|
||||
_KeyValuePairs[keyValuePair.Value] = keyValuePair.Key;
|
||||
else
|
||||
_KeyValuePairs.Add(keyValuePair.Value, keyValuePair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Root> GetWorkItems()
|
||||
{
|
||||
List<Root> results = new();
|
||||
Root workItem;
|
||||
string query = _AppSettings.Client.Query;
|
||||
using Http.HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(FetchData));
|
||||
Library.WIQL.WorkItem[] workItems = Library.HttpClient.GetWorkItems(httpClient, _AppSettings.Client.BasePage, _AppSettings.Client.API, query);
|
||||
for (int i = 0; i < workItems.Length; i++)
|
||||
{
|
||||
workItem = Library.HttpClient.GetWorkItem(httpClient, _AppSettings.Client.BasePage, _AppSettings.Client.API, workItems[i].Id);
|
||||
if (workItem is null)
|
||||
break;
|
||||
results.Add(workItem);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void CreateNew(string project, Dictionary<int, string> keyValuePairs, List<FIBacklogMesa> fIBacklogMesaCollection)
|
||||
{
|
||||
Task<WebApi.Models.WorkItem> workItemTask;
|
||||
foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection.OrderBy(l => int.Parse(l.Req)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(fIBacklogMesa.Title))
|
||||
continue;
|
||||
workItemTask = WorkItemTrackingHttpClient.CreateWorkItem(_IsEnvironmentDevelopment, _WorkItemTrackingHttpClient, project, fIBacklogMesa);
|
||||
workItemTask.Wait();
|
||||
if (workItemTask.Result is null)
|
||||
throw new NullReferenceException(nameof(workItemTask.Result));
|
||||
if (workItemTask.Result?.Id is not null)
|
||||
keyValuePairs.Add(workItemTask.Result.Id.Value, fIBacklogMesa.Req);
|
||||
}
|
||||
}
|
||||
|
||||
private void PossiblyCreate(FIBacklogMesa[] fIBacklogMesaCollection, Dictionary<int, string> keyValuePairs)
|
||||
{
|
||||
List<FIBacklogMesa> collection = new();
|
||||
foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fIBacklogMesa.Title))
|
||||
continue;
|
||||
if (_KeyValuePairs.ContainsKey(fIBacklogMesa.Req) && _KeyValuePairs[fIBacklogMesa.Req] is not null)
|
||||
continue;
|
||||
collection.Add(fIBacklogMesa);
|
||||
}
|
||||
if (collection.Any() && fIBacklogMesaCollection.Length != collection.Count)
|
||||
CreateNew(_AppSettings.Client.Project, keyValuePairs, collection);
|
||||
}
|
||||
|
||||
private void Update(string project, List<(int, FIBacklogMesa)> collection)
|
||||
{
|
||||
Task<WebApi.Models.WorkItem> workItemTask;
|
||||
foreach ((int id, FIBacklogMesa fIBacklogMesa) in collection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fIBacklogMesa.Title))
|
||||
continue;
|
||||
workItemTask = WorkItemTrackingHttpClient.UpdateWorkItem(_WorkItemTrackingHttpClient, project, id, fIBacklogMesa);
|
||||
workItemTask.Wait();
|
||||
if (workItemTask.Result is null)
|
||||
throw new NullReferenceException(nameof(workItemTask.Result));
|
||||
}
|
||||
}
|
||||
|
||||
private void PossiblyUpdate(FIBacklogMesa[] fIBacklogMesaCollection, List<Root> workItems)
|
||||
{
|
||||
int? index;
|
||||
string title;
|
||||
FIBacklogMesa fIBacklogMesa;
|
||||
List<(int, FIBacklogMesa)> collection = new();
|
||||
foreach (Root workItem in workItems)
|
||||
{
|
||||
index = null;
|
||||
for (int i = 0; i < fIBacklogMesaCollection.Length; i++)
|
||||
{
|
||||
fIBacklogMesa = fIBacklogMesaCollection[i];
|
||||
if (string.IsNullOrEmpty(fIBacklogMesa.Title))
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(workItem.Fields.MicrosoftVSTSTCMSystemInfo) || !workItem.Fields.MicrosoftVSTSTCMSystemInfo.Contains(fIBacklogMesa.Req))
|
||||
continue;
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
if (index is null)
|
||||
continue;
|
||||
fIBacklogMesa = fIBacklogMesaCollection[index.Value];
|
||||
title = fIBacklogMesa.Title.Length > 254 ? fIBacklogMesa.Title[..255] : fIBacklogMesa.Title;
|
||||
if (workItem.Fields.SystemTitle != title)
|
||||
collection.Add((workItem.Id, fIBacklogMesa));
|
||||
else if (workItem.Fields.SystemDescription != fIBacklogMesa.Definition)
|
||||
collection.Add((workItem.Id, fIBacklogMesa));
|
||||
}
|
||||
if (collection.Any() && fIBacklogMesaCollection.Length != collection.Count)
|
||||
Update(_AppSettings.Client.Project, collection);
|
||||
}
|
||||
|
||||
private IActionResult GetPage(string json, string pageName)
|
||||
{
|
||||
IActionResult result;
|
||||
FIBacklogMesa[]? fIBacklogMesaCollection = System.Text.Json.JsonSerializer.Deserialize<FIBacklogMesa[]>(json);
|
||||
if (fIBacklogMesaCollection is null)
|
||||
throw new NullReferenceException(nameof(fIBacklogMesaCollection));
|
||||
UpdateKeyValuePairs(fIBacklogMesaCollection);
|
||||
List<Root> workItems = GetWorkItems();
|
||||
if (!workItems.Any())
|
||||
throw new Exception("Failed to get work items!");
|
||||
Dictionary<int, string> keyValuePairs = GetFlopped();
|
||||
PossiblyCreate(fIBacklogMesaCollection, keyValuePairs);
|
||||
PossiblyUpdate(fIBacklogMesaCollection, workItems);
|
||||
SetWorkItems(fIBacklogMesaCollection);
|
||||
MergeBack(keyValuePairs);
|
||||
result = RedirectToPage($"./{nameof(FetchData)}");
|
||||
return result;
|
||||
}
|
||||
|
||||
public IActionResult OnPost()
|
||||
{
|
||||
IActionResult result;
|
||||
WorkItems.Clear();
|
||||
if (!string.IsNullOrEmpty(JsonFileName))
|
||||
result = GetPage(JsonFiles, JsonFileName);
|
||||
else if (!string.IsNullOrEmpty(JSON) && string.IsNullOrEmpty(PageName))
|
||||
result = GetPage(JSON);
|
||||
else if (!string.IsNullOrEmpty(JSON) && !string.IsNullOrEmpty(PageName))
|
||||
result = GetPage(JSON, PageName);
|
||||
else
|
||||
result = Page();
|
||||
return result;
|
||||
}
|
||||
|
||||
private IActionResult SetWorkItemsAndGetPage(string json)
|
||||
{
|
||||
IActionResult result;
|
||||
FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json);
|
||||
SetWorkItems(fIBacklogMesaCollection);
|
||||
result = Page();
|
||||
return result;
|
||||
}
|
||||
|
||||
public IActionResult OnGet()
|
||||
{
|
||||
IActionResult result;
|
||||
JsonFiles.Clear();
|
||||
WorkItems.Clear();
|
||||
string[] jsonFiles = Directory.GetFiles(_Directory, "*.json");
|
||||
JsonFiles.AddRange(jsonFiles.OrderByDescending(l => l));
|
||||
if (!string.IsNullOrEmpty(JSON))
|
||||
result = SetWorkItemsAndGetPage(JSON);
|
||||
else if (!string.IsNullOrEmpty(JsonFileName) && IO.File.Exists(JsonFileName))
|
||||
{
|
||||
string json = IO.File.ReadAllText(JsonFileName);
|
||||
result = SetWorkItemsAndGetPage(json);
|
||||
}
|
||||
else
|
||||
result = Page();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
16
blazorserver/Pages/Shared/FileOption.cshtml
Normal file
16
blazorserver/Pages/Shared/FileOption.cshtml
Normal file
@ -0,0 +1,16 @@
|
||||
@model string
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model) && File.Exists(Model))
|
||||
{
|
||||
string nowTicks = DateTime.Now.Ticks.ToString();
|
||||
string fileName = System.IO.Path.GetFileNameWithoutExtension(Model);
|
||||
if (fileName.Length != nowTicks.Length || !long.TryParse(fileName, out long ticks))
|
||||
{
|
||||
<option value="@(Model)">@(fileName)</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@(Model)">@(new DateTime(ticks).ToString("MM/dd/yyyy hh:mm tt"))</option>
|
||||
}
|
||||
}
|
7
blazorserver/Pages/Shared/FileOption.cshtml.cs
Normal file
7
blazorserver/Pages/Shared/FileOption.cshtml.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Mesa_Backlog.Pages.Shared;
|
||||
|
||||
public class FileOption : PageModel
|
||||
{
|
||||
}
|
51
blazorserver/Pages/Shared/WorkItemsTable.cshtml
Normal file
51
blazorserver/Pages/Shared/WorkItemsTable.cshtml
Normal file
@ -0,0 +1,51 @@
|
||||
@model List<Mesa_Backlog.ViewModels.WorkItem>
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Req<!--Id || Discussion[2]--></th>
|
||||
<th>Submitted<!--Created Date--></th>
|
||||
<th>Requestor<!--Assigned To Display Name--></th>
|
||||
<th>Assigned To<!--Tags--></th>
|
||||
<th>,<!--Title--></th>
|
||||
<th>System(s)<!--Area Path--></th>
|
||||
<th>Priority<!--Priority--></th>
|
||||
<th>Status<!--Iteration Path--></th>
|
||||
<th>Definition<!--Description--></th>
|
||||
<th>Updates<!--Discussion--></th>
|
||||
<th>Est Effort (days)<!--Effort--></th>
|
||||
<th>Commit Date<!--TargetDate--></th>
|
||||
<th>Re-Commit Date<!-- --></th>
|
||||
<th>UAT as of<!--ResolvedDate--></th>
|
||||
<th>CMP Date<!--ClosedDate--></th>
|
||||
<th> <!--State--></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(Model is not null)
|
||||
{
|
||||
@foreach (var workItem in Model)
|
||||
{
|
||||
<tr class="@workItem.Priority" id="@(workItem.Id)">
|
||||
<td><a href="@(workItem.HypertextReference)" target="_blank">@workItem.Req</a></td>
|
||||
<td>@workItem.Submitted</td>
|
||||
<td>@workItem.Requestor</td>
|
||||
<td>@workItem.AssignedTo</td>
|
||||
<td><a href="@(workItem.HypertextReference)" target="_blank">@workItem.Title</a></td>
|
||||
<td>@workItem.Systems</td>
|
||||
<td><a href="@(workItem.HypertextReference)" target="_blank">@workItem.Priority</a></td>
|
||||
<td><a href="@(workItem.HypertextReference)" target="_blank">@workItem.Status</a></td>
|
||||
<td>@Html.Raw(workItem.Definition)</td>
|
||||
<td>@Html.Raw(workItem.Updates)</td>
|
||||
<td>@workItem.EstEffortDays</td>
|
||||
<td>@workItem.CommitDate</td>
|
||||
<td> </td>
|
||||
<td>@workItem.UATAsOf</td>
|
||||
<td>@workItem.CMPDate</td>
|
||||
<td>@workItem.State</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
7
blazorserver/Pages/Shared/WorkItemsTable.cshtml.cs
Normal file
7
blazorserver/Pages/Shared/WorkItemsTable.cshtml.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Mesa_Backlog.Pages.Shared;
|
||||
|
||||
public class WorkItemsTable : PageModel
|
||||
{
|
||||
}
|
70
blazorserver/Pages/UploadAndExtract.cshtml
Normal file
70
blazorserver/Pages/UploadAndExtract.cshtml
Normal file
@ -0,0 +1,70 @@
|
||||
@page
|
||||
@model Mesa_Backlog.Pages.UploadAndExtract
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Mesa Backlog - Upload</title>
|
||||
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="~/css/site.css" rel="stylesheet" />
|
||||
<style>
|
||||
.BugFix {
|
||||
background-color: #ddd9c4;
|
||||
}
|
||||
|
||||
.High {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.Med {
|
||||
background-color: #c4d79b;
|
||||
}
|
||||
|
||||
.Low {
|
||||
background-color: #fabf8f;
|
||||
}
|
||||
|
||||
.TBD {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
td,
|
||||
a {
|
||||
color: #000000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="content px-4">
|
||||
@if (string.IsNullOrEmpty(Model.JSON))
|
||||
{
|
||||
<a href="@(nameof(Mesa_Backlog.Pages.FetchData))">View (from DevOps)</a><br />
|
||||
<a href="@(nameof(Mesa_Backlog.Pages.UploadAndExtract))">Upload and Extract</a>
|
||||
}
|
||||
@if (Model.JSON is null || string.IsNullOrEmpty(Model.JSON))
|
||||
{
|
||||
<form method="post" enctype="multipart/form-data" asp-antiforgery="true">
|
||||
<input type="file" asp-for="@(Model.FormFile))" />
|
||||
<input type="submit" value="Upload and Extract as json" />
|
||||
</form>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form method="post" action="@(nameof(Mesa_Backlog.Pages.FetchData))" asp-antiforgery="true">
|
||||
<input type="submit" value="View as Table" /><br />
|
||||
<textarea cols="150" rows="25" asp-for="@(Model.JSON)">
|
||||
@Html.Raw(Model.JSON)
|
||||
</textarea>
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
44
blazorserver/Pages/UploadAndExtract.cshtml.cs
Normal file
44
blazorserver/Pages/UploadAndExtract.cshtml.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using Mesa_Backlog.Library;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using IO = System.IO;
|
||||
|
||||
namespace Mesa_Backlog.Pages;
|
||||
|
||||
public class UploadAndExtract : PageModel
|
||||
{
|
||||
|
||||
[BindProperty]
|
||||
public string? JSON { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public IFormFile? FormFile { get; set; }
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly IHostEnvironment _HostEnvironment;
|
||||
|
||||
public UploadAndExtract(IHostEnvironment hostEnvironment, AppSettings appSettings)
|
||||
{
|
||||
_AppSettings = appSettings;
|
||||
_HostEnvironment = hostEnvironment;
|
||||
}
|
||||
|
||||
public IActionResult OnPost()
|
||||
{
|
||||
string directory = Path.Combine(_HostEnvironment.ContentRootPath, ".vscode", "Uploads");
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
if (FormFile is not null)
|
||||
{
|
||||
string fileName = Path.Combine(directory, FormFile.FileName);
|
||||
string copyFileName = Path.Combine(directory, $"{DateTime.Now.Ticks}{Path.GetExtension(fileName)}");
|
||||
using FileStream fileStream = new(fileName, FileMode.Create);
|
||||
FormFile.CopyTo(fileStream);
|
||||
IO.File.Copy(fileName, copyFileName);
|
||||
JSON = ExcelReader.GetJson(copyFileName, _AppSettings.Excel.Sheet);
|
||||
IO.File.Delete(copyFileName);
|
||||
}
|
||||
return Page();
|
||||
}
|
||||
|
||||
}
|
8
blazorserver/Pages/_Host.cshtml
Normal file
8
blazorserver/Pages/_Host.cshtml
Normal file
@ -0,0 +1,8 @@
|
||||
@page "/"
|
||||
@namespace Mesa_Backlog.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
|
||||
<component type="typeof(App)" render-mode="ServerPrerendered" />
|
32
blazorserver/Pages/_Layout.cshtml
Normal file
32
blazorserver/Pages/_Layout.cshtml
Normal file
@ -0,0 +1,32 @@
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@namespace Mesa_Backlog.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<base href="~/" />
|
||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
<link href="Mesa-Backlog.styles.css" rel="stylesheet" />
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user