PCRB webassembly
This commit is contained in:
@ -1,8 +1,14 @@
|
||||
@inherits LayoutComponentBase
|
||||
@using System.Text.Json
|
||||
@using System.Text
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject MesaFabApprovalAuthStateProvider authStateProvider
|
||||
@inject IAuthenticationService authenticationService
|
||||
@inject IConfiguration Configuration
|
||||
@inject IMemoryCache cache
|
||||
@inject IJSRuntime jsRuntime
|
||||
@inject IHttpClientFactory httpClientFactory
|
||||
@inject ISnackbar snackbar
|
||||
@inject NavigationManager navManager
|
||||
|
||||
<MudThemeProvider />
|
||||
@ -28,19 +34,22 @@
|
||||
<MudDrawer @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2">
|
||||
<MudNavMenu Color="Color.Info" Bordered="true" Class="d-flex flex-column justify-center p-1 gap-1">
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
Href="@Configuration["OldFabApprovalUrl"]"
|
||||
Target="_blank"
|
||||
StartIcon="@Icons.Material.Filled.Home">
|
||||
Color="Color.Tertiary"
|
||||
Href="@Configuration["OldFabApprovalUrl"]"
|
||||
Target="_blank"
|
||||
StartIcon="@Icons.Material.Filled.Home">
|
||||
Return to Main Site
|
||||
</MudButton>
|
||||
|
||||
<MudDivider Class="my-1" />
|
||||
@if (authStateProvider.CurrentUser is not null) {
|
||||
<MudNavGroup Title="Create New">
|
||||
<MudNavLink OnClick="@(() => GoTo("mrb/new"))">Create New MRB</MudNavLink>
|
||||
<MudNavLink OnClick="@(() => GoTo("pcrb/new"))">Create New PCRB</MudNavLink>
|
||||
</MudNavGroup>
|
||||
<MudNavLink OnClick="@(() => GoTo(""))" Icon="@Icons.Material.Filled.Dashboard">Dashboard</MudNavLink>
|
||||
<MudNavLink OnClick="@(() => GoTo("mrb/all"))" Icon="@Icons.Material.Filled.Ballot">MRB List</MudNavLink>
|
||||
<MudNavLink OnClick="@(() => GoTo("pcrb/all"))" Icon="@Icons.Material.Filled.Ballot">PCRB List</MudNavLink>
|
||||
}
|
||||
</MudNavMenu>
|
||||
</MudDrawer>
|
||||
@ -68,4 +77,48 @@
|
||||
cache.Set("redirectUrl", page);
|
||||
navManager.NavigateTo(page);
|
||||
}
|
||||
|
||||
private async Task GoToExternal(string url, string content) {
|
||||
IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js");
|
||||
await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content);
|
||||
}
|
||||
|
||||
private async Task GoToOldSite() {
|
||||
try {
|
||||
User? currentUser = authStateProvider.CurrentUser;
|
||||
|
||||
AuthTokens? authTokens = await authenticationService.GetAuthTokens();
|
||||
|
||||
if (currentUser is null || authTokens is null) {
|
||||
await authStateProvider.Logout();
|
||||
navManager.NavigateTo("login");
|
||||
return;
|
||||
}
|
||||
|
||||
AuthAttempt authAttempt = new() {
|
||||
LoginID = currentUser.LoginID,
|
||||
AuthTokens = authTokens
|
||||
};
|
||||
|
||||
HttpClient httpClient = httpClientFactory.CreateClient("OldSite");
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "Account/ExternalAuthSetup");
|
||||
|
||||
request.Content = new StringContent(JsonSerializer.Serialize(authAttempt),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
|
||||
|
||||
if (httpResponseMessage.IsSuccessStatusCode) {
|
||||
snackbar.Add("Old site auth setup successful", Severity.Success);
|
||||
} else {
|
||||
snackbar.Add($"Old site auth setup failed, because {httpResponseMessage.ReasonPhrase}", Severity.Error);
|
||||
}
|
||||
|
||||
await GoToExternal($"{Configuration["OldFabApprovalUrl"]}", "");
|
||||
} catch (Exception ex) {
|
||||
snackbar.Add($"Unable to go to old site, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,10 @@
|
||||
<Watch Include="**\*.razor" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Watch Remove="Pages\Components\PCRBApproverForm.razor" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" />
|
||||
@ -17,7 +21,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="MudBlazor" Version="7.6.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) {
|
||||
_redirectPath = System.Net.WebUtility.UrlDecode(redirectPath);
|
||||
_redirectPath = redirectPath.ToString();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) {
|
||||
@ -35,11 +35,12 @@
|
||||
|
||||
string loginId = userService.GetLoginIdFromClaimsPrincipal(principal);
|
||||
|
||||
await authService.ClearCurrentUser();
|
||||
await authService.ClearTokens();
|
||||
|
||||
await authService.SetLoginId(loginId);
|
||||
await authService.SetTokens(_jwt, _refreshToken);
|
||||
|
||||
User? user = await userService.GetUserByLoginId(loginId);
|
||||
await authService.SetCurrentUser(user);
|
||||
await authService.SetCurrentUser(null);
|
||||
|
||||
await authStateProvider.StateHasChanged(principal);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="p-2">
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudTextField T="string"
|
||||
Label="Comments"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="p-2">
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudTextField T="string"
|
||||
Label="Comments"
|
||||
|
@ -4,10 +4,11 @@
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="p-2">
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudSelect T="string"
|
||||
Label="Action"
|
||||
Disabled="@(!string.IsNullOrWhiteSpace(mrbAction.Action))"
|
||||
Required="true"
|
||||
RequiredError="You must select an action!"
|
||||
@bind-Value="@mrbAction.Action"
|
||||
@ -19,29 +20,61 @@
|
||||
<MudSelectItem Value="@("Unblock")" />
|
||||
<MudSelectItem Value="@("Waiver")" />
|
||||
</MudSelect>
|
||||
@if (mrbAction.Action.Equals("Convert")) {
|
||||
<MudTextField @bind-Value="@mrbAction.ConvertFrom"
|
||||
Label="Convert From"
|
||||
@if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
<MudSelect T="string"
|
||||
Label="Convert From Customer"
|
||||
Required
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=convertFromCustomer
|
||||
Text="@convertFromCustomer">
|
||||
@foreach (string customer in customerNames) {
|
||||
<MudSelectItem Value="@(customer)" />
|
||||
}
|
||||
</MudSelect>
|
||||
<MudTextField @bind-Value="@convertFromPart"
|
||||
Label="Convert From Part Number"
|
||||
Required
|
||||
RequiredError="Conversion value required!"
|
||||
Text="@mrbAction.ConvertFrom" />
|
||||
<MudTextField @bind-Value="@mrbAction.ConvertTo"
|
||||
Label="Convert To"
|
||||
RequiredError="Part number required!"
|
||||
Text="@convertFromPart" />
|
||||
<MudSelect T="string"
|
||||
Label="Convert To Customer"
|
||||
Required
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=convertToCustomer
|
||||
Text="@convertToCustomer">
|
||||
@foreach (string customer in customerNames) {
|
||||
<MudSelectItem Value="@(customer)" />
|
||||
}
|
||||
</MudSelect>
|
||||
<MudTextField @bind-Value="@convertToPart"
|
||||
Label="Convert To Part Number"
|
||||
Required
|
||||
RequiredError="Conversion value required!"
|
||||
Text="@mrbAction.ConvertTo" />
|
||||
RequiredError="Part number required!"
|
||||
Text="@convertToPart" />
|
||||
} else {
|
||||
<MudSelect T="string"
|
||||
Label="Affected Customer"
|
||||
Required
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=mrbAction.Customer
|
||||
Text="@mrbAction.Customer">
|
||||
@foreach (string customer in customerNames) {
|
||||
<MudSelectItem Value="@(customer)" />
|
||||
}
|
||||
</MudSelect>
|
||||
<MudAutocomplete T="string"
|
||||
Label="Part Number"
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=mrbAction.PartNumber
|
||||
Text="@mrbAction.PartNumber"
|
||||
SearchFunc="@PartNumberSearch"
|
||||
ResetValueOnEmptyText
|
||||
CoerceText />
|
||||
}
|
||||
<MudSelect T="string"
|
||||
Label="Affected Customer"
|
||||
Required
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=mrbAction.Customer
|
||||
Text="@mrbAction.Customer">
|
||||
@foreach (string customer in customerNames) {
|
||||
<MudSelectItem Value="@(customer)" />
|
||||
}
|
||||
</MudSelect>
|
||||
<MudTextField T="int"
|
||||
InputType="@InputType.Number"
|
||||
Label="Qty"
|
||||
@ -49,15 +82,6 @@
|
||||
RequiredError="You must supply a quantity!"
|
||||
@bind-Value=mrbAction.Quantity
|
||||
Text="@mrbAction.Quantity.ToString()" />
|
||||
<MudAutocomplete T="string"
|
||||
Label="Part Number"
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=mrbAction.PartNumber
|
||||
Text="@mrbAction.PartNumber"
|
||||
SearchFunc="@PartNumberSearch"
|
||||
ResetValueOnEmptyText
|
||||
CoerceText />
|
||||
<MudAutocomplete T="string"
|
||||
Label="Batch Number / Lot Number"
|
||||
Variant="Variant.Outlined"
|
||||
@ -130,6 +154,11 @@
|
||||
|
||||
private IEnumerable<string> customerNames = new List<string>();
|
||||
|
||||
private string convertFromCustomer = string.Empty;
|
||||
private string convertFromPart = string.Empty;
|
||||
private string convertToCustomer = string.Empty;
|
||||
private string convertToPart = string.Empty;
|
||||
|
||||
private bool isVisible { get; set; }
|
||||
private string[] errors = { };
|
||||
private bool processingSave = false;
|
||||
@ -145,10 +174,34 @@
|
||||
actions = (await mrbService.GetMRBActionsForMRB(mrbAction.MRBNumber, false)).OrderByDescending(a => a.ActionID);
|
||||
|
||||
if (actions is not null && actions.Count() > 0) {
|
||||
if (string.IsNullOrWhiteSpace(mrbAction.Action))
|
||||
mrbAction.Action = actions.First().Action;
|
||||
if (string.IsNullOrWhiteSpace(mrbAction.Customer))
|
||||
mrbAction.Customer = actions.First().Customer;
|
||||
if (string.IsNullOrWhiteSpace(mrbAction.LotNumber))
|
||||
mrbAction.LotNumber = actions.First().LotNumber;
|
||||
if (string.IsNullOrWhiteSpace(mrbAction.PartNumber))
|
||||
mrbAction.PartNumber = actions.First().PartNumber;
|
||||
if (string.IsNullOrWhiteSpace(mrbAction.Justification))
|
||||
mrbAction.Justification = actions.First().Justification;
|
||||
if (mrbAction.Quantity == 0)
|
||||
mrbAction.Quantity = actions.First().Quantity;
|
||||
|
||||
if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
string[] convertFrom = actions.First().ConvertFrom.Split(" ");
|
||||
if (convertFrom.Length > 1) {
|
||||
convertFromCustomer = convertFrom[0];
|
||||
foreach (string partStr in convertFrom.Skip(1))
|
||||
convertFromPart += partStr;
|
||||
}
|
||||
|
||||
string[] convertTo = actions.First().ConvertTo.Split(" ");
|
||||
if (convertTo.Length > 1) {
|
||||
convertToCustomer = convertTo[0];
|
||||
foreach (string partStr in convertTo.Skip(1))
|
||||
convertToPart += partStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,9 +218,17 @@
|
||||
actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) &&
|
||||
!string.IsNullOrWhiteSpace(mrbAction.PartNumber) &&
|
||||
!string.IsNullOrWhiteSpace(mrbAction.LotNumber);
|
||||
actionIsValid = actionIsValid && mrbAction.Quantity > 0;
|
||||
|
||||
if (mrbAction.Action.Equals("Scrap"))
|
||||
return actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Justification);
|
||||
if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(convertFromCustomer) &&
|
||||
!string.IsNullOrWhiteSpace(convertFromPart) &&
|
||||
!string.IsNullOrWhiteSpace(convertToCustomer) &&
|
||||
!string.IsNullOrWhiteSpace(convertToPart);
|
||||
}
|
||||
|
||||
if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase))
|
||||
actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Justification);
|
||||
|
||||
return actionIsValid;
|
||||
}
|
||||
@ -177,6 +238,11 @@
|
||||
try {
|
||||
if (!FormIsValid()) throw new Exception("You must complete the form before saving!");
|
||||
|
||||
if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
mrbAction.ConvertFrom = $"{convertFromCustomer} {convertFromPart}";
|
||||
mrbAction.ConvertTo = $"{convertToCustomer} {convertToPart}";
|
||||
}
|
||||
|
||||
if (mrbAction.MRBNumber > 0) {
|
||||
if (mrbAction.ActionID <= 0) {
|
||||
await mrbService.CreateMRBAction(mrbAction);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
@if (availableApprovers is not null) {
|
||||
<MudPaper Class="p-2">
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudSelect T="User"
|
||||
Label="Select a User"
|
||||
Required
|
||||
|
151
MesaFabApproval.Client/Pages/Components/PCR3DocumentForm.razor
Normal file
151
MesaFabApproval.Client/Pages/Components/PCR3DocumentForm.razor
Normal file
@ -0,0 +1,151 @@
|
||||
@inject MesaFabApprovalAuthStateProvider authStateProvider
|
||||
@inject NavigationManager navigationManager
|
||||
@inject IPCRBService pcrbService
|
||||
@inject IUserService userService
|
||||
@inject IECNService ecnService
|
||||
@inject ISnackbar snackbar
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudTextField T="string"
|
||||
Label="Document Type"
|
||||
@bind-Value="@document.DocType"
|
||||
@bind-Text="@document.DocType"
|
||||
Disabled
|
||||
AutoGrow />
|
||||
<MudTextField Label="Document Numbers - Rev. & Title"
|
||||
@bind-Value="@document.DocNumbers"
|
||||
@bind-Text="@document.DocNumbers"
|
||||
Immediate
|
||||
AutoGrow
|
||||
AutoFocus />
|
||||
@if (DocNumberIsNA()) {
|
||||
<MudTextField Label="Comments"
|
||||
@bind-Value="@document.Comment"
|
||||
@bind-Text="@document.Comment"
|
||||
Required
|
||||
RequiredError="You must provide a comment"
|
||||
Immediate
|
||||
AutoGrow />
|
||||
} else {
|
||||
<MudTextField @bind-Value="@document.ECNNumber"
|
||||
Required
|
||||
RequiredError="You must provide a valid ECN#"
|
||||
Clearable
|
||||
Variant="Variant.Outlined"
|
||||
InputType="@InputType.Number"
|
||||
Validation="@(new Func<int, Task<string>>(ECNNoIsValid))"
|
||||
Label="ECN#"
|
||||
Immediate
|
||||
AutoGrow />
|
||||
}
|
||||
<MudCheckBox Label="Complete"
|
||||
Color="Color.Tertiary"
|
||||
@bind-Value=complete
|
||||
LabelPosition="LabelPosition.Start" />
|
||||
</MudForm>
|
||||
</MudPaper>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@if ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) ||
|
||||
(!DocNumberIsNA() && ecnNoIsValid)) {
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
Class="m1-auto"
|
||||
OnClick=Save>
|
||||
@if (saveInProcess) {
|
||||
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
|
||||
<MudText>Processing</MudText>
|
||||
} else {
|
||||
<MudText>Save</MudText>
|
||||
}
|
||||
</MudButton>
|
||||
}
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Class="grey text-black m1-auto"
|
||||
OnClick=Cancel>
|
||||
Cancel
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
MudDialogInstance MudDialog { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public required PCR3Document document { get; set; }
|
||||
|
||||
private string[] errors = { };
|
||||
|
||||
private bool complete = false;
|
||||
|
||||
private bool saveInProcess = false;
|
||||
|
||||
private bool ecnNoIsValid = true;
|
||||
|
||||
protected override async Task OnParametersSetAsync() {
|
||||
complete = document.CompletedByID > 0;
|
||||
}
|
||||
|
||||
private async Task Save() {
|
||||
saveInProcess = true;
|
||||
try {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
document.CompletedByID = 0;
|
||||
document.CompletedBy = null;
|
||||
document.CompletedDate = DateTimeUtilities.MAX_DT;
|
||||
}
|
||||
|
||||
if (complete && document.CompletedByID <= 0) {
|
||||
document.CompletedByID = authStateProvider.CurrentUser.UserID;
|
||||
document.CompletedBy = authStateProvider.CurrentUser;
|
||||
document.CompletedDate = DateTime.Now;
|
||||
}
|
||||
|
||||
if (!DocNumberIsNA() && !ecnNoIsValid)
|
||||
throw new Exception($"{document.ECNNumber} is not a valid ECN#");
|
||||
if (DocNumberIsNA() && string.IsNullOrWhiteSpace(document.Comment))
|
||||
throw new Exception("you must provide a comment");
|
||||
|
||||
await pcrbService.UpdatePCR3Document(document);
|
||||
|
||||
await pcrbService.GetPCR3DocumentsForPlanNumber(document.PlanNumber, true);
|
||||
|
||||
saveInProcess = false;
|
||||
|
||||
MudDialog.Close(DialogResult.Ok(document));
|
||||
} catch (Exception ex) {
|
||||
saveInProcess = false;
|
||||
snackbar.Add($"Unable to save document, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel() {
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
private bool DocNumberIsNA() {
|
||||
if (document.DocNumbers.ToLower().Equals("na") ||
|
||||
document.DocNumbers.ToLower().Equals("n/a")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<string> ECNNoIsValid(int ecnNumber) {
|
||||
string? result = await ecnService.ECNNumberIsValidStr(ecnNumber);
|
||||
if (result is null) ecnNoIsValid = true;
|
||||
else ecnNoIsValid = false;
|
||||
StateHasChanged();
|
||||
return result;
|
||||
}
|
||||
}
|
201
MesaFabApproval.Client/Pages/Components/PCRBActionItemForm.razor
Normal file
201
MesaFabApproval.Client/Pages/Components/PCRBActionItemForm.razor
Normal file
@ -0,0 +1,201 @@
|
||||
@inject MesaFabApprovalAuthStateProvider authStateProvider
|
||||
@inject NavigationManager navigationManager
|
||||
@inject IPCRBService pcrbService
|
||||
@inject IUserService userService
|
||||
@inject ISnackbar snackbar
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudTextField T="string"
|
||||
Label="Action"
|
||||
Required
|
||||
RequiredError="Enter action item"
|
||||
@bind-Value="@name"
|
||||
@bind-Text="@name"
|
||||
Immediate
|
||||
Clearable
|
||||
AutoGrow
|
||||
AutoFocus />
|
||||
<MudCheckBox Label="Gating"
|
||||
Color="Color.Tertiary"
|
||||
@bind-Value=gating
|
||||
LabelPosition="LabelPosition.Start" />
|
||||
<MudCheckBox Label="Closed"
|
||||
Color="Color.Tertiary"
|
||||
@bind-Value="@closedStatus"
|
||||
LabelPosition="LabelPosition.Start" />
|
||||
@if (closedStatus) {
|
||||
<MudDatePicker Label="Closed Date"
|
||||
Color="Color.Tertiary"
|
||||
@bind-Date="@closedDate"
|
||||
Clearable
|
||||
MinDate="@DateTimeUtilities.MIN_DT"
|
||||
MaxDate="@DateTimeUtilities.MAX_DT"
|
||||
Placeholder="Select a closed date" />
|
||||
}
|
||||
<MudSelect T="User"
|
||||
Label="Responsible Person"
|
||||
Variant="Variant.Outlined"
|
||||
Required
|
||||
RequiredError="You must select a responsible person"
|
||||
Clearable
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
ToStringFunc="@UserToNameConverter"
|
||||
@bind-Value=@responsiblePerson>
|
||||
@foreach (User user in allActiveUsers.OrderBy(u => u.FirstName)) {
|
||||
<MudSelectItem T="User" Value="@(user)" />
|
||||
}
|
||||
</MudSelect>
|
||||
</MudForm>
|
||||
</MudPaper>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
Class="m1-auto"
|
||||
OnClick=Save>
|
||||
@if (saveActionItemInProcess) {
|
||||
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
|
||||
<MudText>Processing</MudText>
|
||||
} else {
|
||||
<MudText>Submit</MudText>
|
||||
}
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Class="grey text-black m1-auto"
|
||||
OnClick=Cancel>
|
||||
Cancel
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
MudDialogInstance MudDialog { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int planNumber { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public int step { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public PCRBActionItem? actionItem { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<User> allActiveUsers { get; set; }
|
||||
|
||||
private string[] errors = { };
|
||||
|
||||
private string name = "";
|
||||
private bool gating = false;
|
||||
private DateTime? closedDate = DateTimeUtilities.MAX_DT;
|
||||
private bool closedStatus = false;
|
||||
private User? responsiblePerson = null;
|
||||
|
||||
private bool saveActionItemInProcess = false;
|
||||
|
||||
protected override async Task OnParametersSetAsync() {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
}
|
||||
|
||||
if (planNumber <= 0) {
|
||||
snackbar.Add($"{planNumber} is not a valid PCRB plan#", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
if (allActiveUsers is null || allActiveUsers.Count() <= 0)
|
||||
allActiveUsers = await userService.GetAllActiveUsers();
|
||||
|
||||
if (actionItem is not null) {
|
||||
name = actionItem.Name;
|
||||
gating = actionItem.Gating;
|
||||
closedStatus = actionItem.ClosedStatus;
|
||||
closedDate = actionItem.ClosedDate;
|
||||
if (closedDate.Equals(DateTimeUtilities.MAX_DT)) {
|
||||
closedDate = DateTime.Now;
|
||||
}
|
||||
if (actionItem.ResponsiblePersonID > 0) {
|
||||
if (actionItem.ResponsiblePerson is not null) responsiblePerson = actionItem.ResponsiblePerson;
|
||||
else responsiblePerson = await userService.GetUserByUserId(actionItem.ResponsiblePersonID);
|
||||
actionItem.ResponsiblePerson = responsiblePerson;
|
||||
}
|
||||
} else {
|
||||
name = "";
|
||||
gating = false;
|
||||
closedStatus = false;
|
||||
closedDate = DateTime.Now;
|
||||
responsiblePerson = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Save() {
|
||||
saveActionItemInProcess = true;
|
||||
try {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new Exception("name missing");
|
||||
|
||||
if (actionItem is null) {
|
||||
actionItem = new() {
|
||||
Name = name,
|
||||
UploadedBy = authStateProvider.CurrentUser,
|
||||
UploadedByID = authStateProvider.CurrentUser.UserID,
|
||||
PlanNumber = planNumber,
|
||||
Step = step,
|
||||
Gating = gating,
|
||||
ClosedStatus = closedStatus,
|
||||
ResponsiblePerson = responsiblePerson,
|
||||
ResponsiblePersonID = responsiblePerson.UserID,
|
||||
ClosedDate = closedDate,
|
||||
ClosedBy = closedDate is null || closedDate >= DateTimeUtilities.MAX_DT ? null : authStateProvider.CurrentUser,
|
||||
ClosedByID = closedStatus ? authStateProvider.CurrentUser.UserID : 0
|
||||
};
|
||||
|
||||
if (actionItem.ClosedStatus == false) {
|
||||
actionItem.ClosedDate = DateTimeUtilities.MAX_DT;
|
||||
}
|
||||
|
||||
await pcrbService.CreateNewActionItem(actionItem);
|
||||
} else {
|
||||
actionItem.Name = name;
|
||||
actionItem.Gating = gating;
|
||||
actionItem.ClosedStatus = closedStatus;
|
||||
actionItem.ClosedDate = closedDate;
|
||||
if (closedStatus) {
|
||||
actionItem.ClosedBy = authStateProvider.CurrentUser;
|
||||
actionItem.ClosedByID = authStateProvider.CurrentUser.UserID;
|
||||
} else {
|
||||
actionItem.ClosedDate = DateTimeUtilities.MAX_DT;
|
||||
}
|
||||
actionItem.ResponsiblePerson = responsiblePerson;
|
||||
if (responsiblePerson is not null)
|
||||
actionItem.ResponsiblePersonID = responsiblePerson.UserID;
|
||||
|
||||
await pcrbService.UpdateActionItem(actionItem);
|
||||
}
|
||||
|
||||
saveActionItemInProcess = false;
|
||||
|
||||
MudDialog.Close(DialogResult.Ok(actionItem));
|
||||
} catch (Exception ex) {
|
||||
saveActionItemInProcess = false;
|
||||
snackbar.Add($"Unable to save action item, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel() {
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
private Func<User, string> UserToNameConverter = u => u is null ? string.Empty : u.GetFullName();
|
||||
|
||||
private Func<PCRBAttachment, string> AttachmentToFileNameConverter = a => a is null ? "" : a.FileName;
|
||||
}
|
250
MesaFabApproval.Client/Pages/Components/PCRBApproverForm.razor
Normal file
250
MesaFabApproval.Client/Pages/Components/PCRBApproverForm.razor
Normal file
@ -0,0 +1,250 @@
|
||||
@inject MesaFabApprovalAuthStateProvider authStateProvider
|
||||
@inject NavigationManager navigationManager
|
||||
@inject IPCRBService pcrbService
|
||||
@inject IUserService userService
|
||||
@inject IApprovalService approvalService
|
||||
@inject ISnackbar snackbar
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudSelect T="string"
|
||||
Label="Job Title"
|
||||
Required
|
||||
RequiredError="You must provide a job title"
|
||||
ValueChanged="@SelectedJobTitleChanged"
|
||||
@bind-Text="@selectedJobTitle"
|
||||
Immediate
|
||||
Disabled="@(approval is not null && !string.IsNullOrWhiteSpace(selectedJobTitle))"
|
||||
Clearable
|
||||
AutoFocus >
|
||||
@foreach (string jt in availableJobTitles) {
|
||||
<MudSelectItem Value="@jt">@jt</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect T="User"
|
||||
Label="Select a User"
|
||||
Required
|
||||
Clearable
|
||||
Disabled="@(string.IsNullOrWhiteSpace(selectedJobTitle))"
|
||||
Variant="Variant.Outlined"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
@bind-Value=selectedUser
|
||||
ToStringFunc="@UserToNameConverter">
|
||||
@foreach (User user in availableUsers) {
|
||||
<MudSelectItem Value="@user">@user.GetFullName()</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudForm>
|
||||
</MudPaper>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
Class="m1-auto"
|
||||
OnClick=Save>
|
||||
@if (saveAttendeeInProcess) {
|
||||
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
|
||||
<MudText>Processing</MudText>
|
||||
} else {
|
||||
<MudText>Submit</MudText>
|
||||
}
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Class="grey text-black m1-auto"
|
||||
OnClick=Cancel>
|
||||
Cancel
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
MudDialogInstance MudDialog { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int planNumber { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public int step { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public Approval? approval { get; set; } = null;
|
||||
|
||||
private HashSet<string> availableJobTitles = new();
|
||||
|
||||
private Dictionary<string, SubRole> jobTitleToSubRoleMap = new();
|
||||
|
||||
private Dictionary<string, IEnumerable<User>> jobTitleToAvailableUsersMap = new();
|
||||
|
||||
private HashSet<User> availableUsers = new();
|
||||
|
||||
private string[] errors = { };
|
||||
|
||||
private string selectedJobTitle = "";
|
||||
private User? selectedUser = null;
|
||||
|
||||
private bool saveAttendeeInProcess = false;
|
||||
|
||||
protected override async Task OnParametersSetAsync() {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
}
|
||||
|
||||
if (planNumber <= 0) {
|
||||
snackbar.Add($"{planNumber} is not a valid PCRB plan#", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
await GetAttendees();
|
||||
|
||||
if (approval is not null) {
|
||||
selectedJobTitle = approval.RoleName;
|
||||
if (approval.UserID > 0) {
|
||||
if (approval.User is not null) {
|
||||
selectedUser = approval.User;
|
||||
} else {
|
||||
selectedUser = await userService.GetUserByUserId(approval.UserID);
|
||||
approval.User = selectedUser;
|
||||
}
|
||||
}
|
||||
|
||||
SelectedJobTitleChanged(selectedJobTitle);
|
||||
} else {
|
||||
selectedJobTitle = "";
|
||||
selectedUser = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Save() {
|
||||
saveAttendeeInProcess = true;
|
||||
try {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(selectedJobTitle)) throw new Exception("job title missing");
|
||||
if (selectedUser is null) throw new Exception("attendee not selected");
|
||||
|
||||
PCRB pcrb = await pcrbService.GetPCRBByPlanNumber(planNumber, false);
|
||||
|
||||
if (approval is null) {
|
||||
jobTitleToSubRoleMap.TryGetValue($"{selectedJobTitle}{selectedUser.UserID}", out SubRole? subRole);
|
||||
|
||||
if (subRole is null) throw new Exception($"no approval role found for job title {selectedJobTitle}");
|
||||
|
||||
approval = new() {
|
||||
RoleName = subRole.SubRoleCategoryItem,
|
||||
SubRole = subRole.SubRoleName,
|
||||
SubRoleID = subRole.SubRoleID,
|
||||
IssueID = planNumber,
|
||||
Step = step,
|
||||
User = selectedUser,
|
||||
UserID = selectedUser.UserID,
|
||||
AssignedDate = DateTimeUtilities.MIN_DT
|
||||
};
|
||||
|
||||
await approvalService.CreateApproval(approval);
|
||||
} else {
|
||||
int originalUserId = approval.UserID;
|
||||
|
||||
approval.UserID = selectedUser.UserID;
|
||||
approval.User = selectedUser;
|
||||
|
||||
if (originalUserId != approval.UserID) {
|
||||
if (approval.AssignedDate > DateTimeUtilities.MIN_DT)
|
||||
approval.AssignedDate = DateTime.Now;
|
||||
approval.NotifyDate = DateTimeUtilities.MIN_DT;
|
||||
}
|
||||
|
||||
await approvalService.UpdateApproval(approval);
|
||||
|
||||
if (originalUserId != approval.UserID)
|
||||
await pcrbService.NotifyNewApprovals(pcrb);
|
||||
}
|
||||
|
||||
saveAttendeeInProcess = false;
|
||||
|
||||
MudDialog.Close(DialogResult.Ok(approval));
|
||||
} catch (Exception ex) {
|
||||
saveAttendeeInProcess = false;
|
||||
snackbar.Add($"Unable to save attendee, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel() {
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
private Func<User, string> UserToNameConverter = u => u is null ? string.Empty : u.GetFullName();
|
||||
|
||||
private async Task GetAttendees() {
|
||||
int roleId = await approvalService.GetRoleIdForRoleName("Module Manager");
|
||||
|
||||
if (roleId <= 0) throw new Exception($"could not find Director role ID");
|
||||
|
||||
availableJobTitles.Clear();
|
||||
jobTitleToAvailableUsersMap.Clear();
|
||||
jobTitleToSubRoleMap.Clear();
|
||||
|
||||
IEnumerable<SubRole> subRoles = await approvalService.GetSubRolesForSubRoleName("MMSubRole", roleId);
|
||||
|
||||
HashSet<string> defaultSubRoleCategoryItems = new() { "Si Production", "Si Engineering", "Quality" };
|
||||
HashSet<string> unusedSubRoleCategoryItems = new() { "GaN Engineering", "GaN Operations", "Integration" };
|
||||
foreach (SubRole subRole in subRoles) {
|
||||
if (approval is null) {
|
||||
if (!defaultSubRoleCategoryItems.Contains(subRole.SubRoleCategoryItem) &&
|
||||
!unusedSubRoleCategoryItems.Contains(subRole.SubRoleCategoryItem)) {
|
||||
availableJobTitles.Add(subRole.SubRoleCategoryItem);
|
||||
|
||||
IEnumerable<User> subRoleMembers = await approvalService.GetApprovalGroupMembers(subRole.SubRoleID);
|
||||
|
||||
jobTitleToAvailableUsersMap.Add(subRole.SubRoleCategoryItem, subRoleMembers);
|
||||
|
||||
foreach (User member in subRoleMembers) {
|
||||
jobTitleToSubRoleMap.Add($"{subRole.SubRoleCategoryItem}{member.UserID}", subRole);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!unusedSubRoleCategoryItems.Contains(subRole.SubRoleCategoryItem)) {
|
||||
IEnumerable<User> subRoleMembers = await approvalService.GetApprovalGroupMembers(subRole.SubRoleID);
|
||||
|
||||
jobTitleToAvailableUsersMap.Add(subRole.SubRoleCategoryItem, subRoleMembers);
|
||||
|
||||
foreach (User member in subRoleMembers)
|
||||
availableUsers.Add(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectedJobTitleChanged(string jobTitle) {
|
||||
selectedJobTitle = jobTitle;
|
||||
|
||||
selectedUser = null;
|
||||
|
||||
availableUsers.Clear();
|
||||
|
||||
if (approval is null) {
|
||||
if (jobTitleToAvailableUsersMap.TryGetValue(jobTitle, out IEnumerable<User>? jobTitleMembers)) {
|
||||
if (jobTitleMembers is not null) {
|
||||
foreach (User member in jobTitleMembers)
|
||||
availableUsers.Add(member);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach (IEnumerable<User> memberList in jobTitleToAvailableUsersMap.Values) {
|
||||
if (memberList is not null) {
|
||||
foreach(User member in memberList) {
|
||||
availableUsers.Add(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
140
MesaFabApproval.Client/Pages/Components/PCRBAttachmentForm.razor
Normal file
140
MesaFabApproval.Client/Pages/Components/PCRBAttachmentForm.razor
Normal file
@ -0,0 +1,140 @@
|
||||
@inject MesaFabApprovalAuthStateProvider authStateProvider
|
||||
@inject NavigationManager navigationManager
|
||||
@inject IPCRBService pcrbService
|
||||
@inject ISnackbar snackbar
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudPaper Class="m-2 p-2">
|
||||
<MudForm @bind-Errors="@errors">
|
||||
<MudTextField T="string"
|
||||
Label="File Name"
|
||||
Disabled
|
||||
Immediate
|
||||
@bind-Value="@fileName"
|
||||
@bind-Text="@fileName"
|
||||
AutoGrow />
|
||||
<MudFileUpload T="IBrowserFile"
|
||||
FilesChanged="AddFile"
|
||||
Required
|
||||
Disabled="@(!string.IsNullOrWhiteSpace(fileName))"
|
||||
RequiredError="You must select a file">
|
||||
<ActivatorContent>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
style="margin: auto;"
|
||||
StartIcon="@Icons.Material.Filled.AttachFile">
|
||||
@if (addFileInProcess) {
|
||||
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
|
||||
<MudText>Processing</MudText>
|
||||
} else {
|
||||
<MudText>Add File</MudText>
|
||||
}
|
||||
</MudButton>
|
||||
</ActivatorContent>
|
||||
</MudFileUpload>
|
||||
</MudForm>
|
||||
</MudPaper>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Tertiary"
|
||||
Class="m1-auto"
|
||||
OnClick=Submit>
|
||||
@if (processing) {
|
||||
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
|
||||
<MudText>Processing</MudText>
|
||||
}
|
||||
else {
|
||||
<MudText>Submit</MudText>
|
||||
}
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Class="grey text-black m1-auto"
|
||||
OnClick=Cancel>
|
||||
Cancel
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
[CascadingParameter] MudDialogInstance MudDialog { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int planNumber { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public int step { get; set; } = 0;
|
||||
|
||||
private string[] errors = { };
|
||||
|
||||
private string fileName = "";
|
||||
|
||||
private IBrowserFile? file = null;
|
||||
|
||||
private bool addFileInProcess = false;
|
||||
private bool processing = false;
|
||||
|
||||
protected override async Task OnParametersSetAsync() {
|
||||
if (planNumber <= 0) {
|
||||
snackbar.Add($"{planNumber} is not a valid PCRB plan#", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
if (step <= 0) {
|
||||
snackbar.Add($"{step} is not a valid PCRB stage#", Severity.Error);
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
}
|
||||
}
|
||||
|
||||
private void AddFile(IBrowserFile newFile) {
|
||||
addFileInProcess = true;
|
||||
file = newFile;
|
||||
fileName = newFile.Name;
|
||||
addFileInProcess = false;
|
||||
}
|
||||
|
||||
private async Task Submit() {
|
||||
processing = true;
|
||||
try {
|
||||
if (authStateProvider.CurrentUser is null) {
|
||||
await authStateProvider.Logout();
|
||||
navigationManager.NavigateTo("login");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(fileName))
|
||||
throw new Exception("file name missing");
|
||||
|
||||
if (file is null)
|
||||
throw new Exception("file is missing");
|
||||
|
||||
PCRBAttachment attachment = new() {
|
||||
Step = step,
|
||||
UploadDateTime = DateTime.Now,
|
||||
UploadedByID = authStateProvider.CurrentUser.UserID,
|
||||
PlanNumber = planNumber,
|
||||
File = file,
|
||||
FileName = fileName
|
||||
};
|
||||
|
||||
await pcrbService.UploadAttachment(attachment);
|
||||
|
||||
processing = false;
|
||||
|
||||
MudDialog.Close(DialogResult.Ok(attachment));
|
||||
} catch (Exception ex) {
|
||||
snackbar.Add($"Unable to save document, because {ex.Message}", Severity.Error);
|
||||
processing = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel() {
|
||||
MudDialog.Close(DialogResult.Cancel());
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
@inject NavigationManager navigationManager
|
||||
@inject ISnackbar snackbar
|
||||
@inject IMRBService mrbService
|
||||
@inject IPCRBService pcrbService
|
||||
@inject IECNService ecnService
|
||||
@inject ICAService caService
|
||||
@inject IJSRuntime jsRuntime
|
||||
@ -88,6 +89,7 @@
|
||||
<MudSpacer />
|
||||
<MudTextField @bind-Value="mrbSearchString"
|
||||
Placeholder="Search"
|
||||
Immediate
|
||||
Adornment="Adornment.Start"
|
||||
AdornmentIcon="@Icons.Material.Filled.Search"
|
||||
IconSize="Size.Medium"
|
||||
@ -147,21 +149,100 @@
|
||||
</MudOverlay>
|
||||
}
|
||||
</MudTabPanel>
|
||||
<MudTabPanel Text="My PCRBs" Style="min-width:50%; text-align: center;">
|
||||
@if (stateProvider.CurrentUser is not null && myPCRBs is not null && !myPcrbsProcessing) {
|
||||
<MudPaper Outlined="true"
|
||||
Class="p-2 m-2 d-flex flex-column justify-center">
|
||||
<MudText Typo="Typo.h4" Align="Align.Center">My PCRBs</MudText>
|
||||
<MudDivider DividerType="DividerType.Middle" Class="my-2" />
|
||||
<MudTable Items="@myPCRBs"
|
||||
Class="m-2"
|
||||
Striped
|
||||
SortLabel="Sort by"
|
||||
Filter="new Func<PCRB, bool>(FilterFuncForPCRBTable)">
|
||||
<ToolBarContent>
|
||||
<MudSpacer />
|
||||
<MudTextField @bind-Value="pcrbSearchString"
|
||||
Placeholder="Search"
|
||||
Adornment="Adornment.Start"
|
||||
Immediate
|
||||
AdornmentIcon="@Icons.Material.Filled.Search"
|
||||
IconSize="Size.Medium"
|
||||
Class="mt-0" />
|
||||
</ToolBarContent>
|
||||
<HeaderContent>
|
||||
<MudTh>
|
||||
<MudTableSortLabel InitialDirection="SortDirection.Descending" SortBy="new Func<PCRB,object>(x=>x.PlanNumber)">
|
||||
PCRB#
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.Title)">
|
||||
Title
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.CurrentStep)">
|
||||
Current Step
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.InsertTimeStamp)">
|
||||
Submitted Date
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.LastUpdateDate)">
|
||||
Last Updated
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.ClosedDate)">
|
||||
Completed Date
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd DataLabel="PCRB#">
|
||||
<MudLink OnClick="@(() => GoTo($"pcrb/{context.PlanNumber}"))">@context.PlanNumber</MudLink>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Title">@context.Title</MudTd>
|
||||
<MudTd DataLabel="Current Step">@(GetCurrentPCRBStep(context.CurrentStep))</MudTd>
|
||||
<MudTd DataLabel="Submitted Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.InsertTimeStamp)</MudTd>
|
||||
<MudTd DataLabel="Last Updated">@DateTimeUtilities.GetDateAsStringMinDefault(context.LastUpdateDate)</MudTd>
|
||||
<MudTd DataLabel="Completed Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.ClosedDate)</MudTd>
|
||||
</RowTemplate>
|
||||
<PagerContent>
|
||||
<MudTablePager />
|
||||
</PagerContent>
|
||||
</MudTable>
|
||||
</MudPaper>
|
||||
} else {
|
||||
<MudOverlay Visible DarkBackground="true" AutoClose="false">
|
||||
<MudText Align="Align.Center" Typo="Typo.h3">Processing</MudText>
|
||||
<MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" />
|
||||
</MudOverlay>
|
||||
}
|
||||
</MudTabPanel>
|
||||
</MudTabs>
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
private IEnumerable<Approval> approvalList = new List<Approval>();
|
||||
private IEnumerable<MRB> myMRBs = new List<MRB>();
|
||||
private IEnumerable<PCRB> myPCRBs = new List<PCRB>();
|
||||
|
||||
private IEnumerable<int> ecnNumbers = new HashSet<int>();
|
||||
private IEnumerable<int> caNumbers = new HashSet<int>();
|
||||
private IEnumerable<int> mrbNumbers = new HashSet<int>();
|
||||
private IEnumerable<int> pcrbNumbers = new HashSet<int>();
|
||||
|
||||
private bool myApprovalsProcessing = false;
|
||||
private bool myMrbsProcessing = false;
|
||||
private bool myPcrbsProcessing = false;
|
||||
|
||||
private string mrbSearchString = "";
|
||||
private string pcrbSearchString = "";
|
||||
|
||||
protected async override Task OnParametersSetAsync() {
|
||||
try {
|
||||
@ -178,9 +259,17 @@
|
||||
.ToList()
|
||||
.OrderByDescending(x => x.SubmittedDate);
|
||||
myMrbsProcessing = false;
|
||||
|
||||
myPcrbsProcessing = true;
|
||||
myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID)
|
||||
.ToList()
|
||||
.OrderByDescending(p => p.InsertTimeStamp);
|
||||
myPcrbsProcessing = false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
myApprovalsProcessing = false;
|
||||
myMrbsProcessing = false;
|
||||
myPcrbsProcessing = false;
|
||||
snackbar.Add($"Unable to load the dashboard, because {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
@ -191,12 +280,15 @@
|
||||
bool isEcn = false;
|
||||
bool isCa = false;
|
||||
bool isMrb = false;
|
||||
bool isPcrb = false;
|
||||
if (ecnNumbers.Contains(issueId))
|
||||
isEcn = true;
|
||||
if (caNumbers.Contains(issueId))
|
||||
isCa = true;
|
||||
if (mrbNumbers.Contains(issueId))
|
||||
isMrb = true;
|
||||
if (pcrbNumbers.Contains(issueId))
|
||||
isPcrb = true;
|
||||
|
||||
if (!isEcn && !isCa && !isMrb) {
|
||||
Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId);
|
||||
@ -208,6 +300,9 @@
|
||||
Task<bool> isMrbTask = mrbService.NumberIsValid(issueId);
|
||||
tasks.Add(isMrbTask);
|
||||
|
||||
Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId);
|
||||
tasks.Add(isPcrbTask);
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
if (isEcnTask.Result) {
|
||||
@ -216,12 +311,15 @@
|
||||
isCa = true;
|
||||
} else if (isMrbTask.Result) {
|
||||
isMrb = true;
|
||||
} else if (isPcrbTask.Result) {
|
||||
isPcrb = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", "");
|
||||
if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", "");
|
||||
if (isMrb) GoTo($"mrb/{issueId}");
|
||||
if (isPcrb) GoTo($"pcrb/{issueId}");
|
||||
}
|
||||
|
||||
private void GoTo(string page) {
|
||||
@ -245,4 +343,21 @@
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString);
|
||||
|
||||
private bool PCRBFilterFunc(PCRB pcrb, string searchString) {
|
||||
if (string.IsNullOrWhiteSpace(searchString))
|
||||
return true;
|
||||
if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
|
||||
return true;
|
||||
if (pcrb.PlanNumber.ToString().Contains(searchString.Trim()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetCurrentPCRBStep(int step) {
|
||||
if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty;
|
||||
else return PCRB.Stages[step];
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
||||
<HeaderContent>
|
||||
<MudTh>
|
||||
<MudTableSortLabel InitialDirection="SortDirection.Descending" SortBy="new Func<PCRB,object>(x=>x.PlanNumber)">
|
||||
Plan#
|
||||
Change#
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>
|
||||
@ -43,6 +43,7 @@
|
||||
Owner
|
||||
</MudTableSortLabel>
|
||||
</MudTh>
|
||||
<MudTh>Stage</MudTh>
|
||||
<MudTh>
|
||||
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.InsertTimeStamp)">
|
||||
Submitted Date
|
||||
@ -65,6 +66,7 @@
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Title">@context.Title</MudTd>
|
||||
<MudTd DataLabel="Owner">@context.OwnerName</MudTd>
|
||||
<MudTd DataLabel="Stage">@(GetStageName(context.CurrentStep))</MudTd>
|
||||
<MudTd DataLabel="Submitted Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.InsertTimeStamp)</MudTd>
|
||||
<MudTd DataLabel="Last Updated">@DateTimeUtilities.GetDateAsStringMinDefault(context.LastUpdateDate)</MudTd>
|
||||
<MudTd DataLabel="Closed Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.ClosedDate)</MudTd>
|
||||
@ -116,4 +118,9 @@
|
||||
cache.Set("redirectUrl", page);
|
||||
navigationManager.NavigateTo(page);
|
||||
}
|
||||
|
||||
private string GetStageName(int step) {
|
||||
if (step >= PCRB.Stages.Length || step < 0) return "";
|
||||
return PCRB.Stages[step];
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,9 @@ WebAssemblyHostBuilder builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
string _apiBaseUrl = builder.Configuration["FabApprovalApiBaseUrl"] ??
|
||||
throw new NullReferenceException("FabApprovalApiBaseUrl not found in config");
|
||||
|
||||
string _oldSiteUrl = builder.Configuration["OldFabApprovalUrl"] ??
|
||||
throw new NullReferenceException("OldFabApprovalUrl not found in config");
|
||||
|
||||
builder.Services.AddTransient<ApiHttpClientHandler>();
|
||||
|
||||
builder.Services
|
||||
@ -30,6 +33,12 @@ builder.Services
|
||||
})
|
||||
.AddHttpMessageHandler<ApiHttpClientHandler>();
|
||||
|
||||
builder.Services
|
||||
.AddHttpClient("OldSite", client => {
|
||||
client.BaseAddress = new Uri(_oldSiteUrl);
|
||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
|
||||
});
|
||||
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
builder.Services.AddMudServices(config => {
|
||||
|
@ -289,7 +289,7 @@ public class ApprovalService : IApprovalService {
|
||||
if (members is null || members.Count() <= 0)
|
||||
throw new Exception($"unable to find group members for sub role {subRoleId}");
|
||||
|
||||
_cache.Set($"approvalMembers{subRoleId}", members, DateTimeOffset.Now.AddMinutes(15));
|
||||
_cache.Set($"approvalMembers{subRoleId}", members, DateTimeOffset.Now.AddMinutes(2));
|
||||
} else {
|
||||
throw new Exception($"Unable to get group members, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
@ -165,9 +165,7 @@ public class AuthenticationService : IAuthenticationService {
|
||||
await _localStorageService.AddItem("MesaFabApprovalUserId", loginId);
|
||||
}
|
||||
|
||||
public async Task SetCurrentUser(User user) {
|
||||
if (user is null) throw new ArgumentNullException("User cannot be null");
|
||||
|
||||
public async Task SetCurrentUser(User? user) {
|
||||
_cache.Set<User>("MesaFabApprovalCurrentUser", user);
|
||||
await _localStorageService.AddItem<User>("MesaFabApprovalCurrentUser", user);
|
||||
}
|
||||
@ -182,8 +180,10 @@ public class AuthenticationService : IAuthenticationService {
|
||||
public async Task<User> GetCurrentUser() {
|
||||
User? currentUser = null;
|
||||
|
||||
currentUser = _cache.Get<User>("MesaFabApprovalCurrentUser") ??
|
||||
await _localStorageService.GetItem<User>("MesaFabApprovalCurrentUser");
|
||||
currentUser = _cache.Get<User>("MesaFabApprovalCurrentUser");
|
||||
|
||||
if (currentUser is null)
|
||||
currentUser = await _localStorageService.GetItem<User>("MesaFabApprovalCurrentUser");
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
@ -46,6 +46,16 @@ public class MesaFabApprovalAuthStateProvider : AuthenticationStateProvider, IDi
|
||||
CurrentUser = await _authService.GetCurrentUser();
|
||||
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));
|
||||
|
||||
if (CurrentUser is null) {
|
||||
string loginId = _userService.GetLoginIdFromClaimsPrincipal(principal);
|
||||
|
||||
User? user = await _userService.GetUserByLoginId(loginId);
|
||||
|
||||
await _authService.SetCurrentUser(user);
|
||||
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoginAsync(string loginId, string password) {
|
||||
|
@ -1,8 +1,11 @@
|
||||
using System.Text;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using MesaFabApproval.Shared.Models;
|
||||
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
using MudBlazor;
|
||||
@ -11,28 +14,52 @@ namespace MesaFabApproval.Client.Services;
|
||||
|
||||
public interface IPCRBService {
|
||||
Task<string> IdIsValid(string id);
|
||||
Task<bool> IdIsValid(int id);
|
||||
Task<IEnumerable<PCRB>> GetAllPCRBs(bool bypassCache);
|
||||
Task CreateNewPCRB(PCRB pcrb);
|
||||
Task<PCRB> GetPCRBByPlanNumber(int planNumber, bool bypassCache);
|
||||
Task<PCRB> GetPCRBByTitle(string title, bool bypassCache);
|
||||
Task UpdatePCRB(PCRB pcrb);
|
||||
Task DeletePCRB(int planNumber);
|
||||
Task UploadAttachment(PCRBAttachment attachment);
|
||||
Task<IEnumerable<PCRBAttachment>> GetAttachmentsByPlanNumber(int planNumber, bool bypassCache);
|
||||
Task UpdateAttachment(PCRBAttachment attachment);
|
||||
Task DeleteAttachment(PCRBAttachment attachment);
|
||||
Task CreateNewActionItem(PCRBActionItem actionItem);
|
||||
Task UpdateActionItem(PCRBActionItem actionItem);
|
||||
Task DeleteActionItem(int id);
|
||||
Task<IEnumerable<PCRBActionItem>> GetActionItemsForPlanNumber(int planNumber, bool bypassCache);
|
||||
Task CreateNewAttendee(PCRBAttendee attendee);
|
||||
Task UpdateAttendee(PCRBAttendee attendee);
|
||||
Task DeleteAttendee(int id);
|
||||
Task<IEnumerable<PCRBAttendee>> GetAttendeesByPlanNumber(int planNumber, bool bypassCache);
|
||||
Task CreatePCR3Document(PCR3Document document);
|
||||
Task UpdatePCR3Document(PCR3Document document);
|
||||
Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache);
|
||||
Task NotifyNewApprovals(PCRB pcrb);
|
||||
Task NotifyApprovers(PCRBNotification notification);
|
||||
Task NotifyOriginator(PCRBNotification notification);
|
||||
Task NotifyResponsiblePerson(PCRBActionItemNotification notification);
|
||||
}
|
||||
|
||||
public class PCRBService : IPCRBService {
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ISnackbar _snackbar;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public PCRBService(IMemoryCache cache, IHttpClientFactory httpClientFactory, ISnackbar snackbar) {
|
||||
public PCRBService(IMemoryCache cache,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ISnackbar snackbar,
|
||||
IUserService userService) {
|
||||
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected");
|
||||
_snackbar = snackbar ?? throw new ArgumentNullException("ISnackbar not injected");
|
||||
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
|
||||
}
|
||||
|
||||
public async Task<string> IdIsValid(string id) {
|
||||
bool isMatch = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(id)) isMatch = false;
|
||||
|
||||
try {
|
||||
@ -63,6 +90,37 @@ public class PCRBService : IPCRBService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> IdIsValid(int id) {
|
||||
bool isMatch = true;
|
||||
if (id <= 0) isMatch = false;
|
||||
|
||||
try {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/getByPlanNumber?planNumber={id}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
PCRB? pcrb = JsonSerializer.Deserialize<PCRB>(responseContent, jsonSerializerOptions);
|
||||
|
||||
if (pcrb is null) isMatch = false;
|
||||
} else {
|
||||
isMatch = false;
|
||||
}
|
||||
} catch (Exception) {
|
||||
isMatch = false;
|
||||
}
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCRB>> GetAllPCRBs(bool bypassCache) {
|
||||
try {
|
||||
IEnumerable<PCRB>? allPCRBs = null;
|
||||
@ -219,7 +277,7 @@ public class PCRBService : IPCRBService {
|
||||
}
|
||||
|
||||
public async Task UpdatePCRB(PCRB pcrb) {
|
||||
if (pcrb is null) throw new ArgumentNullException("MRB cannot be null");
|
||||
if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
@ -251,7 +309,7 @@ public class PCRBService : IPCRBService {
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/delete?planNumber={planNumber}");
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb?planNumber={planNumber}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
@ -260,4 +318,450 @@ public class PCRBService : IPCRBService {
|
||||
IEnumerable<PCRB> allPCRBs = await GetAllPCRBs(true);
|
||||
_cache.Set("allPCRBs", allPCRBs);
|
||||
}
|
||||
|
||||
public async Task UploadAttachment(PCRBAttachment attachment) {
|
||||
if (attachment is null) throw new ArgumentNullException("attachment cannot be null");
|
||||
if (attachment.File is null) throw new ArgumentNullException("file cannot be null");
|
||||
if (attachment.File.Size <= 0) throw new ArgumentException("file size must be greater than zero");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/attachment");
|
||||
|
||||
using MultipartFormDataContent content = new MultipartFormDataContent();
|
||||
|
||||
try {
|
||||
long maxFileSize = 1024L * 1024L * 1024L * 2L;
|
||||
StreamContent fileContent = new StreamContent(attachment.File.OpenReadStream(maxFileSize));
|
||||
|
||||
FileExtensionContentTypeProvider contentTypeProvider = new FileExtensionContentTypeProvider();
|
||||
|
||||
const string defaultContentType = "application/octet-stream";
|
||||
|
||||
if (!contentTypeProvider.TryGetContentType(attachment.File.Name, out string? contentType)) {
|
||||
contentType = defaultContentType;
|
||||
}
|
||||
|
||||
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
|
||||
content.Add(content: fileContent, name: "\"file\"", fileName: attachment.File.Name);
|
||||
} catch (Exception ex) {
|
||||
_snackbar.Add(ex.Message);
|
||||
}
|
||||
|
||||
content.Add(new StringContent(attachment.PlanNumber.ToString()), "PlanNumber");
|
||||
content.Add(new StringContent(attachment.FileName), "FileName");
|
||||
content.Add(new StringContent(attachment.UploadedByID.ToString()), "UploadedByID");
|
||||
content.Add(new StringContent(attachment.Title), "Title");
|
||||
content.Add(new StringContent(attachment.UploadDateTime.ToString("yyyy-MM-dd HH:mm:ss")), "UploadDateTime");
|
||||
content.Add(new StringContent(attachment.Step.ToString()), "Step");
|
||||
|
||||
requestMessage.Content = content;
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
await GetAttachmentsByPlanNumber(attachment.PlanNumber, true);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCRBAttachment>> GetAttachmentsByPlanNumber(int planNumber, bool bypassCache) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
|
||||
|
||||
IEnumerable<PCRBAttachment>? attachments = null;
|
||||
if (!bypassCache)
|
||||
attachments = _cache.Get<IEnumerable<PCRBAttachment>>($"pcrbAttachments{planNumber}");
|
||||
|
||||
if (attachments is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/attachments?planNumber={planNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
attachments = JsonSerializer.Deserialize<IEnumerable<PCRBAttachment>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<PCRBAttachment>();
|
||||
|
||||
if (attachments.Count() > 0) {
|
||||
foreach (PCRBAttachment attachment in attachments) {
|
||||
attachment.UploadedBy = await _userService.GetUserByUserId(attachment.UploadedByID);
|
||||
}
|
||||
|
||||
_cache.Set($"pcrbAttachments{planNumber}", attachments, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
public async Task UpdateAttachment(PCRBAttachment attachment) {
|
||||
if (attachment is null) throw new ArgumentNullException("attachment cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/attachment");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(attachment),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task DeleteAttachment(PCRBAttachment attachment) {
|
||||
if (attachment is null) throw new ArgumentNullException("attachment cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/attachment");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(attachment),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task CreateNewActionItem(PCRBActionItem actionItem) {
|
||||
if (actionItem is null) throw new ArgumentNullException("action item cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/actionItem");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(actionItem),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
await GetActionItemsForPlanNumber(actionItem.PlanNumber, true);
|
||||
}
|
||||
|
||||
public async Task UpdateActionItem(PCRBActionItem actionItem) {
|
||||
if (actionItem is null) throw new ArgumentNullException("action item cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/actionItem");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(actionItem),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task DeleteActionItem(int id) {
|
||||
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB action item ID");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/actionItem?id={id}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCRBActionItem>> GetActionItemsForPlanNumber(int planNumber, bool bypassCache) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
|
||||
|
||||
IEnumerable<PCRBActionItem>? actionItems = null;
|
||||
if (!bypassCache)
|
||||
actionItems = _cache.Get<IEnumerable<PCRBActionItem>>($"pcrbActionItems{planNumber}");
|
||||
|
||||
if (actionItems is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/actionItems?planNumber={planNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
actionItems = JsonSerializer.Deserialize<IEnumerable<PCRBActionItem>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<PCRBActionItem>();
|
||||
|
||||
if (actionItems.Count() > 0) {
|
||||
foreach (PCRBActionItem actionItem in actionItems) {
|
||||
actionItem.UploadedBy = await _userService.GetUserByUserId(actionItem.UploadedByID);
|
||||
if (actionItem.ResponsiblePersonID > 0)
|
||||
actionItem.ResponsiblePerson = await _userService.GetUserByUserId(actionItem.ResponsiblePersonID);
|
||||
if (actionItem.ClosedByID > 0)
|
||||
actionItem.ClosedBy = await _userService.GetUserByUserId(actionItem.ClosedByID);
|
||||
}
|
||||
|
||||
_cache.Set($"pcrbActionItems{planNumber}", actionItems, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
return actionItems;
|
||||
}
|
||||
|
||||
public async Task CreateNewAttendee(PCRBAttendee attendee) {
|
||||
if (attendee is null) throw new ArgumentNullException("attendee cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/attendee");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(attendee),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
await GetAttendeesByPlanNumber(attendee.PlanNumber, true);
|
||||
}
|
||||
|
||||
public async Task UpdateAttendee(PCRBAttendee attendee) {
|
||||
if (attendee is null) throw new ArgumentNullException("attendee cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/attendee");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(attendee),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task DeleteAttendee(int id) {
|
||||
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB attendee ID");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/attendee?id={id}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCRBAttendee>> GetAttendeesByPlanNumber(int planNumber, bool bypassCache) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
|
||||
|
||||
IEnumerable<PCRBAttendee>? attendees = null;
|
||||
if (!bypassCache)
|
||||
attendees = _cache.Get<IEnumerable<PCRBAttendee>>($"pcrbAttendees{planNumber}");
|
||||
|
||||
if (attendees is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/attendees?planNumber={planNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
attendees = JsonSerializer.Deserialize<IEnumerable<PCRBAttendee>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<PCRBAttendee>();
|
||||
|
||||
if (attendees.Count() > 0) {
|
||||
foreach (PCRBAttendee attendee in attendees)
|
||||
attendee.Attendee = await _userService.GetUserByUserId(attendee.AttendeeID);
|
||||
|
||||
_cache.Set($"pcrbAttendees{planNumber}", attendees, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
return attendees;
|
||||
}
|
||||
|
||||
public async Task CreatePCR3Document(PCR3Document document) {
|
||||
if (document is null) throw new ArgumentNullException("document cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/pcr3Document");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(document),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
|
||||
await GetPCR3DocumentsForPlanNumber(document.PlanNumber, true);
|
||||
}
|
||||
|
||||
public async Task UpdatePCR3Document(PCR3Document document) {
|
||||
if (document is null) throw new ArgumentNullException("document cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/pcr3Document");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(document),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache) {
|
||||
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
|
||||
|
||||
IEnumerable<PCR3Document>? documents = null;
|
||||
if (!bypassCache)
|
||||
documents = _cache.Get<IEnumerable<PCR3Document>>($"pcr3Documents{planNumber}");
|
||||
|
||||
if (documents is null) {
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/pcr3Documents?planNumber={planNumber}&bypassCache={bypassCache}");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
string responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
|
||||
JsonSerializerOptions jsonSerializerOptions = new() {
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
documents = JsonSerializer.Deserialize<IEnumerable<PCR3Document>>(responseContent, jsonSerializerOptions) ??
|
||||
new List<PCR3Document>();
|
||||
|
||||
if (documents.Count() > 0) {
|
||||
foreach (PCR3Document document in documents) {
|
||||
if (document.CompletedByID > 0)
|
||||
document.CompletedBy = await _userService.GetUserByUserId(document.CompletedByID);
|
||||
}
|
||||
|
||||
_cache.Set($"pcr3Documents{planNumber}", documents, DateTimeOffset.Now.AddMinutes(5));
|
||||
}
|
||||
} else {
|
||||
throw new Exception(responseMessage.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
return documents;
|
||||
}
|
||||
|
||||
public async Task NotifyNewApprovals(PCRB pcrb) {
|
||||
if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/notify/new-approvals");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(pcrb),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify new PCRB approvers, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyApprovers(PCRBNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/notify/approvers");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify PCRB approvers, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyOriginator(PCRBNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/notify/originator");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify PCRB originator, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
|
||||
public async Task NotifyResponsiblePerson(PCRBActionItemNotification notification) {
|
||||
if (notification is null) throw new ArgumentNullException("notification cannot be null");
|
||||
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient("API");
|
||||
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/notify/responsiblePerson");
|
||||
|
||||
requestMessage.Content = new StringContent(JsonSerializer.Serialize(notification),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
throw new Exception($"Unable to notify PCRB responsible person, because {responseMessage.ReasonPhrase}");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user