This commit is contained in:
Emmanuele Sassi
2023-05-11 12:22:40 +02:00
70 changed files with 1465 additions and 401 deletions
+24 -22
View File
@@ -19,40 +19,42 @@ Traduzione OVUNQUE x ogni termine/etichetta/button
Per completare
- <del>aggiunta paginatore</del>
- <del>aggiunta stato ordine</del>
- <del>aggiunta filtri ricerca</del>
- <del>periodo da-a</del>
- <del>search generico</del>
- <del>stato ordine </del>
- <del>aggiunta filtri ricerca
- periodo da-a
- search generico
- stato ordine</del>
- <del>ordinamento</del>
### DCA Order Man
FORSE la Orders home Page NON VA bene x gli utenti backoffice, oppure va estesa, perché x confermare quotazione, indicare avanzamento ordini gli operatori ABH/DCA devono avere una apgina operativa...
FORSE la Orders home Page NON VA bene x gli utenti backoffice, oppure va estesa, perché x confermare quotazione, indicare avanzamento ordini gli operatori ABH/DCA devono avere una pagina operativa...
### OrderDetails
Per completare:
- aggiunta button x il cambio stato da end-user
- sistemare con paginatore max 3 righe x 4 porte
- fix button verde add-new
- conteggio num modifiche da salvare
- armonizzare il cancel/save nella pagina
- revisione testata fino al btn del salva generale
- sostituire il salva generale con 2 buttons:
- salva, o meglio RECALC PNG = update PNG, potrebbe andare in automatico DOPO i vari SALVA nella pagina (opzione x auto-recalc?!?)
- get 3D obj (in new window/tab)
- <del>aggiunta button x il cambio stato da end-user</del>
- <del>sistemare con paginatore max 3 righe x 4 porte</del>
- <del>fix button verde add-new</del>
### DoorDefinition
### DoorDefinition BaseParams
- <del>conteggio num modifiche da salvare</del>
- <del>armonizzare il cancel/save nella pagina</del>
- <del>revisione testata fino al btn del salva generale</del>
- <del>sostituire il salva generale con 2 buttons:
- salva, o meglio RECALC PNG = update PNG, potrebbe andare in automatico DOPO i vari SALVA nella pagina (opzione x auto-recalc?!?)
- get 3D obj (in new window/tab)</del>
### DoorDefinition Hardware
Sistemare:
- da implementare davvero lettura pdf (da cartella pdf di esempi)
- fix cancel/save: globale x Hardware oppure x ognuno con icona?
- <del>da implementare davvero lettura pdf (da cartella pdf di esempi)</del>
- <del>fix cancel/save: globale x Hardware oppure x ognuno con icona?</del>
- verificare perché NON si aggiorna al salvataggio pagina dei 18 hw
- mancano il totale componenti x ogni hw attivato
- <del>mancano il totale componenti x ogni hw attivato</del>
#### Report
Va inserita una lista dei componenti + elenco quote
<del>Va inserita una lista dei componenti + elenco quote.</del>
Va pensato esportabile in pdf, comprensivo di "check pdf fatto da tizio alle ..."
@@ -61,6 +63,6 @@ Va pensato esportabile in pdf, comprensivo di "check pdf fatto da tizio alle ...
### Top
Da sistemare
- btn effettivi
- dinamico da user-role?
- fix responsive
- <del>btn effettivi</del>
- <del>dinamico da user-role?</del>
- <del>fix responsive</del>
@@ -278,6 +278,35 @@ namespace WebDoorCreator.Data.Controllers
}
return dbResult;
}
/// <summary>
/// Retrieving current door operations by id
/// </summary>
/// <returns></returns>
public DoorOpModel DoorOpGetById(int doorOpId)
{
DoorOpModel dbResult = new DoorOpModel();
using (WDCDataContext localDbCtx = new WDCDataContext(_configuration))
{
try
{
// extracting entire set
var temp = localDbCtx
.DbSetDoorOp
.Where(x => x.DoorOpId == doorOpId)
.FirstOrDefault();
if(temp != null)
{
dbResult = temp;
}
}
catch (Exception exc)
{
Log.Error($"Error in DoorOpGetById:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Adding door's OP
+8 -6
View File
@@ -18,11 +18,11 @@ namespace WebDoorCreator.Data.DTO
#region Public Properties
public string version { get; set; } = "0";
public bool produce { get; set; } = true;
public string measures { get; set; } = "inch";
public string measures { get; set; } = "inches";
public string code { get; set; } = "0015943";
public OrderDto order { get; set; } = new OrderDto();
public DateTime date { get; set; } = DateTime.UtcNow.Date;
public DateTime date { get; set; } = DateTime.Parse(DateTime.Today.ToString("dd/MM/yyyy"));
public string piece { get; set; } = "DO_1";
#endregion Public Properties
@@ -53,7 +53,7 @@ namespace WebDoorCreator.Data.DTO
/// <param name="serialSwing"></param>
/// <param name="serialProperties"></param>
/// <returns></returns>
public string GetSerialized(List<string> headRows, List<string> footRows, string serialDoorOps, string serialEdges,string serialSize, string serialSwing, string serialProperties, string serialFinishing)
public string GetSerialized(List<string> headRows, List<string> footRows, string serialDoorOps, string serialEdges, string serialSize, string serialSwing, string serialProperties, string serialFinishing)
{
string fullData = "";
StringBuilder sb = new StringBuilder();
@@ -74,17 +74,19 @@ namespace WebDoorCreator.Data.DTO
var currYaml = GetObjYaml();
fullData += currYaml;
#if false
// aggiungo la parte woodType come yaml reale/striped...
if (!string.IsNullOrEmpty(serialProperties))
{
fullData += serialProperties;
}
// aggiungo la parte woodType come yaml reale/striped...
// aggiungo la parte finishing come yaml reale/striped...
if (!string.IsNullOrEmpty(serialFinishing))
{
fullData += serialFinishing;
}
}
#endif
// aggiungo la parte size come yaml reale/striped...
if (!string.IsNullOrEmpty(serialSize))
@@ -275,7 +275,7 @@ namespace WebDoorCreator.Data.Services
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
// per prima cosa controllo se ho GIA' in coda qualcosa come richeiste
// per prima cosa controllo se ho GIA' in coda qualcosa come richieste
long numPending = await NumRequestPending();
// se coda non vuota: cerco la DoorId corrente, se c'è sovrascrivo versione altrimenti
@@ -309,6 +309,7 @@ namespace WebDoorCreator.Data.Services
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SendCalcReq | DoorId: {DoorId} enqueued in: {ts.TotalMilliseconds} ms");
#if false
// FIXME TODO!!!! levare quando ci sarà il vero sw in esecuzione...
// simulazione ritorno dati...
@@ -328,7 +329,8 @@ namespace WebDoorCreator.Data.Services
await Task.Delay(300);
string retMess = $"{sDoorId}:{sCurrVers}";
// invio il FINTO messaggio di ritorno...
CalcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess);
CalcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess);
#endif
return currVers;
}
@@ -399,7 +401,7 @@ namespace WebDoorCreator.Data.Services
}
/// <summary>
/// Invio elenco risultati elaborazioni (modalità boolean di esecuzione corretta)
/// Salvo elenco risultati elaborazioni (modalità boolean di esecuzione corretta)
/// </summary>
/// <param name="calcResults">Risultati elaborazioni in formato CalcResultDTO</param>
/// <returns></returns>
@@ -407,6 +409,27 @@ namespace WebDoorCreator.Data.Services
{
bool answ = true;
await Task.Delay(1);
if (calcResults != null && calcResults.Count > 0)
{
string sDoorId = "";
string sCurrVers = "";
foreach (var calcTask in calcResults)
{
// solo se risultato valido...
if (calcTask.Validated)
{
// salvo in area REDIS
var doorData = calcTask.DoorIdVers.Split(".");
sDoorId = doorData.Length > 0 ? doorData[0] : "";
sCurrVers = doorData.Length > 0 ? doorData[0] : "";
RedisKey currSvgKey = new RedisKey($"{Constants.CALC_REQ_SVG_CACHE}:{sDoorId}:{sCurrVers}");
await redisDb.StringSetAsync(currSvgKey, calcTask.SvgGen, DayLongCache);
// invio il FINTO messaggio di ritorno...
string retMess = $"{sDoorId}:{sCurrVers}";
CalcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess);
}
}
}
return answ;
}
@@ -1,12 +1,14 @@
<div>
@B_doorOpUpd
@if (B_doorOpUpd)
@if (B_doorOpUpd || true)
{
<button class="btn btn-success" @onclick="() => doSave()"><i class="fa-solid fa-floppy-disk fa-bounce"></i></button>
<button class="btn btn-success" @onclick="() => doSave()"><i class="fa-solid fa-floppy-disk"></i></button>
<a class="btn btn-warning" href="https://iis01.egalware.com/Test3D/Doors041122/EXB_0267100040/EXB_0267100040.html" target="_blank"><i class="fa-solid fa-cube"></i></a>
}
else
{
<button class="btn btn-secondary"><i class="fa-solid fa-floppy-disk"></i></button>
<button class="btn btn-secondary"><i class="fa-solid fa-cube"></i></button>
}
@*<button class="btn btn-success" @onclick="() => toOrderPage()">Return to Order <b>@idOrd</b></button>*@
</div>
@@ -28,6 +28,8 @@ namespace WebDoorCreator.UI.Components.Buttons
[Inject]
protected WebDoorCreatorService WDCService { get; set; } = null!;
[Inject]
protected WDCUserService WDCUService { get; set; } = null!;
[Inject]
protected QueueDataService QDataServ { get; set; } = null!;
@@ -110,6 +112,7 @@ namespace WebDoorCreator.UI.Components.Buttons
if (listOp != null)
{
// chiamo metodo x avewre DDF serializzato
//var list2Ord = ;
string currDdf = currDdfConv.GetSerialized(listOp);
// FIXME TODO: si potrebbe eliminare in futuro che va su REDIS
await SaveYaml(currDdf);
@@ -118,6 +121,14 @@ namespace WebDoorCreator.UI.Components.Buttons
}
}
}
/// <summary>
/// Effettua Richiesta visione porta 3D
/// </summary>
/// <returns></returns>
protected async Task doReq3D()
{
await Task.Delay(1);
}
protected WebDoorCreator.Data.DDF.Converter currDdfConv { get; set; } = null!;
}
@@ -6,16 +6,22 @@ else
{
<div class="row">
<div class="row mb-1">
<div class="col-4"></div>
<div class="col-4"></div>
<div class="col-4">
@if (DoorOp2Save != null)
{
<div>Pending changes: <b>@DoorOp2Save.Count()</b></div>
}
</div>
<div class="col-4"></div>
@if (paramsChanged)
{
<div class="col-4">
<div class="btn-group w-100">
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="()=>resetEdit()">
<button class="btn btn-outline-danger" style="cursor: pointer;" @onclick="()=>resetEdit()">
CANCEL
</button>
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="()=>doSaveDoorOp()">
<button class="btn btn-outline-success" style="cursor: pointer;" @onclick="()=>doSaveDoorOp()">
SAVE
</button>
</div>
@@ -7,7 +7,14 @@
<div>
<h5>@BlockDoorOp.ObjectId</h5>
</div>
@if (paramsChanged)
{
<div class="circle pulse blue"></div>
}
else
{
<div class="circle grey"></div>
}
</div>
<div class="row">
@@ -71,6 +71,7 @@ namespace WebDoorCreator.UI.Components.DoorDef
[Inject]
protected WDCRefreshService WDCRService { get; set; } = null!;
protected async Task doSaveBlock(Dictionary<string, Dictionary<string, string>> updSet)
{
await Task.Delay(1);
@@ -91,6 +92,7 @@ namespace WebDoorCreator.UI.Components.DoorDef
await E_doorOp2Save.InvokeAsync(BlockDoorOp);
WDCRService.isDoorOpUpd = true;
//showCirc = true;
await InvokeAsync(StateHasChanged);
}
@@ -99,6 +101,8 @@ namespace WebDoorCreator.UI.Components.DoorDef
}
}
protected bool showCirc { get; set; } = false;
protected Dictionary<string, List<string>> getParamsConfig(string paramName)
{
Dictionary<string, List<string>> answ = new Dictionary<string, List<string>>();
@@ -0,0 +1,28 @@
body {
height: 100vh;
overflow: hidden;
}
.blue {
background: #3652D9;
}
.grey {
background: #7F8C8D;
opacity: 50%;
}
.circle {
width: 1rem;
height: 1rem;
border-radius: 50%;
box-shadow: 0px 0px 1px 1px #0000001a;
}
.pulse {
animation: pulse-animation 2s infinite;
}
@keyframes pulse-animation {
0% {
box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.2);
}
100% {
box-shadow: 0 0 0 20px rgba(0, 0, 0, 0);
}
}
@@ -0,0 +1,35 @@
body {
height: 100vh;
overflow: hidden;
}
.blue {
background: #3652D9;
}
.grey {
background: #7F8C8D;
opacity: 50%;
}
.circle {
width: 1rem;
height: 1rem;
border-radius: 50%;
box-shadow: 0px 0px 1px 1px #0000001a;
}
.pulse {
animation: pulse-animation 2s infinite;
}
@keyframes pulse-animation {
0% {
box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.2);
}
100% {
box-shadow: 0 0 0 20px rgba(0, 0, 0, 0);
}
}
@@ -0,0 +1 @@
body{height:100vh;overflow:hidden;}.blue{background:#3652d9;}.grey{background:#7f8c8d;opacity:50%;}.circle{width:1rem;height:1rem;border-radius:50%;box-shadow:0 0 1px 1px #0000001a;}.pulse{animation:pulse-animation 2s infinite;}@keyframes pulse-animation{0%{box-shadow:0 0 0 0 rgba(0,0,0,.2);}100%{box-shadow:0 0 0 20px rgba(0,0,0,0);}}
@@ -1,21 +1,21 @@
@if (currOrderStatus != null)
{
<div class="d-flex justify-content-between p-2" style="background-color: @bgColor">
<div>
<div class="badge rounded-pilll bg-dark text-light">Insert Date</div>
<div>@currOrderStatus.DateIns</div>
<div class="d-flex justify-content-between px-2 py-2" style="background-color: @bgColor">
<div class="d-flex justify-content-between">
@*<div class="badge rounded-pilll bg-dark text-light">Insert Date</div>*@
<div>Insert Date: <b>@currOrderStatus.DateIns</b></div>
</div>
<div>
<div class="badge rounded-pilll bg-dark text-light">Order External Code</div>
<div>@currOrderStatus.OrderExtCode</div>
<div class="d-flex justify-content-between">
@*<div class="badge rounded-pilll bg-dark text-light">Order External Code</div>*@
<div>Order External Code: <b>@currOrderStatus.OrderExtCode</b></div>
</div>
<div>
<div class="badge rounded-pilll bg-dark text-light">Models Number</div>
<div class="text-center">@currOrderStatus.NumType</div>
<div class="d-flex justify-content-between">
@*<div class="badge rounded-pilll bg-dark text-light">Models Number</div>*@
<div class="text-center">Models Number: <b>@currOrderStatus.NumType</b></div>
</div>
<div>
<div class="badge rounded-pilll bg-dark text-light">Doors Number</div>
<div class="text-center">@currOrderStatus.NumDoors</div>
<div class="d-flex justify-content-between">
@*<div class="badge rounded-pilll bg-dark text-light">Doors Number</div>*@
<div class="text-center">Doors Number: <b>@currOrderStatus.NumDoors</b></div>
</div>
<div style="background: #AFCFD1; text-align: end">
<ButtonsDoorDef></ButtonsDoorDef>
@@ -7,17 +7,17 @@
<div class="col px-0" @onclick="()=>changeStep(int.Parse(item.Value))">
@if (int.Parse(item.Value) == CurrDoorDefStatus)
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:{item.DefaultVal};")" StrokeColors="@listBord01" TipAngle="90" ObjW="650" ObjH="100"></StepArrow>
}
else
{
@if (int.Parse(item.Value) < CurrDoorDefStatus)
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@($"{item.Label} ✓")" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@($"{item.Label} ✓")" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100" TipAngle="90"></StepArrow>
}
else
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:transparent;")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:transparent;")" ObjW="650" ObjH="100" TipAngle="90"></StepArrow>
}
}
</div>
@@ -46,8 +46,16 @@ namespace WebDoorCreator.UI.Components.DoorDef
}
}
listBord01 = new();
listBord01.Add("White");
listBord01.Add("White");
listBord01.Add("White");
listBord01.Add("White");
}
protected List<string> listBord01 { get; set; } = new();
protected async Task changeStep(int step)
{
await E_CurrStep.InvokeAsync(step);
@@ -1,4 +1,4 @@
<div class="" style="height:100%; width:100%; position:sticky; background: linear-gradient(#AFCFD1, #92B2C4);">
<div class="" style="height:100%; width:100%; position:sticky; background: linear-gradient(#AFCFD1, #92B2C4);min-height: 46rem;max-height: 46rem;">
@if (!string.IsNullOrEmpty(@SvgContent))
{
@svgPreview
@@ -1,8 +1,19 @@
@if (DoorsList != null)
{
<div class="col-3 py-1">
<DoorSvgObj LineColor="rgb(39, 174, 96)" LineWidth="8" ObjH="200" ObjW="650" EC_ExeFunct="@createDoor" ObjId="0" TextData="@baseDict"></DoorSvgObj>
</div>
@if (orderStatus == 10)
{
<div class="row">
<div class="col-4 py-1">
<DoorSvgObj LineColor="rgb(39, 174, 96)" LineWidth="8" ObjH="200" ObjW="900" LeftTextClass="col-10 fs-1 fw-bold" RightTextClass="col-2" EC_ExeFunct="@(()=> createDoor(""))" ObjId="0" TextData="@AddDoorDict"></DoorSvgObj>
</div>
<div class="col-4 py-1">
<DoorSvgObj LineColor="rgb(39, 174, 96)" LineWidth="8" ObjH="200" ObjW="900" LeftTextClass="col-10 fs-1 fw-bold" RightTextClass="col-2" EC_ExeFunct="@(()=> createDoor(""))" ObjId="0" TextData="@AddFromTemplDict"></DoorSvgObj>
</div>
<div class="col-4 py-1">
<DoorSvgObj LineColor="#8E44AD" LineWidth="8" ObjH="200" ObjW="900" LeftTextClass="col-10 fs-1 fw-bold" RightTextClass="col-2" EC_ExeFunct="@(()=> sendToAbh(currOrderId, orderStatus))" ObjId="0" TextData="@SendOrderDict" Message1="@currOrderId.ToString()" Message2="@orderStatus.ToString()"></DoorSvgObj>
</div>
</div>
}
<div class="row">
@if (DoorsList == null || DoorsList.Count == 0)
{ }
@@ -15,7 +26,7 @@
imgPath = $"images/LogoEgw{idxCount % 5:00}.png";
idxCount++;
<div class="col-3 py-1">
<DoorSvgObj LineColor="#2D3047" LineWidth="8" ObjH="200" ObjW="650" EC_ExeFunct="editRec" Message="@door.DoorId.ToString()" ImagePath="@imgPath" ObjId="idxCount" TextData="@textDictSetup(door)"></DoorSvgObj>
<DoorSvgObj LineColor="#2D3047" LineWidth="8" ObjH="200" ObjW="650" LeftTextClass="col-4" RightTextClass="col-8" EC_ExeFunct="@(()=> editRec(@door.DoorId.ToString()))" Message1="@door.DoorId.ToString()" ImagePath="@imgPath" ObjId="idxCount" TextData="@textDictSetup(door)"></DoorSvgObj>
</div>
}
@@ -15,6 +15,13 @@ namespace WebDoorCreator.UI.Components.DoorMan
[Parameter]
public EventCallback<bool> E_DoorChanged { get; set; }
[Parameter]
public EventCallback<int> updateRecordCount { get; set; }
[Parameter]
public DoorsSelectFilter actFilter { get; set; } = new DoorsSelectFilter();
#endregion Public Properties
#region Protected Properties
@@ -30,7 +37,9 @@ namespace WebDoorCreator.UI.Components.DoorMan
protected int orderStatus { get; set; } = 10;
protected Dictionary<string, string> baseDict { get; set; } = new Dictionary<string, string>();
protected Dictionary<string, string> AddDoorDict { get; set; } = new Dictionary<string, string>();
protected Dictionary<string, string> AddFromTemplDict { get; set; } = new Dictionary<string, string>();
protected Dictionary<string, string> SendOrderDict { get; set; } = new Dictionary<string, string>();
[Inject]
protected WebDoorCreatorService WDService { get; set; } = null!;
@@ -93,20 +102,37 @@ namespace WebDoorCreator.UI.Components.DoorMan
protected async Task ReloadData()
{
if(!baseDict.ContainsKey("ADD NEW DOOR"))
if (!AddDoorDict.ContainsKey("ADD NEW DOOR"))
{
baseDict.Add("ADD NEW DOOR", "");
AddDoorDict.Add("ADD NEW DOOR", "");
}
if (!AddFromTemplDict.ContainsKey("ADD NEW DOOR FROM TEMPLATE"))
{
AddFromTemplDict.Add("ADD NEW DOOR FROM TEMPLATE", "");
}
if (!SendOrderDict.ContainsKey("SEND TO ABH"))
{
SendOrderDict.Add("SEND TO ABH", "");
}
if (currOrderId != -1)
{
DoorsList = await WDService.DoorGetByOrderId(currOrderId);
if (DoorsList != null)
var SearchRecords = await WDService.DoorGetByOrderId(currOrderId);
if (SearchRecords != null)
{
var currOrder = DoorsList.FirstOrDefault();
if (currOrder?.OrderNav != null)
totalCount = SearchRecords.Count;
DoorsList = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
if (DoorsList != null)
{
orderStatus = currOrder.OrderNav.Status;
var currOrder = DoorsList.FirstOrDefault();
if (currOrder?.OrderNav != null)
{
orderStatus = currOrder.OrderNav.Status;
}
}
}
}
@@ -151,5 +177,50 @@ namespace WebDoorCreator.UI.Components.DoorMan
// rimando alla pagina... dettaglio...
NavManager.NavigateTo($"/DoorDefinition?idOrd={currOrderId}&idDoor={doorId}");
}
protected async void sendToAbh(int ordId, int orderStat)
{
if (orderStat == 10)
{
//int doorId = await WDService.createDoor(currOrderId, userId, "mm");
bool done = await WDService.OrderUpdate(ordId, 20);
if (done)
{
await InvokeAsync(StateHasChanged);
}
}
await ReloadData();
}
private int currPage
{
get => actFilter.CurrPage;
set => actFilter.CurrPage = value;
}
private int numRecord
{
get => actFilter.NumRec;
set => actFilter.NumRec = value;
}
private string searchVal
{
get => actFilter.searchValue;
set => actFilter.searchValue = value;
}
private int _totalCount { get; set; } = 0;
private int totalCount
{
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
updateRecordCount.InvokeAsync(value);
}
}
}
}
}
@@ -19,7 +19,16 @@
</div>
<div class="col d-flex row pb-1 col">
<div class="form-floating col ps-1">
<input id="orderStatus" @bind="@orderStatus" class="form-control" />
<select @bind="@orderStatus" id="orderStatus" class="form-select">
@if(ListValuesAll != null)
{
foreach(var item in ListValuesAll)
{
<option value="@int.Parse(item.Value)">@item.Label</option>
}
}
</select>
@*<input id="orderStatus" @bind="@orderStatus" class="form-control" />*@
<label for="orderStatus">Order Status</label>
</div>
</div>
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using WebDoorCreator.Data.DbModels;
using WebDoorCreator.UI.Data;
namespace WebDoorCreator.UI.Components.Filters
@@ -10,19 +11,13 @@ namespace WebDoorCreator.UI.Components.Filters
[Parameter]
public OrderSelectFilter actFilter { get; set; } = new OrderSelectFilter();
#if false
public List<ItemFamilyModel>? itemFamList { get; set; } = null;
[Inject]
protected StockDataService SDService { get; set; } = null!;
#endif
private List<ListValuesModel>? ListValuesAll = null;
protected override async Task OnParametersSetAsync()
{
//itemFamList = await SDService.ItemFamilyGetAll();
ListValuesAll = await WDService.ListValuesGetAll("All", "OrderStep");
}
[Inject]
protected WebDoorCreatorService WDService { get; set; } = null!;
private string searchVal
{
get => actFilter.searchValue;
@@ -11,69 +11,130 @@
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<AuthorizeView Roles="SuperAdmin, CompAdmin, CompUser" Context="MenuHide">
<Authorized>
<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="OrdersHomePage">
<span class="oi oi-cart" aria-hidden="true"></span> Orders home page
</NavLink>
</div>
</Authorized>
</AuthorizeView>
<!--Hiding to non-SuperAdmin users the option to manage the application -->
<AuthorizeView Roles="SuperAdmin" Context="MenuHide">
<Authorized>
<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="SuperAdmin">
<span class="oi oi-list-rich" aria-hidden="true"></span> General management
</NavLink>
</div>
</Authorized>
</AuthorizeView>
<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="DoorDefinition">
<span class="bi bi-door-open-fill pe-3" aria-hidden="true"></span> Door definition page
</NavLink>
<div class="w-100 d-flex justify-content-start">
<AuthorizeView Roles="SuperAdmin, CompAdmin, CompUser" Context="MenuHide">
<Authorized>
<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="OrdersHomePage">
<span class="oi oi-cart" aria-hidden="true"></span> Orders home page
</NavLink>
</div>
</Authorized>
</AuthorizeView>
<!--Hiding to non-SuperAdmin users the option to manage the application -->
<AuthorizeView Roles="SuperAdmin" Context="MenuHide">
<Authorized>
<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="SuperAdmin">
<span class="oi oi-list-rich" aria-hidden="true"></span> General management
</NavLink>
</div>
</Authorized>
</AuthorizeView>
</div>
@*<div class="nav-item px-3 d-flex flex-warp align-items-center">
<NavLink class="nav-link" href="DoorDefinition">
<span class="bi bi-door-open-fill pe-3" aria-hidden="true"></span> Door definition page
</NavLink>
</div>*@
</div>
</div>
</div>
<div class="text-end text-nowrap px-3">
<div class="d-flex justify-content-between small">
<div class="d-flex justify-content-between">
<a href="Identity/Account/Manage" class="text-decoration-none text-dark" style="">@context.User.Identity?.Name!</a>
<div class="text-decoration-none text-secondary small" style="">
@if (listCompanies != null)
{
@if (listCompanies.Count > 1)
<div class="dropdown">
<a class="btn btn-primary dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
@context.User.Identity?.Name
</a>
<ul class="dropdown-menu p-2">
<li>
<div class="">
<button href="Identity/Account/Manage" class="btn btn-sm btn-success w-100 fw-bold text-light text-decoration-none text-dark" style="">User options</button>
</div>
</li>
<li>
<div class="text-decoration-none text-secondary small" style="">
<div class="mb-1 small">
<b>Company</b>
</div>
@if (listCompanies != null)
{
<select @bind="userCurrCompany" class="form-select form-select-sm">
@foreach (var item in listCompanies)
{
<option value="@item.CompanyId">@item.CompanyName</option>
}
</select>
}
else
{
@if (compToShow != null)
@if (listCompanies.Count > 1)
{
<div>@compToShow.CompanyName</div>
<select @bind="userCurrCompany" class="form-select form-select-sm">
@foreach (var item in listCompanies)
{
<option value="@item.CompanyId">@item.CompanyName</option>
}
</select>
}
else
{
@if (compToShow != null)
{
<div>@compToShow.CompanyName</div>
}
}
}
}
</div>
<div>
<select @bind="userLang" class="form-select form-select-sm">
<option>EN</option>
<option>IT</option>
</select>
</div>
</div>
<form method="post" action="Identity/Account/LogOut">
<button type="submit" class="btnLogout">Log out</button>
</form>
</div>
</li>
<li>
<div class="">
<div class="mb-1 text-secondary small">
Language
</div>
<select @bind="userLang" class="form-select form-select-sm">
<option>EN</option>
<option>IT</option>
</select>
</div>
<hr />
</li>
<li>
<div class="text-end">
<form method="post" action="Identity/Account/LogOut">
<button type="submit" class="btnLogout">Log out <i class="fa-solid fa-arrow-right-from-bracket"></i></button>
</form>
</div>
</li>
</ul>
</div>
@*<div class="d-flex justify-content-between small">
<div class="d-flex justify-content-between">
<a href="Identity/Account/Manage" class="text-decoration-none text-dark" style="">@context.User.Identity?.Name</a>
<div class="text-decoration-none text-secondary small" style="">
@if (listCompanies != null)
{
@if (listCompanies.Count > 1)
{
<select @bind="userCurrCompany" class="form-select form-select-sm">
@foreach (var item in listCompanies)
{
<option value="@item.CompanyId">@item.CompanyName</option>
}
</select>
}
else
{
@if (compToShow != null)
{
<div>@compToShow.CompanyName</div>
}
}
}
</div>
<div>
<select @bind="userLang" class="form-select form-select-sm">
<option>EN</option>
<option>IT</option>
</select>
</div>
</div>
<form method="post" action="Identity/Account/LogOut">
<button type="submit" class="btnLogout">Log out</button>
</form>
</div>*@
</div>
</nav>
</Authorized>
@@ -1,63 +1,52 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0, 0, 0, 0.4);
height: 3.5rem;
background-color: rgba(0, 0, 0, 0.4);
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
/*.nav-item:first-of-type {
/*.nav-item:first-of-type {
padding-top: 1rem;
}*/
/*.nav-item:last-of-type {
/*.nav-item:last-of-type {
padding-bottom: 1rem;
}*/
.nav-item ::deep a {
color: #29b6f6;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item ::deep a.active {
background-color: #2962ff;
color: white;
}
.nav-item ::deep a:hover {
background-color: #2962ff;
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
.nav-item ::deep a {
color: #29b6f6;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item ::deep a.active {
background-color: #2962ff;
color: white;
}
.nav-item ::deep a:hover {
background-color: #2962ff;
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
.btnLogout {
border: none;
background-color: #29b6f6;
margin-left: 1rem;
padding: 0.2rem;
border-radius: 0.3rem;
border: none;
background-color: transparent;
}
@@ -59,8 +59,5 @@
.btnLogout {
border: none;
background-color: rgb(41, 182, 246);
margin-left: 1rem;
padding: 0.2rem;
border-radius: 0.3rem;
background-color: transparent;
}
@@ -1 +1 @@
.navbar-toggler{background-color:rgba(255,255,255,.1);}.top-row{height:3.5rem;background-color:rgba(0,0,0,.4);}.oi{width:2rem;font-size:1.1rem;vertical-align:text-top;top:-2px;}.nav-item{font-size:.9rem;padding-bottom:.5rem;}.nav-item ::deep a{color:#29b6f6;border-radius:4px;height:3rem;display:flex;align-items:center;line-height:3rem;}.nav-item ::deep a.active{background-color:#2962ff;color:#fff;}.nav-item ::deep a:hover{background-color:#2962ff;color:#fff;}@media(min-width:641px){.navbar-toggler{display:none;}.collapse{display:block;}}.btnLogout{border:0;background-color:#29b6f6;margin-left:1rem;padding:.2rem;border-radius:.3rem;}
.navbar-toggler{background-color:rgba(255,255,255,.1);}.top-row{height:3.5rem;background-color:rgba(0,0,0,.4);}.oi{width:2rem;font-size:1.1rem;vertical-align:text-top;top:-2px;}.nav-item{font-size:.9rem;padding-bottom:.5rem;}.nav-item ::deep a{color:#29b6f6;border-radius:4px;height:3rem;display:flex;align-items:center;line-height:3rem;}.nav-item ::deep a.active{background-color:#2962ff;color:#fff;}.nav-item ::deep a:hover{background-color:#2962ff;color:#fff;}@media(min-width:641px){.navbar-toggler{display:none;}.collapse{display:block;}}.btnLogout{border:0;background-color:transparent;}
@@ -5,7 +5,7 @@
{
<div class="row m-0">
<div class="text-center">
<div class="row col-4" >
<div class="row col-4">
<div class="rectangle">
@(translate(HwToShow.Label))
<div class="circle" @onclick="()=>hwToAdd()"></div>
@@ -26,8 +26,16 @@
@foreach (var item in HwList)
{
<div class="row col-4">
<div class="rectangle @setBgColor(item.TableName)" @onclick="()=>hwToChoose(item.TableName)">
@(translate(item.Label))
<div class="rectangle @setBgColor(item.TableName) row" @onclick="()=>hwToChoose(item.TableName)">
<div class="col-8">
@(translate(item.Label))
</div>
@if (@getInstNumber(item.Value) > 0)
{
<div class="col-4 text-end pe-4">
@getInstNumber(item.Value)
</div>
}
<div class="circle"></div>
</div>
</div>
@@ -141,7 +141,7 @@ namespace WebDoorCreator.UI.Components.Hardware
if (fatto)
{
hwAdd = fatto;
await InvokeAsync(StateHasChanged);
await InvokeAsync(StateHasChanged);
}
}
}
@@ -237,6 +237,21 @@ namespace WebDoorCreator.UI.Components.Hardware
}
}
protected int getInstNumber(string hwCode)
{
int answ = 0;
if(DoorOpList != null)
{
answ = DoorOpList
.Where(x => x.ObjectId == hwCode)
.ToList()
.Count();
}
return answ;
}
#endregion Private Methods
}
}
@@ -5,12 +5,12 @@
else
{
<div class="d-flex justify-content-between small">
<div style="width: 90%">
<div style="width: 90%" class="me-2">
<div class="btnHead d-flex justify-content-between">
<div class="testata">
@*<div class="borderTop"></div>*@
<div class="row borderTop">
<div class="fs-2 text-end col-8">
<div class="fs-3 text-end col-8">
@($"{translate(DoorOpInst.ObjectId)} #{instanceN}")
</div>
<div class="text-end col-4">
@@ -121,27 +121,23 @@ else
@if (isChangedVal())
{
<div class="col-10">
<div class="btn-group w-100">
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="() => doCancel()">
CANCEL
</button>
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="() => doSave()">
SAVE
</button>
</div>
<button class="btnCancel" style="cursor: pointer; --colorCode:#E67E22;" @onclick="() => doCancel()">
<i class="fa-solid fa-rotate"></i>
</button>
<button class="btnSave" style="cursor: pointer; --colorCode:#27AE60;" @onclick="() => doSave()">
<i class="fa-solid fa-cloud-arrow-up"></i>
</button>
</div>
}
else
{
<div class="col-10">
<div class="btn-group w-100">
<button class="btn btn-outline-secondary" style="cursor: pointer;" disabled>
CANCEL
</button>
<button class="btn btn-outline-secondary" style="cursor: pointer;" disabled>
SAVE
</button>
</div>
<button class="btnCancel" style="cursor: pointer; --colorCode:#7F8C8D;" disabled>
<i class="fa-solid fa-rotate"></i>
</button>
<button class="btnSave" style="cursor: pointer; --colorCode:#7F8C8D;" disabled>
<i class="fa-solid fa-cloud-arrow-up"></i>
</button>
</div>
}
<div class="text-end col-2">
@@ -163,15 +159,17 @@ else
</div>
</div>
<div class="row borderBottom">
<div class="col-10">
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="()=>doConfirm()">
CONFIRM
</button>
</div>
@*<div class="col-10">
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="()=>doConfirm()">
CONFIRM
</button>
</div>*@
<div class="text-end col-2">
<button class="btnPDFPending">
<i class="fa-solid fa-file-pdf"></i>
</button>
<NavLink href="@pathFinder(DoorOpInst.DoorOpId)" target="_blank">
<button class="btnPDFPending">
<i class="fa-solid fa-file-pdf"></i>
</button>
</NavLink>
</div>
</div>
</div>
@@ -233,6 +233,12 @@ namespace WebDoorCreator.UI.Components.Hardware
return answ;
}
private string pathFinder(int id)
{
string answ = $"HwPdfConfirm?idHwInst={id}";
return answ;
}
#endregion Protected Methods
#region Private Methods
@@ -3,20 +3,23 @@
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
}
.btnDelete {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: #B71C1C;
transform: translate(25px, -12px);
transform: translate(25px, -1rem);
}
.btnClone {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: #FFF;
transform: translate(1.6rem, -1rem);
}
@@ -25,25 +28,46 @@
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: #8E44AD;
transform: translate(25px, 12px);
transform: translate(1rem, 1rem);
}
.btnPDFPending {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: #F1C40F;
transform: translate(25px, 12px);
transform: translate(16rem, 1rem);
}
.btnHighlight {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: #03A9F4;
transform: translate(1.6rem, 1rem);
}
.btnCancel {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: var(--colorCode);
transform: translate(-2rem, 1rem);
}
.btnSave {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
background: var(--colorCode);
transform: translate(-2.6rem, 1rem);
}
.btnHeadTail {
width: 100%;
padding: 0.8rem 0 0.8rem 0;
@@ -1,11 +1,12 @@
@xDelta: 25px;
@yDelta: 12px;
@yDelta: 1rem;
.btnGen {
border-radius: 50%;
width: 3.5rem;
height: 3.5rem;
border: 5px solid #00838F;
z-index: 99999;
}
.btnDelete {
@@ -23,13 +24,13 @@
.btnPDFSuccess {
.btnGen;
background: #8E44AD;
transform: translate(@xDelta, @yDelta);
transform: translate(1rem, @yDelta);
}
.btnPDFPending {
.btnGen;
background: #F1C40F;
transform: translate(@xDelta, @yDelta);
transform: translate(16rem, @yDelta);
}
.btnHighlight {
@@ -37,6 +38,16 @@
background: #03A9F4;
transform: translate(1.6rem, 1rem);
}
.btnCancel {
.btnGen;
background: var(--colorCode);
transform: translate(-2rem, 1rem);
}
.btnSave {
.btnGen;
background: var(--colorCode);
transform: translate(-2.6rem, 1rem);
}
.btnHeadTail {
@@ -1 +1 @@
.btnGen{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;}.btnDelete{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;background:#b71c1c;transform:translate(25px,-12px);}.btnClone{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;background:#fff;transform:translate(1.6rem,-1rem);}.btnPDFSuccess{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;background:#8e44ad;transform:translate(25px,12px);}.btnPDFPending{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;background:#f1c40f;transform:translate(25px,12px);}.btnHighlight{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;background:#03a9f4;transform:translate(1.6rem,1rem);}.btnHeadTail{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;}.btnConfirm{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;border-bottom:3px solid #000;}.btnHead{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;}.borderTop{border-top:7px solid #00838f;}.borderBottom{border-bottom:7px solid #00838f;width:100%;}.modal-dialog{overflow-y:initial!important;}.modal-body{height:18.75rem;overflow-y:auto;}.testata{width:100%;}select,input{border:0;border-bottom:2px solid #000;background:none;height:2rem;}i{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;font-size:1.1rem;}
.btnGen{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;}.btnDelete{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:#b71c1c;transform:translate(25px,-1rem);}.btnClone{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:#fff;transform:translate(1.6rem,-1rem);}.btnPDFSuccess{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:#8e44ad;transform:translate(1rem,1rem);}.btnPDFPending{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:#f1c40f;transform:translate(16rem,1rem);}.btnHighlight{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:#03a9f4;transform:translate(1.6rem,1rem);}.btnCancel{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:var(--colorCode);transform:translate(-2rem,1rem);}.btnSave{border-radius:50%;width:3.5rem;height:3.5rem;border:5px solid #00838f;z-index:99999;background:var(--colorCode);transform:translate(-2.6rem,1rem);}.btnHeadTail{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;}.btnConfirm{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;border-bottom:3px solid #000;}.btnHead{width:100%;padding:.8rem 0 .8rem 0;background:none;border:0;}.borderTop{border-top:7px solid #00838f;}.borderBottom{border-bottom:7px solid #00838f;width:100%;}.modal-dialog{overflow-y:initial!important;}.modal-body{height:18.75rem;overflow-y:auto;}.testata{width:100%;}select,input{border:0;border-bottom:2px solid #000;background:none;height:2rem;}i{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;font-size:1.1rem;}
@@ -8,8 +8,8 @@ else
<thead>
<tr class="">
<td></td>
<th @onclick="()=>orderByDate()">Order Date</th>
<th @onclick="()=>orderByCode()">Order Number</th>
<th>Order Date <Sorter ParamName="OrderDate" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Order Number <Sorter ParamName="OrderNumber" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Order Description</th>
<th class="text-end">Doors Number</th>
<th class="text-end">Model Number</th>
@@ -29,7 +29,7 @@ else
<td>@item.OrderDescript</td>
<td class="text-end">@item.NumDoors</td>
<td class="text-end">@item.NumType</td>
<td class="text-end">@item.OrderStatus</td>
<td class="text-end">@getOrderStatusLabel(item.OrderStatus)</td>
<td class="text-end">@($"{item.TotCost:C2}")</td>
@*<td>
<div class="progress">
@@ -1,3 +1,4 @@
using EgwCoreLib.Razor;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.DataProtection;
@@ -29,6 +30,17 @@ namespace WebDoorCreator.UI.Components.Order
[Inject]
protected WebDoorCreatorService WDService { get; set; } = null!;
private bool sortAsc = true;
private string sortField = "";
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
[Parameter]
public EventCallback<int> updateRecordCount { get; set; }
@@ -89,11 +101,6 @@ namespace WebDoorCreator.UI.Components.Order
#region Protected Methods
//protected override async Task OnInitializedAsync()
//{
// //await SetSelectedData();
//}
protected override async Task OnParametersSetAsync()
{
//if (B_doorChaged)
@@ -107,6 +114,7 @@ namespace WebDoorCreator.UI.Components.Order
#region Private Fields
private List<OrderStatusViewModel>? ListOrdersStatus = null;
private List<ListValuesModel>? ListValuesAll = null;
#endregion Private Fields
@@ -161,37 +169,55 @@ namespace WebDoorCreator.UI.Components.Order
var domani = DateTime.Today.AddDays(1);
ListOrdersStatus = null;
await Task.Delay(1);
ListValuesAll = await WDService.ListValuesGetAll("All", "OrderStep");
if (userClaims != null)
{
var SearchRecords = await WDService.OrderStatusGetFilt(userCurrCompany, orderStatus, dateFrom, dateTo);
if (SearchRecords != null)
{
if (orderType == Core.Enum.orderTypeEnum.DateAscending)
{
SearchRecords = SearchRecords.OrderBy(x => x.DateIns).ToList();
}
else if (orderType == Core.Enum.orderTypeEnum.DateDescending)
{
SearchRecords = SearchRecords.OrderByDescending(x => x.OrderExtCode).ToList();
}
else if (orderType == Core.Enum.orderTypeEnum.CodeAscending)
{
SearchRecords = SearchRecords.OrderBy(x => x.OrderExtCode).ToList();
}
else if (orderType == Core.Enum.orderTypeEnum.CodeDescending)
{
SearchRecords = SearchRecords.OrderByDescending(x => x.OrderExtCode).ToList();
}
totalCount = SearchRecords.Count;
if (searchVal != "")
{
ListOrdersStatus = SearchRecords.Where(x=>x.OrderDescript.Contains(searchVal) || x.OrderExtCode.Contains(searchVal)).Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
ListOrdersStatus = SearchRecords
.Where(x => x.OrderDescript.ToLower().Contains(searchVal.ToLower()) || x.OrderExtCode.ToLower().Contains(searchVal.ToLower()))
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListOrdersStatus = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
}
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "OrderDate":
if (sortAsc)
{
ListOrdersStatus = SearchRecords.OrderBy(x => x.DateIns).ToList();
}
else
{
ListOrdersStatus = SearchRecords.OrderByDescending(x => x.DateIns).ToList();
}
break;
default:
case "OrderNumber":
if (sortAsc)
{
ListOrdersStatus = SearchRecords.OrderBy(x => x.OrderExtCode).ToList();
}
else
{
ListOrdersStatus = SearchRecords.OrderByDescending(x => x.OrderExtCode).ToList();
}
break;
}
}
}
}
await Task.Delay(1);
@@ -247,8 +273,24 @@ namespace WebDoorCreator.UI.Components.Order
protected Core.Enum.orderTypeEnum orderType = Core.Enum.orderTypeEnum.none;
#endregion Private Methods
protected string getOrderStatusLabel(int orderStat)
{
string answ = "";
if (ListValuesAll != null)
{
var currOrdStat = ListValuesAll.Where(x => int.Parse(x.Value) == orderStat).FirstOrDefault();
if (currOrdStat != null)
{
answ = currOrdStat.Label;
}
}
return answ;
}
}
}
@@ -8,17 +8,17 @@
<div class="col px-0">
@if (int.Parse(item.Value) == CurrOrderStatus)
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></StepArrow>
}
else
{
@if (int.Parse(item.Value) < CurrOrderStatus)
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@($"{item.Label} ✓")" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@($"{item.Label} ✓")" BlockStyle="@($"fill:{item.DefaultVal};")" ObjW="650" ObjH="100"></StepArrow>
}
else
{
<WebDoorCreator.UI.Components.SvgComp.StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:transparent;")" ObjW="650" ObjH="100"></WebDoorCreator.UI.Components.SvgComp.StepArrow>
<StepArrow ObjId="@int.Parse(item.Value)" StepText="@item.Label" BlockStyle="@($"fill:transparent;")" ObjW="650" ObjH="100"></StepArrow>
}
}
</div>
@@ -0,0 +1,27 @@
@if (DoorOps != null)
{
@*<div class="row">@getTranslatedLabel(@item.ObjectId) @getTemplate(item)</div>*@
<table class="">
<thead>
<tr class="">
<th>Object Name</th>
<th>Template</th>
<th>Approved By:</th>
<th class="text-end">Approval Date</th>
</tr>
</thead>
<tbody>
@foreach (var item in DoorOps)
{
<tr>
<td>@getTranslatedLabel(@item.ObjectId)</td>
<td>@getTemplate(item)</td>
<td>@item.userConfirm</td>
<td class="text-end">@item.DtConfirm</td>
</tr>
}
</tbody>
</table>
}
@@ -0,0 +1,68 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.Build.Framework;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using WebDoorCreator.Data.DbModels;
using WebDoorCreator.UI.Data;
namespace WebDoorCreator.UI.Components.Report
{
public partial class ReportList
{
[Parameter]
public int doorId { get; set; } = 0;
[Parameter]
public string Lingua { get; set; } = "EN";
protected List<DoorOpModel>? DoorOps { get; set; } = null;
[Inject]
protected WebDoorCreatorService WDService { get; set; } = null!;
[Inject]
protected WDCVocabularyService WDVService { get; set; } = null!;
protected string getTemplate(DoorOpModel currDoorOp)
{
string answ = "";
answ = currDoorOp.CurrVals["template"];
return answ;
}
protected string getTranslatedLabel(string HwId)
{
string answ = "";
var listHw = Task.Run(async () => await WDService.ListValuesGetAll(HwId, "Hardware")).Result;
if (listHw != null)
{
var hw2Translate = listHw.FirstOrDefault();
if (hw2Translate != null)
{
answ = translate(hw2Translate.Label);
}
}
return answ;
}
protected async override Task OnParametersSetAsync()
{
var result = await WDService.DoorOpGetByDoorId(doorId);
if (result != null)
{
DoorOps = result.Where(x => x.ObjectId != "Size" && x.ObjectId != "Profiles" && x.ObjectId != "Swing" && x.ObjectId != "Properties" && x.ObjectId != "Finishing").ToList();
}
}
protected string translate(string lemma)
{
string answ = "";
answ = WDVService.Traduci(Lingua, lemma);
return answ;
}
}
}
@@ -0,0 +1,14 @@
tr {
padding: 0.5rem;
border-bottom: 1px solid;
font-weight: bold;
background-color: #fff;
color: #000;
}
table {
width: 100%;
height: 100%;
}
td {
padding: 0.5rem;
}
@@ -0,0 +1,16 @@
tr {
padding: 0.5rem;
border-bottom: 1px solid;
font-weight: bold;
background-color: #fff;
color: #000;
}
table {
width: 100%;
height: 100%;
}
td {
padding: 0.5rem;
}
@@ -0,0 +1 @@
tr{padding:.5rem;border-bottom:1px solid;font-weight:bold;background-color:#fff;color:#000;}table{width:100%;height:100%;}td{padding:.5rem;}
@@ -1,16 +1,17 @@
<svg viewBox="0 0 @ObjW @ObjH" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100%" height="100%" fill="white" fill-opacity="0.1"></rect>
<g transform="translate(0,@LineDist)">
<foreignObject width="@TextAreaWidth" height="@TextAreaHeight">
<div class="row" style="@TextStyle">
@foreach (var item in TextData)
{
<div class="col-4">
@item.Key
</div>
<div class="col-8 text-end">
<b>@item.Value</b>
</div>
}
@foreach (var item in TextData)
{
<div class="@LeftTextClass">
@item.Key
</div>
<div class="@RightTextClass text-end">
<b>@item.Value</b>
</div>
}
</div>
</foreignObject>
</g>
@@ -7,7 +7,7 @@ namespace WebDoorCreator.UI.Components.SvgComp
#region Public Properties
[Parameter]
public EventCallback<string> EC_ExeFunct { get; set; }
public EventCallback<bool> EC_ExeFunct { get; set; }
[Parameter]
public string ImagePath { get; set; } = "images/LogoEgw.png";
@@ -34,7 +34,14 @@ namespace WebDoorCreator.UI.Components.SvgComp
public string TextStyle { get; set; } = "font-size: 1.5em; fill: #000;";
[Parameter]
public string Message { get; set; } = "";
public string Message1 { get; set; } = "";
[Parameter]
public string Message2 { get; set; } = "";
[Parameter]
public string LeftTextClass { get; set; } = "";
[Parameter]
public string RightTextClass { get; set; } = "";
#endregion Public Properties
@@ -64,7 +71,7 @@ namespace WebDoorCreator.UI.Components.SvgComp
protected void execFunc()
{
EC_ExeFunct.InvokeAsync(Message);
EC_ExeFunct.InvokeAsync(true);
}
protected override void OnParametersSet()
@@ -0,0 +1,27 @@
<svg viewBox="0 0 @ObjW @ObjH" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="theClippingPath">
<path d="@PathClipData" />
</clipPath>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#34495E"></rect>
<image href="@ImagePath" height="100%" width="100%" clip-path="url(#theClippingPath)"></image>
<path d="@PathLineData" stroke="@LineColor" stroke-width="@LineWidth" fill="none" />
<g transform="translate(0,@(ObjH/4))">
<foreignObject width="@(ObjW/2)" height="@(ObjH/2)">
<div class="row text-white text-center">
<div style="@TitleStyle" class="text-uppercase">
@TitleText
</div>
<div style="@BodyStyle">
@BodyText
</div>
<div class="mt-5">
<button class="btn btn-lg btn-primary rounded-pill p-3 px-4 text-uppercase" @onclick="() => raiseEvent()">
@ButtonText
</button>
</div>
</div>
</foreignObject>
</g>
</svg>
@@ -0,0 +1,164 @@
using Microsoft.AspNetCore.Components;
namespace WebDoorCreator.UI.Components.SvgComp
{
public partial class HomeCard
{
#region Public Properties
[Parameter]
public string BodyStyle { get; set; } = "font-size: 2em;";
[Parameter]
public string BodyText { get; set; } = "Body Text";
[Parameter]
public string ButtonText { get; set; } = "Button Text";
[Parameter]
public EventCallback<bool> EC_ExeFunct { get; set; }
[Parameter]
public string ImagePath { get; set; } = "images/DOORBG.png";
[Parameter]
public string LineColor { get; set; } = "#3989CC";
[Parameter]
public int LineWidth { get; set; } = 16;
[Parameter]
public int ObjH { get; set; } = 204;
[Parameter]
public int ObjId { get; set; } = 0;
[Parameter]
public int ObjW { get; set; } = 450;
[Parameter]
public int StartPoint { get; set; } = 220;
[Parameter]
public string TitleStyle { get; set; } = "font-size: 5.5em;";
[Parameter]
public string TitleText { get; set; } = "Title Text";
#endregion Public Properties
#region Protected Properties
protected List<PointData> PathClip { get; set; } = null!;
protected string PathClipData
{
get
{
//string path = $"{PathLineData} L1200,0 L1920,0 L1920,1080 L900,1080 Z";
string path = PathLineData;
if (pathClipCloseList.Count > 0)
{
for (int i = 0; i < pathClipCloseList.Count; i++)
{
path += $" L{pathClipCloseList[i].px},{pathClipCloseList[i].py}";
}
}
path += " Z";
return path;
}
}
protected List<PointData> PathLine { get; set; } = null!;
protected string PathLineData
{
get
{
string path = "";
if (pathPointList.Count > 0)
{
path = $"M{pathPointList[0].px},{pathPointList[0].py} Q";
for (int i = 1; i < pathPointList.Count; i++)
{
path += $" {pathPointList[i].px},{pathPointList[i].py}";
}
}
return path;
}
}
#endregion Protected Properties
#region Protected Methods
protected void execFunc()
{
EC_ExeFunct.InvokeAsync(true);
}
protected override void OnParametersSet()
{
setupGraphParams();
}
protected void setupGraphParams()
{
pathPointList = new List<PointData>();
pathClipCloseList = new List<PointData>();
// calcolo i dati necessari a disegnare
int deltaX = (ObjW / 2 - StartPoint) / 6;
int deltaY = ObjH / 3;
// inizio aggiungendo punti parametrici
pathPointList.Add(new PointData(StartPoint, ObjH));
pathPointList.Add(new PointData(StartPoint - deltaX, ObjH - (deltaY / 2)));
pathPointList.Add(new PointData(StartPoint + deltaX, ObjH - deltaY));
pathPointList.Add(new PointData((ObjW / 2) - deltaX * 3, (ObjH / 2) + deltaY / 8));
pathPointList.Add(new PointData(ObjW / 2, ObjH / 2));
pathPointList.Add(new PointData((ObjW / 2) + deltaX * 3, (ObjH / 2) - deltaY / 8));
pathPointList.Add(new PointData(ObjW - (StartPoint + deltaX), deltaY));
pathPointList.Add(new PointData(ObjW - (StartPoint - deltaX), (deltaY / 2)));
pathPointList.Add(new PointData(ObjW - StartPoint, 0));
// ora provvedo x la parte clip
pathClipCloseList.Add(new PointData(ObjW - StartPoint, 0));
pathClipCloseList.Add(new PointData(ObjW, 0));
pathClipCloseList.Add(new PointData(ObjW, ObjH));
pathClipCloseList.Add(new PointData(StartPoint, ObjH));
}
protected List<PointData> pathPointList = new List<PointData>();
protected List<PointData> pathClipCloseList = new List<PointData>();
#endregion Protected Methods
#region Protected Classes
protected class PointData
{
#region Public Constructors
public PointData(int valx, int valy)
{
px = valx;
py = valy;
}
#endregion Public Constructors
#region Public Properties
public int px { get; set; } = 0;
public int py { get; set; } = 0;
#endregion Public Properties
}
protected async Task raiseEvent()
{
await EC_ExeFunct.InvokeAsync(true);
}
#endregion Protected Classes
}
}
@@ -1,7 +0,0 @@
<svg viewBox="0 0 @ObjW @ObjH" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<rect width="@rectW" height="@rectH" style="@BlockStyle" transform="skewX(@tipSize)" />
<g transform="translate(@tipSize,@rectH)">
<rect width="@rectW" height="@rectH" style="@BlockStyle" transform="skewX(@(-tipSize))" />
</g>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" style="@TextStyle">@StepText</text>
</svg>
@@ -1,58 +0,0 @@
using Microsoft.AspNetCore.Components;
namespace WebDoorCreator.UI.Components.SvgComp
{
public partial class StepArrow
{
#region Public Properties
[Parameter]
public int ObjH { get; set; } = 100;
[Parameter]
public int ObjId { get; set; } = 0;
[Parameter]
public int ObjW { get; set; } = 500;
[Parameter]
public string StepText { get; set; } = "Arrow Stepped";
[Parameter]
public string TextStyle { get; set; } = "font-size: 2.5em; font-weight:bold; fill: white;";
[Parameter]
public string BlockStyle { get; set; } = "fill:rgb(0,0,255);stroke-width:0;stroke:rgb(0,0,0);";
[Parameter]
public string BlockStyleBorderUp { get; set; } = "stroke-width:5px;stroke:rgb(255,255,255);stroke-dasharray: 650,600;";
#endregion Public Properties
#region Protected Properties
protected int deltaH
{
get => ObjH / 100;
}
protected int rectH
{
get => (ObjH / 2);
//* (96 / 100);
}
protected int rectW
{
get => ObjW - ObjH / 2;
}
protected int tipSize
{
get => ObjH / 3;
}
#endregion Protected Properties
}
}
@@ -0,0 +1,78 @@
namespace WebDoorCreator.UI.Data
{
public class DoorsSelectFilter
{
#region Public Constructors
public DoorsSelectFilter()
{ }
#endregion Public Constructors
#region Public Properties
public int CurrPage { get; set; } = 1;
public string Id { get; set; } = "*";
public string searchValue { get; set; } = "";
public int MaxRecord { get; set; } = 100;
public int NumRec { get; set; } = 10;
public int TotCount { get; set; } = 0;
#endregion Public Properties
#region Public Methods
public DoorsSelectFilter clone()
{
DoorsSelectFilter clonedData = new DoorsSelectFilter()
{
CurrPage = this.CurrPage,
MaxRecord = this.MaxRecord,
NumRec = this.NumRec,
searchValue = this.searchValue,
TotCount = this.TotCount,
Id = this.Id
};
return clonedData;
}
public override bool Equals(object? obj)
{
if (obj == null)
return false;
if (!(obj is OrderSelectFilter item))
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (NumRec != item.NumRec)
return false;
if (TotCount != item.TotCount)
return false;
if (searchValue != item.searchValue)
return false;
if (CurrPage != item.CurrPage)
return false;
if (Id != item.Id)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
@@ -201,7 +201,7 @@ namespace WebDoorCreator.UI.Data
TableName = "All",
FieldName = "OrderStep",
Value = "10",
Label = "DoorDef",
Label = "Door Draft",
Ordinal = 10,
DefaultVal = "#EF6C00",
InputType = ""
@@ -212,7 +212,7 @@ namespace WebDoorCreator.UI.Data
TableName = "All",
FieldName = "OrderStep",
Value = "20",
Label = "Sent",
Label = "Sent to ABH",
Ordinal = 20,
DefaultVal = "#FBC02D",
InputType = ""
@@ -223,7 +223,7 @@ namespace WebDoorCreator.UI.Data
TableName = "All",
FieldName = "OrderStep",
Value = "30",
Label = "ApprovedByMaker",
Label = "Approved By Maker",
Ordinal = 30,
DefaultVal = "#2962FF",
InputType = ""
@@ -234,7 +234,7 @@ namespace WebDoorCreator.UI.Data
TableName = "All",
FieldName = "OrderStep",
Value = "40",
Label = "ApprovedByCustomer",
Label = "Approved By Customer",
Ordinal = 40,
DefaultVal = "#673AB7",
InputType = ""
@@ -256,7 +256,7 @@ namespace WebDoorCreator.UI.Data
TableName = "All",
FieldName = "OrderStep",
Value = "60",
Label = "InProduction",
Label = "In Production",
Ordinal = 60,
DefaultVal = "#43A047",
InputType = ""
@@ -272,6 +272,7 @@ namespace WebDoorCreator.UI.Data
DefaultVal = "#AEEA00",
InputType = ""
};
listValues.Add(listValObj);
listValObj = new ListValuesTempModel()
{
@@ -459,6 +460,27 @@ namespace WebDoorCreator.UI.Data
isSerializable = true
};
listValues.Add(listValObj);
int i = 0;
#if false
var o = listActiveCompo.ToArray();
for (int t = 0; t < dirs.Length; t++)
{
var dirPath = dirs[t];
var h = dirPath.Split("\\");
var c = h[h.Length - 1];
c = o[t];
StringBuilder sb = new StringBuilder();
foreach (var item in h)
{
sb.Append($"{item}\\");
}
sb.Append(c);
dirs[t] = $"{sb}";
}
#endif
foreach (string dir in dirs)
{
int numPar = 1;
@@ -488,6 +510,10 @@ namespace WebDoorCreator.UI.Data
string layerName = fIni.ReadString("Layer", "LayerName", "LAYER");
// lo slash indica l'alias
var compoNameSplit = compoName.Split("/");
var compoAcArray = listActiveCompo.ToArray();
var x = Array.FindIndex(compoAcArray, row => row == compoNameSplit[0]);
if (listActiveCompo.Contains(compoNameSplit[0].ToString()))
{
//creo il componente (padre)
@@ -497,7 +523,7 @@ namespace WebDoorCreator.UI.Data
FieldName = "Hardware",
Value = $"{compoNameSplit[0]}",
Label = $"{compoNameSplit[1]}",
Ordinal = 0,
Ordinal = x,
DefaultVal = " ",
InputType = " "
};
@@ -505,6 +531,7 @@ namespace WebDoorCreator.UI.Data
//await dbController.CompoAdd(compoConfig);
//listCompoS.Add(compoConfig);
listValues.Add(listValObj);
i++;
//cerco all'interno del file tutte le sezioni che contengono "[Graphic" così da poter prendere il nome della sezione ES: [Graphic parameters1] = Graphic parameters1
var lineToSearch = lines.Where(x => x.Contains("[Graphic")).ToList();
numHead = 1;
@@ -695,7 +722,7 @@ namespace WebDoorCreator.UI.Data
/// <summary>
/// Doors list by orderId
/// </summary>
public async Task<List<DoorOpModel>?> DoorOpGetByDoorId(int doorId)
public async Task<List<DoorOpModel>> DoorOpGetByDoorId(int doorId)
{
string source = "DB";
List<DoorOpModel>? dbResult = new List<DoorOpModel>();
@@ -732,6 +759,26 @@ namespace WebDoorCreator.UI.Data
Log.Debug($"DoorOpGetByDoorId | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Doors list by orderId
/// </summary>
public async Task<DoorOpModel> DoorOpGetById(int doorOpId)
{
await Task.Delay(1);
string source = "DB";
DoorOpModel? dbResult = new DoorOpModel();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.DoorOpGetById(doorOpId);
if (dbResult == null)
{
dbResult = new DoorOpModel();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"DoorOpGetById | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// lista DoorOpList necessarie all'init
@@ -33,6 +33,10 @@
{
<HardwareList isHwStep="@setHwToNull" DoorId="@idDoor" Lingua="@userLang"></HardwareList>
}
else if (currDefStep == 30)
{
<ReportList doorId="@idDoor" Lingua="@userLang"></ReportList>
}
</CascadingValue>
</div>
</div>
@@ -0,0 +1,26 @@
@page "/HwPdfConfirm"
@if (currDoorOp != null)
{
<div>
@*@if (currDoorOp.DtConfirm != null && currDoorOp.userConfirm != "")
{*@
<div class="col-10 text-center mb-2">
Please press
<button class="btn btn-outline-dark" style="cursor: pointer;" @onclick="()=>doConfirm()">
CONFIRM
</button>
after reading the whole file
</div>
@*}
else
{
<div class="col-10 text-center mb-2">
<span>Template already confirmed by user: <b>@currDoorOp.userConfirm</b> on <b>@currDoorOp.DtConfirm</b></span>
</div>
}*@
<embed src="Docs/1001.pdf" width="100%" height="800px" />
</div>
}
@@ -0,0 +1,80 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Newtonsoft.Json;
using WebDoorCreator.Data.DbModels;
using WebDoorCreator.UI.Data;
namespace WebDoorCreator.UI.Pages
{
public partial class HwPdfConfirm
{
[Inject]
protected NavigationManager NavManager { get; set; } = null!;
[Inject]
protected WDCUserService WDCUService { get; set; } = null!;
protected int idHwInst { get; set; } = 0;
protected DoorOpModel currDoorOp { get; set; } = new DoorOpModel();
protected List<DoorOpModel> allDoorOps { get; set; } = new List<DoorOpModel>();
protected async override Task OnInitializedAsync()
{
await Task.Delay(1);
var uri = NavManager.ToAbsoluteUri(NavManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("idHwInst", out var _idHwInst))
{
idHwInst = int.Parse(_idHwInst);
await ReloadData();
}
}
protected async Task ReloadData()
{
currDoorOp = await WDService.DoorOpGetById(idHwInst);
if (currDoorOp != null)
{
allDoorOps = await WDService.DoorOpGetByDoorId(currDoorOp.DoorId);
}
await Task.Delay(1);
}
[Inject]
protected WebDoorCreatorService WDService { get; set; } = null!;
protected async Task doConfirm()
{
currDoorOp.userConfirm = WDCUService.userId;
currDoorOp.DtConfirm = DateTime.Now;
var doorOps2Save = new List<DoorOpModel>() { currDoorOp };
await WDService.DoorOpUpdate(doorOps2Save);
}
protected bool checkIfConf()
{
bool answ = false;
if (allDoorOps != null)
{
var rawObj = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(currDoorOp.JsoncActVal!);
if (rawObj != null)
{
foreach (var op in allDoorOps)
{
var opObj = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(op.JsoncActVal!);
if (opObj != null)
{
if (rawObj["template"] == opObj["template"] && op.DtConfirm != null && op.userConfirm != "")
{
answ = true;
}
}
}
}
}
return answ;
}
}
}
@@ -0,0 +1 @@

@@ -0,0 +1 @@

+1
View File
@@ -0,0 +1 @@

+5 -5
View File
@@ -2,8 +2,8 @@
<PageTitle>Index</PageTitle>
<div class="bgbg">
<div class="transpLayer">
<div class="fs-1 p-2 px-3">Web Door Creator</div>
</div>
</div>
<div class="shadow-lg">
<HomeCard ObjH="900" ObjW="1920" StartPoint="820" LineWidth="18" TitleText="Web Door Creator" BodyText="The new way to create doors" ImagePath="images/HeroSecDoor.png" EC_ExeFunct="changePage" ButtonText="Go To Orders"></HomeCard>
</div>
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using WebDoorCreator.UI;
using WebDoorCreator.UI.Components;
using WebDoorCreator.UI.Components.Buttons;
using WebDoorCreator.UI.Components.CompMan;
using WebDoorCreator.UI.Components.DoorMan;
using WebDoorCreator.UI.Components.DoorDef;
using WebDoorCreator.UI.Components.Gen;
using WebDoorCreator.UI.Components.Order;
using WebDoorCreator.UI.Components.Users;
using WebDoorCreator.UI.Components.Hardware;
using WebDoorCreator.UI.Components.SvgComp;
using WebDoorCreator.UI.Components.Filters;
using WebDoorCreator.UI.Shared;
using WebDoorCreator.Data.DbModels;
using EgwCoreLib.Razor;
namespace WebDoorCreator.UI.Pages
{
public partial class Index
{
[Inject]
protected NavigationManager NavManager { get; set; } = null!;
protected async Task changePage(bool newPage)
{
await Task.Delay(1);
NavManager.NavigateTo("OrdersHomePage");
}
}
}
+12 -9
View File
@@ -25,14 +25,14 @@
<div>&nbsp;</div>
<div class="fw-bold">@orderView.NumDoors</div>
</div>
@*
<div class="input-group">
<select @bind="@currMeaUnit" class="form-select">
<option value="mm">mm</option>
<option value="inch">inch</option>
</select>
<button class="btn btn-sm btn-success" @onclick="() => createDoor()">+ Add new door</button>
</div>*@
@*
<div class="input-group">
<select @bind="@currMeaUnit" class="form-select">
<option value="mm">mm</option>
<option value="inch">inch</option>
</select>
<button class="btn btn-sm btn-success" @onclick="() => createDoor()">+ Add new door</button>
</div>*@
</div>
}
@@ -42,5 +42,8 @@
</div>
</div>
<div class="p-5 cardDoors">
<DoorList currOrderId="@idOrd"></DoorList>
<DoorList currOrderId="@idOrd" updateRecordCount="UpdateTotCount" actFilter="@currFilter"></DoorList>
<div class="mt-4">
<EgwCoreLib.Razor.DataPager @ref="pagerDoors" PageSize="@numRecord" currPage="@currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="@totalCount" showLoading="@isLoading" />
</div>
</div>
+52 -1
View File
@@ -1,3 +1,4 @@
using EgwCoreLib.Razor;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Newtonsoft.Json;
@@ -11,6 +12,8 @@ namespace WebDoorCreator.UI.Pages
{
#region Public Properties
protected DataPager? pagerDoors = null!;
public string userId
{
get
@@ -106,8 +109,56 @@ namespace WebDoorCreator.UI.Pages
#region Private Fields
private List<OrderStatusViewModel>? ListOrdersStatus = null;
#endregion Private Fields
protected DoorsSelectFilter currFilter { get; set; } = new DoorsSelectFilter();
private int currPage
{
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private string searchValue
{
get => currFilter.searchValue;
set => currFilter.searchValue = value;
}
protected int totalCount { get; set; }
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
private async Task updateFilter(DoorsSelectFilter newParams)
{
isLoading = true;
await Task.Delay(1);
currPage = 1;
searchValue = newParams.searchValue;
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
currFilter = newParams;
isLoading = false;
}
}
}
+24 -16
View File
@@ -19,26 +19,34 @@
</div>
</div>*@
<div class="d-flex justify-content-between">
@*<div>
<div style="border-radius: 18px; padding: 1rem 4rem 0.5rem 4rem; box-shadow: rgba(0, 0, 0, 0.45) 0px 20px 22px -9px; margin-top: 0.5rem; margin-bottom: 1rem;">
<div class="row mb-3">
@*<div>
<img src="images/LogoEgw.png" style="width: 30%;height: auto;box-shadow:rgba(0, 0, 0, 0.45) 0px -8px 22px -9px;" />
</div>*@
<div class="fw-bold fs-2 text-center">
WEB DOOR CREATOR
</div>
<div>
<OrderFilter FilterUpdated="updateFilter"></OrderFilter>
</div>
@* <div class="text-end">
</div>*@
<div class="fw-bold fs-2 text-start col-4">
WEB DOOR CREATOR
</div>
<div class="d-flex justify-content-between col-8">
<OrderFilter FilterUpdated="updateFilter"></OrderFilter>
<button type="button" class="btn btn-sm btn-success" data-bs-toggle="modal" data-bs-target="#newOrderModal">
<i class="fa-solid fa-plus"></i> Add new order
</button>
</div>
@* <div class="text-end">
<img src="images/LogoEgw.png" style="width: 30%;height: auto;box-shadow:rgba(0, 0, 0, 0.45) 0px -8px 22px -9px;" />
</div>*@
</div>
<div style="border-radius: 18px; padding: 1rem 4rem 0.5rem 4rem; box-shadow: rgba(0, 0, 0, 0.45) 0px -18px 22px -9px; margin-top: 50px; margin-bottom: 50px;">
<OrderList updateRecordCount="UpdateTotCount" actFilter="@currFilter" E_currOrderStatus="catchCurrOrder" B_doorChaged="@doorChange" UserCurrCompany="@userCurrCompany"></OrderList>
</div>*@
</div>
<div style="min-height: 35rem;">
<OrderList updateRecordCount="UpdateTotCount" actFilter="@currFilter" E_currOrderStatus="catchCurrOrder" B_doorChaged="@doorChange" UserCurrCompany="@userCurrCompany"></OrderList>
</div>
<div class="mt-2">
<EgwCoreLib.Razor.DataPager @ref="pagerOrderHP" PageSize="@numRecord" currPage="@currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="@totalCount" showLoading="@isLoading" />
</div>
</div>
<EgwCoreLib.Razor.DataPager @ref="pagerOrderHP" PageSize="@numRecord" currPage="@currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="@totalCount" showLoading="@isLoading" />
<!-- Modal Order -->
<div class="modal fade" id="newOrderModal" tabindex="-1" aria-labelledby="newOrderModalLabel" aria-hidden="true">
<div class="modal-dialog">
+16 -17
View File
@@ -8,9 +8,8 @@ namespace WebDoorCreator.UI.Pages
{
public partial class OrdersHomePage : IDisposable
{
public OrderSelectFilter currFilter { get; set; } = new OrderSelectFilter();
protected DataPager? pagerOrderHP = null!;
protected OrderSelectFilter currFilter { get; set; } = new OrderSelectFilter();
#region Public Properties
[Parameter]
@@ -222,25 +221,14 @@ namespace WebDoorCreator.UI.Pages
#endregion Protected Methods
protected int totalCount { get; set; }
private int currPage
{
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private string searchValue
{
get => currFilter.searchValue;
set => currFilter.searchValue = value;
}
private DateTime dateFrom
{
get => currFilter.DateFrom;
@@ -252,14 +240,25 @@ namespace WebDoorCreator.UI.Pages
get => currFilter.DateTo;
set => currFilter.DateTo = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private int orderStatus
{
get => currFilter.OrderStatus;
set => currFilter.OrderStatus = value;
}
protected int totalCount { get; set; }
private string searchValue
{
get => currFilter.searchValue;
set => currFilter.searchValue = value;
}
protected void ForceReload(int newNum)
{
numRecord = newNum;
+1 -1
View File
@@ -15,7 +15,7 @@ using WebDoorCreator.Data.Services;
using WebDoorCreator.UI.Areas.Identity;
using WebDoorCreator.UI.Data;
var builder = WebApplication.CreateBuilder(args);
var builder = WebApplication.CreateBuilder(args);
// configuration setup
ConfigurationManager configuration = builder.Configuration;
+12 -8
View File
@@ -16,15 +16,9 @@
<NavMenuHorizontal></NavMenuHorizontal>
</div>
@if (NavManager.Uri.Contains("OrderDetails"))
@if (NavManager.Uri == NavManager.BaseUri)
{
<article class="px-2 content">
@Body
</article>
}
else if (NavManager.Uri.Contains("DoorDefinition"))
{
<article class="px-4 py-0 content">
<article class="p-0 content">
@Body
</article>
}
@@ -34,6 +28,16 @@
@Body
</article>
}
@*else if (NavManager.Uri.Contains("DoorDefinition"))
{
<article class="px-4 py-0 content">
@Body
</article>
}
else
{
}*@
@*<div class="fixed-bottom bottom-row px-2">
<CmpFooter></CmpFooter>
</div>*@
+1 -1
View File
@@ -34,7 +34,7 @@
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.SessionStorage" Version="2.3.0" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2303.215" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2305.1008" />
<PackageReference Include="EntityFrameworkCore.SqlServer.HierarchyId" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.14" />
+4 -1
View File
@@ -18,6 +18,9 @@
@using WebDoorCreator.UI.Components.Hardware
@using WebDoorCreator.UI.Components.SvgComp
@using WebDoorCreator.UI.Components.Filters
@using WebDoorCreator.UI.Components.Report
@using WebDoorCreator.UI.Shared
@using WebDoorCreator.Data.DbModels
@using WebDoorCreator.Data.DbModels
@using EgwCoreLib.Razor
+16
View File
@@ -46,5 +46,21 @@
{
"outputFile": "Components/Order/OrderList.razor.css",
"inputFile": "Components/Order/OrderList.razor.less"
},
{
"outputFile": "Components/DoorDef/DoorDataBlock.razor.css",
"inputFile": "Components/DoorDef/DoorDataBlock.razor.less"
},
{
"outputFile": "Pages/HwPdfConfirm.razor.css",
"inputFile": "Pages/HwPdfConfirm.razor.less"
},
{
"outputFile": "Components/Gen/NavMenuHorizontal.razor.css",
"inputFile": "Components/Gen/NavMenuHorizontal.razor.less"
},
{
"outputFile": "Components/Report/ReportList.razor.css",
"inputFile": "Components/Report/ReportList.razor.less"
}
]
+43 -5
View File
@@ -4,7 +4,7 @@
version: 2
produce: true
measures: inch
measures: inches
code: 0015943
order:
customer:
@@ -12,17 +12,22 @@ order:
project:
pO:
line:
date: 2023-05-05T00:00:00.0000000Z
date: 2023-11-05T00:00:00.0000000
piece: DO_1
properties: Maple
size: {}
swing: {}
properties: Pine
finishing: Varnishing
size:
width: 33.8125
height: 81.25
thickness: 1.75
swing: LH
swing: RH
secure: UP
material: wood
profiles: {}
hardware: {}
profiles:
lockedge:
type: SQ
@@ -40,6 +45,39 @@ profiles:
type: SQ
machining: ON
overmaterial: 0.1
hardware: {}
hardware:
flush_pulls:
- template: Generic\Circle
position: 35
back_set: 5
depth: 1
face: secure
- template: Generic\Circle
position: 35
back_set: 5
depth: 1
face: secure
locks:
- template: Generic\DocMyTest5Bore.nge
position: 45.875
back_set: 2.0
offset_WS: 0.0
side: lock_top
hinges:
- template: Generic Conceiled\StdConHingeDeepR
ToptoCL: 4.875
back_set: 0.125
thickness: 0.25
groove:
- template: Generic\Groove
type: side
width: 0.6
depth: 0.8
offset_WS: 0
side: bottom
---
Binary file not shown.
+3
View File
@@ -26,6 +26,9 @@ a,
background-color: #AEEA00;
color: #000;
}
#viewer > #toolbar {
display: none;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
+4
View File
@@ -32,6 +32,10 @@ a, .btn-link {
color: #000;
}
#viewer > #toolbar {
display: none;
}
.btn-primary {
color: #fff;
+1 -1
View File
@@ -1 +1 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');html,body{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;}h1:focus{outline:0;}a,.btn-link{color:#0071c1;}.bg-orange{background-color:#ef6c00;color:#000;}.bg-purple{background-color:#673ab7;color:#fff;}.bg-turquoise{background-color:#00b8d4;color:#000;}.bg-lGreen{background-color:#aeea00;color:#000;}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac;}.content{padding-top:1.1rem;}.valid.modified:not([type=checkbox]){outline:1px solid #26b050;}.invalid{outline:1px solid #f00;}.validation-message{color:#f00;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.blazor-error-boundary{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem,#b32121;padding:1rem 1rem 1rem 3.7rem;color:#fff;}.blazor-error-boundary::after{content:"An error has occurred.";}
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');html,body{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;}h1:focus{outline:0;}a,.btn-link{color:#0071c1;}.bg-orange{background-color:#ef6c00;color:#000;}.bg-purple{background-color:#673ab7;color:#fff;}.bg-turquoise{background-color:#00b8d4;color:#000;}.bg-lGreen{background-color:#aeea00;color:#000;}#viewer>#toolbar{display:none;}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac;}.content{padding-top:1.1rem;}.valid.modified:not([type=checkbox]){outline:1px solid #26b050;}.invalid{outline:1px solid #f00;}.validation-message{color:#f00;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.blazor-error-boundary{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem,#b32121;padding:1rem 1rem 1rem 3.7rem;color:#fff;}.blazor-error-boundary::after{content:"An error has occurred.";}
Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB