Merge branch 'Release/MpMon_07'

This commit is contained in:
Samuele Locatelli
2025-03-18 19:30:13 +01:00
22 changed files with 1197 additions and 28 deletions
-6
View File
@@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.MON", "MP.MON\MP.MON.csproj", "{82FD7CF4-42A2-499C-88FC-46502D166F70}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.MON.Client", "MP.MON.Client\MP.MON.Client.csproj", "{162B91FA-4BFD-4270-966A-C5E8B5DC1346}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.Core", "MP.Core\MP.Core.csproj", "{4F652F76-AC46-444D-B808-40102F2F05C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.TaskMan", "MP.TaskMan\MP.TaskMan.csproj", "{3447D4AF-13C2-47BB-8C5F-74299A46D063}"
@@ -27,10 +25,6 @@ Global
{82FD7CF4-42A2-499C-88FC-46502D166F70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82FD7CF4-42A2-499C-88FC-46502D166F70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82FD7CF4-42A2-499C-88FC-46502D166F70}.Release|Any CPU.Build.0 = Release|Any CPU
{162B91FA-4BFD-4270-966A-C5E8B5DC1346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{162B91FA-4BFD-4270-966A-C5E8B5DC1346}.Debug|Any CPU.Build.0 = Debug|Any CPU
{162B91FA-4BFD-4270-966A-C5E8B5DC1346}.Release|Any CPU.ActiveCfg = Release|Any CPU
{162B91FA-4BFD-4270-966A-C5E8B5DC1346}.Release|Any CPU.Build.0 = Release|Any CPU
{4F652F76-AC46-444D-B808-40102F2F05C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F652F76-AC46-444D-B808-40102F2F05C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F652F76-AC46-444D-B808-40102F2F05C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+2 -2
View File
@@ -18,7 +18,7 @@
<Routes />
<script src="lib/WindowSize.js"></script>
<script src="_framework/blazor.web.js"></script>
<script>
@* <script>
Blazor.start({
reconnectionOptions: {
maxRetries: 600,
@@ -32,7 +32,7 @@
}, 5000);
}
});
</script>
</script> *@
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<div class="d-flex justify-content-between text-light fs-4">
<div class="px-1">
<b>Mapo MON @(DateTime.Today.Year)</b> | <span class="small">v.@version</span>
</div>
<div class="px-2">
@if (Width > 0)
{
}
<small class="small align-items-center">@Width x @Height | </small>
<small class="ps-1 small align-items-center">@(OperatingSystem.IsBrowser() ? "WASM" : "Server")</small>
| <a class="text-light" href="https://www.egalware.com/" target="_blank"><img class="img-fluid" width="16" src="images/LogoEgw.png" /> Egalware </a>
</div>
</div>
+109
View File
@@ -0,0 +1,109 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
namespace MP.MON.Components.Compo
{
public partial class CmpFooter : ComponentBase, IDisposable
{
#region Public Properties
[Parameter]
public Version version { get; set; } = null!;
#endregion Public Properties
#region Public Methods
public void Dispose()
{
aTimer.Stop();
aTimer.Dispose();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
//Console.WriteLine($"{DateTime.Now} | Elapsed Timer Footer");
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
}
public void StartTimer()
{
int tOutPeriod = 1000;
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
#endregion Public Methods
#region Public Classes
public class WindowDimension
{
#region Public Properties
public int Height { get; set; }
public int Width { get; set; }
#endregion Public Properties
}
#endregion Public Classes
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task getWDim()
{
var dimension = await JSRuntime.InvokeAsync<WindowDimension>("getWindowDimensions");
Height = dimension.Height;
Width = dimension.Width;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await getWDim();
StateHasChanged();
Console.WriteLine($"Dimensioni schermo: {Width}x{Height}");
}
//Console.WriteLine($"OnAfterRenderAsync completato");
}
protected override void OnInitialized()
{
StartTimer();
Console.WriteLine($"OnInitialized Footer completato");
}
#endregion Protected Methods
#region Private Fields
private static System.Timers.Timer aTimer = null!;
#endregion Private Fields
#region Private Properties
private int Height { get; set; } = 0;
private int Width { get; set; } = 0;
#endregion Private Properties
}
}
+20
View File
@@ -0,0 +1,20 @@
<div class="px-2">
<img class="logoImg img-fluid" src="images/LogoMapo.png" height="20" />
<span class="px-5 mx-5">&nbsp;</span>
</div>
<div class="px-2">
<NavLink class="mainHead p-3 align-middle" href="force-reload" style="text-decoration:none;">
<span class="fs-2"><span style="color: #DEDEDE;">Mapo MON</span>itor</span>
</NavLink>
</div>
<div class="px-2">
<span id="text-white text-right">
@($"{DateTime.Now:yyyy.MM.dd}")
</span>
<span class="text-white fw-bold fs-2">
@($"{DateTime.Now:HH:mm:ss}")
</span>
@* <img class="logoImg img-fluid" src="images/logoCliente.png" height="24" />
<span class=" text-white">EgalWare</span> *@
</div>
@@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Components;
namespace MP.MON.Components.Compo
{
public partial class CmpHeader: ComponentBase, IDisposable
{
protected override void OnInitialized()
{
StartTimer();
Console.WriteLine($"OnInitialized Header completato");
}
public void Dispose()
{
aTimer.Stop();
aTimer.Dispose();
}
private static System.Timers.Timer aTimer;
public void StartTimer()
{
int tOutPeriod = 1000;
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
public void ElapsedTimer(Object source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
//Console.WriteLine($"{DateTime.Now} | Elapsed Timer Footer");
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
}
}
}
+145
View File
@@ -0,0 +1,145 @@
<div class="m-0 pe-1">
@if (CurrRecord == null || !dataLoaded)
{
<LoadingDataSmall></LoadingDataSmall>
}
else
{
<div class="@cssStatus(CurrRecord.Semaforo) p-1 @overlayCss">
<div class="d-flex ui-title justify-content-center align-items-center text-uppercase">
<div class="px-0 @textDescrCss(@CurrRecord.Nome, maxChar4Scroll)">
<span>@CurrRecord.Nome</span>
</div>
</div>
@if (hasRow(1))
{
<div class="d-flex ui-subtitle justify-content-between py-0 px-1">
@foreach (var item in rowValues(1))
{
<div class="px-0 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex ui-subtitle justify-content-between py-0 px-1 fontSmall text-uppercase">
<div class="px-1">Art</div>
<div class="px-1 ui-art">
@if (showArt == "CodArticolo")
{
<span>@CurrRecord.CodArticolo</span>
}
else
{
if (string.IsNullOrEmpty(CurrRecord.Disegno))
{
<span>[@CurrRecord.CodArticolo]</span>
}
else
{
<span>@CurrRecord.Disegno</span>
}
}
</div>
</div>
}
@if (hasRow(2))
{
<div class="d-flex ui-subtitle justify-content-between py-0 px-1">
@foreach (var item in rowValues(2))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex ui-subtitle justify-content-between py-0 px-1 fontSmall text-uppercase">
<div class="px-1">PODL</div>
<div class="px-1 ui-art">@(CurrRecord.IdxPOdl > 0 ? $"{CurrRecord.IdxPOdl:00000000}" : "-")</div>
</div>
<div class="d-flex ui-subtitle justify-content-between py-0 px-1 fontSmall text-uppercase">
<div class="px-1">ODL</div>
<div class="px-1 ui-art">@(CurrRecord.IdxOdl > 0 ? $"{CurrRecord.IdxOdl:00000000}" : "-")</div>
</div>
}
@if (hasRow(3))
{
<div class="d-flex justify-content-between py-0 mt-1 px-1">
@foreach (var item in rowValues(3))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex justify-content-between pt-0 mt-1 pb-1 px-1 fontSmall text-uppercase">
<div class="px-1 text-truncate">@CurrRecord.DescrizioneStato</div>
<div class="px-1 ps-0 text-nowrap">@getMinSec(getDecimal(@CurrRecord.Durata))</div>
</div>
}
@if (hasRow(4))
{
<div class="d-flex justify-content-between py-0 px-1">
@foreach (var item in rowValues(4))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex justify-content-between pt-0 pb-1 px-1 fontSmall text-uppercase2">
<div class="px-1 pe-0">TC. Act</div>
@* <div class="px-1 ps-0">std @getMinSec(@CurrRecord.TCAssegnato)</div> *@
<div class="px-1 ps-0">@getMinSec(@CurrRecord.TCLavRT) <small>[@getMinSec(@CurrRecord.TCAssegnato)]</small></div>
</div>
}
@if (hasRow(5))
{
<div class="d-flex justify-content-between py-0 px-1">
@foreach (var item in rowValues(5))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex justify-content-between py-0 px-1 fontSmall text-uppercase">
<div class="px-1 pe-0">Pezzi<small class="small"><sub>p/o</sub></small></div>
<div class="px-1 ps-0">@CurrRecord.PezziProd / @CurrRecord.NumPezzi</div>
</div>
}
@if (hasRow(6))
{
<div class="d-flex justify-content-between py-0 px-1">
@foreach (var item in rowValues(6))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
</div>
<div class="@cssComStatus(CurrRecord.Semaforo, CurrRecord.LastUpdate) p-1">
<div class="row fontSmaller mt-1">
<div class="col-12">
<div class="text-right ui-footer px-2">
<div class="row">
@if (showComErr(CurrRecord.LastUpdate))
{
<div class="col text-warning">
<b>C.101</b>
</div>
}
<div class="col text-end">
@CurrRecord.LastUpdate
</div>
</div>
</div>
</div>
</div>
</div>
}
</div>
+322
View File
@@ -0,0 +1,322 @@
using Microsoft.AspNetCore.Components;
using MP.Core.Conf;
using MP.Core.DTO;
namespace MP.MON.Components.Compo
{
public partial class DetailMSE : ComponentBase
{
#region Public Properties
[Parameter]
public string cssOverlayOff { get; set; } = "";
[Parameter]
public MappaStatoExplDTO? CurrRecord { get; set; } = null;
[Parameter]
public List<TagData>? currTagConf { get; set; } = null;
[Parameter]
public Dictionary<string, string> currTagVal { get; set; } = new Dictionary<string, string>();
[Parameter]
public bool doAnimate { get; set; } = true;
[Parameter]
public bool doBlink { get; set; } = false;
[Parameter]
public int keepAliveMin { get; set; } = 5;
[Parameter]
public int maxChar4Scroll { get; set; } = 20;
[Parameter]
public string showArt { get; set; } = "";
#endregion Public Properties
#region Public Methods
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
// verifica variazione x blink...
bool needUpdate = false;
if (CurrRecord == null)
{
needUpdate = true;
}
else
{
if (OldRecord == null)
{
needUpdate = true;
}
else
{
if (!CurrRecord.Semaforo.Equals(OldRecord.Semaforo) || CurrRecord.Semaforo != "sVe")
{
needUpdate = true;
}
}
}
if (needUpdate)
{
await InvokeAsync(() => StateHasChanged());
}
OldRecord = CurrRecord;
});
pUpd.Wait();
}
public void StartTimer()
{
int tOutPeriod = 1000;
//int.TryParse(Configuration["ReloadStatusTimer"], out tOutPeriod);
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
#endregion Public Methods
#region Protected Fields
protected string baseCss = "sem";
protected int kaFactor = 60 / 2;
#endregion Protected Fields
#region Protected Properties
protected string codIOB
{
get
{
string answ = "";
if (CurrRecord != null)
{
answ = CurrRecord.IdxMacchina;
}
return answ;
}
}
protected bool dataLoaded { get; set; } = false;
/// <summary>
/// CSS Class x overlay (effetto spento x macchina spenta/ sGr)
/// </summary>
protected string overlayCss
{
get
{
string answ = "";
if (CurrRecord != null)
{
answ = CurrRecord.Semaforo == "sGr" ? cssOverlayOff : "";
}
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// restituisce il valore data la tagLocation
/// </summary>
/// <param name="tagLocation"></param>
/// <returns></returns>
protected string currVal(string tagLocation)
{
string answ = "";
if (currTagVal.ContainsKey(tagLocation))
{
answ = currTagVal[tagLocation];
}
return answ;
}
/// <summary>
/// Verifica se ci sia un override per la riga indicata
/// </summary>
/// <param name="numRow"></param>
/// <returns></returns>
protected bool hasRow(int numRow)
{
bool answ = false;
if (currTagConf != null)
{
if (currTagConf.Count > 0)
{
var currVals = rowValues(numRow);
answ = currVals.Count > 0;
}
}
return answ;
}
protected override async Task OnInitializedAsync()
{
//StartTimer();
Random rnd = new Random();
await Task.Delay(rnd.Next(5));
setupConf();
dataLoaded = true;
}
/// <summary>
/// Restituisce (se presenti) valori di override per la riga indicata
/// </summary>
/// <param name="numRow"></param>
/// <returns></returns>
protected List<TagData> rowValues(int numRow)
{
List<TagData>? rowVals = null;
if (currTagConf != null)
{
if (currTagConf.Count > 0)
{
//cerco solo la riga corrente...
rowVals = currTagConf.Where(x => x.RowNum == numRow).ToList();
}
}
if (rowVals == null)
{
rowVals = new List<TagData>();
}
return rowVals;
}
/// <summary>
/// CSS class x testo (se descr lunga scorre...)
/// </summary>
protected string textDescrCss(string currText, int maxChar)
{
string answ = "text-nowrap";
if (currText.Length > maxChar)
{
answ = " scroll-left";
}
return answ;
}
#endregion Protected Methods
#region Private Properties
private static System.Timers.Timer aTimer { get; set; } = null!;
/// <summary>
/// Valore precedente x calcolo variazione
/// </summary>
private MappaStatoExplDTO? OldRecord { get; set; } = null;
#endregion Private Properties
#region Private Methods
private string cssComStatus(string semaforo, DateTime? lastUpdateN)
{
DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1);
string answ = cssStatus(semaforo);
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor))
{
answ = $"{baseCss}Ro";
// blink se secondo pari...
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
answ += "_b";
}
}
return answ;
}
private string cssStatus(string codSemaforo)
{
// se vuoto --> mostra nero!
if (string.IsNullOrEmpty(codSemaforo))
{
codSemaforo = "sNe";
}
string codColore = codSemaforo.Substring(1, 2);
string answ = $"{baseCss}{codColore}";
if (doAnimate && codColore != "Ve")
{
if (doBlink)
{
answ += "_b";
}
}
return answ;
}
private decimal getDecimal(object? rawData)
{
decimal answ = 0;
if (rawData != null)
{
decimal.TryParse($"{rawData}", out answ);
}
return answ;
}
private string getMinSec(decimal? currTimeMin)
{
string answ = "nd";
TimeSpan tSpan = new TimeSpan(0);
try
{
double cTimeMin = currTimeMin != null ? (double)currTimeMin : 0;
tSpan = TimeSpan.FromMinutes(cTimeMin);
if (tSpan.TotalHours < 1)
{
answ = $"{tSpan:mm}:{tSpan:ss}";
}
else
{
answ = $"{tSpan.TotalHours:N0}h {tSpan:mm}:{tSpan:ss}";
}
}
catch
{ }
return answ;
}
private void setupConf()
{
//baseCss = doAnimate ? "semBlink" : "sem";
}
private bool showComErr(DateTime? lastUpdateN)
{
DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1);
bool answ = false;
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor))
{
answ = true;
}
return answ;
}
#endregion Private Methods
}
}
@@ -0,0 +1,44 @@
@using MP.Core.Conf
@using MP.Core.DTO;
@if (useNewDisplay)
{
<DetailViewMSE CurrRecord="@currRecord" currTagConf="@currTagConf" currTagVal="@currTagVal" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" @rendermode="InteractiveServer"></DetailViewMSE>
}
else
{
<DetailMSE CurrRecord="@currRecord" currTagConf="@currTagConf" currTagVal="@currTagVal" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" cssOverlayOff="@cssOverlayOff" @rendermode="InteractiveServer"></DetailMSE>
}
@code {
[Parameter]
public MappaStatoExplDTO? currRecord { get; set; } = null;
[Parameter]
public List<TagData>? currTagConf { get; set; } = null;
[Parameter]
public Dictionary<string, string> currTagVal { get; set; } = new Dictionary<string, string>();
[Parameter]
public bool doAnimate { get; set; } = true;
[Parameter]
public bool doBlink { get; set; } = false;
[Parameter]
public int keepAliveMin { get; set; } = 5;
[Parameter]
public int maxChar4Scroll { get; set; } = 20;
[Parameter]
public string showArt { get; set; } = "";
[Parameter]
public bool useNewDisplay { get; set; } = true;
[Parameter]
public string cssOverlayOff { get; set; } = "";
}
+154
View File
@@ -0,0 +1,154 @@
@if (CurrRecord == null || !dataLoaded)
{
<LoadingDataSmall></LoadingDataSmall>
}
else
{
<div class="card mb-1 border border-dark rounded rounded-3 shadow bg-dark @brightCss">
<div class="card-body @cssStatus(CurrRecord.Semaforo, doAnimate) bg-gradient text-white p-1">
<div class="bg-dark text-white opacity-80 px-1 rounded shadow small lh-sm py-0 my-0">
<div class="card-title text-uppercase text-center py-0 my-0 text-truncate" style="font-size: @titleMult;">
<span class="py-0 my-0 @textBlinkBright">@CurrRecord.Nome</span>
</div>
<div class="bg-dark text-white opacity-100 bg-gradient px-1 rounded shadow small lh-sm py-0">
@if (hasRow(1))
{
<div class="card-text d-flex justify-content-between small lh-sm">
@foreach (var item in rowValues(1))
{
<div class="px-0 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="card-text d-flex justify-content-between small lh-sm">
<div class="px-1">
ART:
</div>
<div class="px-1">
@if (showArt == "CodArticolo")
{
<span>@CurrRecord.CodArticolo</span>
}
else
{
if (string.IsNullOrEmpty(CurrRecord.Disegno))
{
<span>[@CurrRecord.CodArticolo]</span>
}
else
{
<span>@CurrRecord.Disegno</span>
}
}
</div>
</div>
}
@if (hasRow(2))
{
<div class="d-flex ui-subtitle justify-content-between py-0 px-1">
@foreach (var item in rowValues(2))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="card-text d-flex justify-content-between small lh-sm">
<div class="px-1">
PODL:
</div>
<div class="px-1">
@(CurrRecord.IdxPOdl > 0 ? $"{CurrRecord.IdxPOdl:000000}" : "-")
</div>
</div>
<div class="card-text d-flex justify-content-between small lh-sm">
<div class="px-1">
ODL:
</div>
<div class="px-1">
@(CurrRecord.IdxOdl > 0 ? $"{CurrRecord.IdxOdl:000000}" : "-")
</div>
</div>
}
@if (showTC)
{
@if (hasRow(3))
{
<div class="d-flex justify-content-between small lh-sm">
@foreach (var item in rowValues(4))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex justify-content-between small lh-sm">
<div class="px-1 pe-0">TC. Act</div>
<div class="px-1 ps-0">@getMinSec(@CurrRecord.TCLavRT) <small>[@getMinSec(@CurrRecord.TCAssegnato)]</small></div>
</div>
}
}
</div>
</div>
<div class="card-text text-light bg-dark bg-gradient rounded py-1 shadow mt-1 mb-0">
@if (hasRow(4))
{
<div class="d-flex justify-content-between py-0 mt-1 px-1">
@foreach (var item in rowValues(3))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class=" d-flex justify-content-between text-warning small w-100">
<div class="px-1 text-uppercase d-inline-block @textCss(@CurrRecord.DescrizioneStato) @textBlinkBright">
<span>@CurrRecord.DescrizioneStato</span>
</div>
<div class="px-1">@getMinSec(getDecimal(@CurrRecord.Durata))</div>
</div>
}
@if (hasRow(5))
{
<div class="d-flex justify-content-between py-0 px-1">
@foreach (var item in rowValues(5))
{
<div class="px-1 @item.TagCss">@item.TagName: <b>@currVal(item.TagLocation)</b></div>
}
</div>
}
else
{
<div class="d-flex justify-content-around fs-3">
<div class="px-1">
<span class="text-light">@CurrRecord.PezziProd</span> / <span class="text-light">@CurrRecord.NumPezzi</span>
</div>
</div>
}
</div>
</div>
<div class="card-footer px-1 pb-1 pt-0 small @cssStatus(CurrRecord.Semaforo, false)" style="font-size: 0.7rem;">
<div class="d-flex text-white justify-content-between @cssComStatus(CurrRecord.Semaforo, CurrRecord.LastUpdate)">
<div class="px-1 @textC101(CurrRecord.LastUpdate)">
@if (showComErr(CurrRecord.LastUpdate))
{
<b>C.101</b>
}
else
{
<span>@(OperatingSystem.IsBrowser() ? "Wasm" : "Online")</span>
}
</div>
<div class="px-1 text-end text-light text-truncate">
@($"{CurrRecord.LastUpdate:yyyy.MM.dd HH:mm:ss}")
</div>
</div>
</div>
</div>
}
@@ -0,0 +1,303 @@
using Microsoft.AspNetCore.Components;
using MP.Core.DTO;
using MP.Core.Conf;
namespace MP.MON.Components.Compo
{
public partial class DetailViewMSE : ComponentBase
{
#region Public Properties
[Parameter]
public MappaStatoExplDTO? CurrRecord { get; set; } = null;
[Parameter]
public List<TagData>? currTagConf { get; set; } = null;
[Parameter]
public Dictionary<string, string> currTagVal { get; set; } = new Dictionary<string, string>();
[Parameter]
public bool doAnimate { get; set; } = true;
[Parameter]
public bool doBlink { get; set; } = false;
[Parameter]
public int keepAliveMin { get; set; } = 5;
[Parameter]
public int maxChar4Scroll { get; set; } = 20;
[Parameter]
public string showArt { get; set; } = "";
[Parameter]
public bool scrollText { get; set; } = false;
[Parameter]
public string brightCss { get; set; } = "";
[Parameter]
public string titleMult { get; set; } = "";
[Parameter]
public bool showTC { get; set; } = false;
#if false
protected override void OnParametersSet()
{
base.OnParametersSet();
Console.WriteLine($"{DateTime.Now} | {CurrRecord.IdxMacchina} params received!");
}
#endif
#endregion Public Properties
#region Protected Fields
protected int kaFactor = 60 / 2;
#endregion Protected Fields
#region Protected Properties
protected bool dataLoaded { get; set; } = true;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// restituisce il valore data la tagLocation
/// </summary>
/// <param name="tagLocation"></param>
/// <returns></returns>
protected string currVal(string tagLocation)
{
string answ = "";
if (currTagVal.ContainsKey(tagLocation))
{
answ = currTagVal[tagLocation];
}
return answ;
}
/// <summary>
/// Verifica se ci sia un override per la riga indicata
/// </summary>
/// <param name="numRow"></param>
/// <returns></returns>
protected bool hasRow(int numRow)
{
bool answ = false;
if (currTagConf != null)
{
if (currTagConf.Count > 0)
{
var currVals = rowValues(numRow);
answ = currVals.Count > 0;
}
}
return answ;
}
/// <summary>
/// Restituisce (se presenti) valori di override per la riga indicata
/// </summary>
/// <param name="numRow"></param>
/// <returns></returns>
protected List<TagData> rowValues(int numRow)
{
List<TagData>? rowVals = null;
if (currTagConf != null)
{
if (currTagConf.Count > 0)
{
//cerco solo la riga corrente...
rowVals = currTagConf.Where(x => x.RowNum == numRow).ToList();
}
}
if (rowVals == null)
{
rowVals = new List<TagData>();
}
return rowVals;
}
/// <summary>
/// CSS class x testo (se descr lunga scorre...)
/// </summary>
protected string textCss(string currText)
{
string answ = "text-truncate";
if (currText.Length > maxChar4Scroll)
{
answ = scrollText ? "scroll-left" : "text-reduced";
// calcolo delta... a-b-c con 5-10-oltre
int delta = currText.Length - maxChar4Scroll;
if (delta < 5)
{
answ += "-a";
}
else if (delta < 10)
{
answ += "-b";
}
else
{
answ += "-c";
}
}
return answ;
}
#endregion Protected Methods
#region Private Methods
private string cssComStatus(string semaforo, DateTime? lastUpdateN)
{
DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1);
string answ = "bg-dark opacity-75"; cssStatus(semaforo, false);
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor))
{
answ = $"bg-danger";
// blink se secondo pari...
#if false
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
answ += " opacity-100";
}
#endif
}
return answ;
}
private string cssStatus(string codSemaforo, bool animate)
{
string answ = "";
// se vuoto --> mostra nero!
if (string.IsNullOrEmpty(codSemaforo))
{
codSemaforo = "sNe";
}
string codColore = codSemaforo.Substring(1, 2);
switch (codSemaforo)
{
case "sVe":
answ = "bg-success";
animate = false;
break;
case "sGi":
answ = "bg-warning";
break;
case "sGr":
answ = "bg-dark opacity-50";
animate = false;
break;
case "sRo":
answ = "bg-danger";
break;
case "sBl":
answ = "bg-primary";
break;
case "sNe":
answ = "bg-dark";
break;
default:
break;
}
if (animate)
{
if (doBlink)
{
answ += " opacity-50";
}
else
{
//answ += " bright100";
textBlinkBright = brightCss;
}
}
return answ;
}
/// <summary>
/// Valore brightness solo x elementi testuali durante lampeggio
/// </summary>
protected string textBlinkBright = "bright100";
private decimal getDecimal(object? rawData)
{
decimal answ = 0;
if (rawData != null)
{
decimal.TryParse($"{rawData}", out answ);
}
return answ;
}
private string getMinSec(decimal? currTimeMin)
{
string answ = "nd";
TimeSpan tSpan = new TimeSpan(0);
try
{
double cTimeMin = currTimeMin != null ? (double)currTimeMin : 0;
tSpan = TimeSpan.FromMinutes(cTimeMin);
if (tSpan.TotalHours < 1)
{
answ = $"{tSpan:mm}:{tSpan:ss}";
}
else
{
answ = $"{tSpan.TotalHours:00}:{tSpan:mm}:{tSpan:ss}";
}
}
catch
{ }
return answ;
}
private bool showComErr(DateTime? lastUpdateN)
{
DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1);
bool answ = false;
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor))
{
answ = true;
}
return answ;
}
private string textC101(DateTime? lastUpdateN)
{
DateTime lastUpdate = lastUpdateN.HasValue ? (DateTime)lastUpdateN : DateTime.Now.AddHours(-1);
string answ = "text-light";
if (DateTime.Now.Subtract(lastUpdate).TotalSeconds > (keepAliveMin * kaFactor))
{
// blink se secondo pari...
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 1)
{
answ = $"text-danger";
}
}
return answ;
}
#endregion Private Methods
}
}
+10
View File
@@ -0,0 +1,10 @@
<div class="row p-5 m-5 alert alert-primary">
<div class="col-6 text-center mt-4 py-3 bg-light">
<h1>MAPO MON</h1>
EgalWare MES suite <img class="logoImg img-fluid" src="images/logoCliente.png" />
</div>
<div class="col-6 text-center mt-4 py-3 bg-light">
<h3>loading data | <b>@(OperatingSystem.IsBrowser() ? "WASM" : "Server")</b> mode</h3>
<i class="fas fa-spinner fa-spin fa-4x"></i>
</div>
</div>
@@ -0,0 +1,6 @@
<div class="row p-2 m-2">
<div class="col-12 text-center mt-2 py-2 alert alert-primary">
<b>loading data</b>
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
+4 -4
View File
@@ -12,7 +12,7 @@
{
<div class="row statusMap mx-1 my-1">
<div class="col-12">
<LoadingData @rendermode="InteractiveServer"></LoadingData>
<LoadingData ></LoadingData>
</div>
</div>
}
@@ -40,14 +40,14 @@ else
if (currMse != null)
{
<div class="col p-0">
@* <DetailMapSelector CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" cssOverlayOff="@cssOverlayOff" useNewDisplay="@newDisplay" @rendermode="InteractiveServer"></DetailMapSelector> *@
@* <DetailMapSelector CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" cssOverlayOff="@cssOverlayOff" useNewDisplay="@newDisplay" ></DetailMapSelector> *@
@if (newDisplay)
{
<DetailViewMSE CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" scrollText="@scrollText" brightCss="@brightCss" titleMult="@titleMult" showTC="@showTC" @rendermode="InteractiveServer"></DetailViewMSE>
<DetailViewMSE CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" scrollText="@scrollText" brightCss="@brightCss" titleMult="@titleMult" showTC="@showTC" ></DetailViewMSE>
}
else
{
<DetailMSE CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" cssOverlayOff="@cssOverlayOff" @rendermode="InteractiveServer"></DetailMSE>
<DetailMSE CurrRecord="@currMse" currTagConf="@getIobTag(currMse.IdxMacchina)" currTagVal="@getTagVal(currMse.IdxMacchina)" doAnimate="@doAnimate" keepAliveMin="@keepAliveMin" showArt="@showArt" doBlink="@doBlink" maxChar4Scroll="@maxChar4Scroll" cssOverlayOff="@cssOverlayOff" ></DetailMSE>
}
</div>
}
+1 -1
View File
@@ -1,4 +1,4 @@
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }">
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
+1 -2
View File
@@ -16,7 +16,6 @@
@using MP.Data.DTO
@using MP.Data.Services
@using MP.MON
@using MP.MON.Client
@using MP.MON.Client.Components
@using MP.MON.Components
@using MP.MON.Components.Compo
@using MP.MON.Components.Pages
+4 -2
View File
@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.MON</RootNamespace>
<AssemblyName>$(AssemblyName.Replace(' ', '_'))</AssemblyName>
<Version>6.16.2503.1809</Version>
<Version>6.16.2503.1819</Version>
</PropertyGroup>
<ItemGroup>
@@ -34,8 +34,10 @@
<ItemGroup>
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
<ProjectReference Include="..\MP.MON.Client\MP.MON.Client.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="8.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Common" Version="8.0.14" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.14" />
</ItemGroup>
+5 -8
View File
@@ -1,8 +1,5 @@
using MP.MON.Client.Components;
using MP.Data.Services;
using MP.MON.Components;
using MP.MON.Components.Layout;
using MP.MON.Components.Pages;
using NLog;
using NLog.Web;
using StackExchange.Redis;
@@ -11,8 +8,8 @@ var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
.AddInteractiveServerComponents();
//.AddInteractiveWebAssemblyComponents();
var logger = LogManager.Setup()
@@ -60,9 +57,9 @@ app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MP.MON.Client._Imports).Assembly);
.AddInteractiveServerRenderMode();
//.AddInteractiveWebAssemblyRenderMode()
//.AddAdditionalAssemblies(typeof(MP.MON.Client._Imports).Assembly);
logger.Info("App: Run stage");
app.Run();
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2503.1809</h4>
<h4>Versione: 6.16.2503.1819</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2503.1809
6.16.2503.1819
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2503.1809</version>
<version>6.16.2503.1819</version>
<url>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+6
View File
@@ -0,0 +1,6 @@
window.getWindowDimensions = function () {
return {
width: window.innerWidth,
height: window.innerHeight
};
};