Merge branch 'Release/FixLandLicenseMsg'

This commit is contained in:
Samuele Locatelli
2023-10-16 11:13:54 +02:00
695 changed files with 236111 additions and 324 deletions
+30
View File
@@ -187,6 +187,19 @@ IOC:build:
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
TAB3:build:
stage: build
tags:
- win
variables:
APP_NAME: MP-TAB-SERV
SOL_NAME: MP-TAB3
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# ----- Start DEPLOY develop (IIS01) -----
LAND:IIS01:deploy:
@@ -325,6 +338,23 @@ IOC:IIS01:deploy:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PASSWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
TAB3:IIS01:deploy:
stage: deploy
tags:
- win
variables:
APP_NAME: MP-TAB-SERV
SOL_NAME: MP-TAB3
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
only:
- develop
needs: ["TAB3:build"]
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PASSWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
# ----- Start DEPLOY master (IIS02/IIS04) -----
LAND:IIS02:deploy:
stage: deploy
+12
View File
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
+67
View File
@@ -0,0 +1,67 @@
<EgwCoreLib.Razor.PeriodoSel CurrPeriodo="CurrPeriodo" E_PeriodoSel="SetPeriodo"></EgwCoreLib.Razor.PeriodoSel>
<ShowProcessing Message="Invio in corso" IsProcessing="@isSending"></ShowProcessing>
@if (isProcessing)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<table class="table table-dark table-sm table-striped">
<thead>
<tr class="text-start1">
<th>
Elenco Allarmi
</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListPaged)
{
<tr>
<td>
<div class="row">
<div class="col-6 col-md-8 small">
<div>
Mem: <b>@($"{item.MemAddress}.{@item.MemIndex}")</b>
</div>
<div class="text-danger">
<b>@item.ValDecoded</b>
</div>
</div>
<div class="col-6 col-md-4 text-end small">
<div class="d-flex flex-row-reverse">
<div class="px-1">
<div class="text-truncate">
@($"{item.DtRif:ddd dd.MM.yy HH:mm:ss}") <i class="fa fa-clock-o" aria-hidden="true"></i>
</div>
<div class="text-truncate">
@($"{item.Duration:N2} min") <i class="fa fa-hourglass-end" aria-hidden="true"></i>
</div>
</div>
<div class="px-1">
@if (!string.IsNullOrEmpty(item.UserAck))
{
<b>@item.UserAck</b> <i class="fa fa-user" aria-hidden="true"></i>
}
</div>
<div class="px-1">
@if (item.ReqNotify != 0)
{
<button class="btn btn-sm btn-primary py-0" @onclick="() => SendNotify(item)">Invia&nbsp;<i class="fa fa-envelope" aria-hidden="true"></i></button>
}
@if (item.ReqAck != 0)
{
<button class="btn btn-sm btn-warning py-0" @onclick="() => DoAck(item)">Set <i class="fa fa-exclamation-triangle" aria-hidden="true"></i></button>
}
</div>
</div>
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
<EgwCoreLib.Razor.DataPager currPage="@PageNum" PageSize="@NumRecPage" totalCount="@TotalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
}
+211
View File
@@ -0,0 +1,211 @@
using global::Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
using System.Text;
using static EgwCoreLib.Utils.DtUtils;
namespace MP_TAB_SERV.Components
{
public partial class AlarmsMan
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Public Methods
/// <summary>
/// Aggiorno valori produzione alla data richiesta...
/// </summary>
/// <param name="newDate"></param>
public async Task doUpdate()
{
isProcessing = true;
await Task.Delay(1);
if (!string.IsNullOrEmpty(IdxMaccSel))
{
ListComplete = await TabDServ.AlarmLogListFilt(IdxMaccSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, false);
TotalCount = ListComplete.Count;
// esegue paginazione
UpdateTable();
}
isProcessing = false;
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Fields
protected bool isProcessing = false;
protected bool isSending = false;
protected int NumRecPage = 10;
protected int PageNum = 1;
protected int TotalCount = 0;
#endregion Protected Fields
#region Protected Properties
protected List<string> AlarmsDest { get; set; } = new List<string>();
[Inject]
protected IConfiguration config { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
protected List<AlarmLogModel> ListComplete { get; set; } = new List<AlarmLogModel>();
protected List<AlarmLogModel> ListPaged { get; set; } = new List<AlarmLogModel>();
[Inject]
protected MailService MailServ { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoAck(AlarmLogModel currAlarm)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler registrare ACK dell'allarme?{Environment.NewLine}[{currAlarm.ValDecoded}]"))
return;
isSending = true;
await Task.Delay(1);
TabDServ.AlarmLogSetAck(currAlarm.AlarmLogId, DateTime.Now, $"{MServ.MatrOpr} - {MServ.CognomeNome}");
isSending = false;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
protected override async Task OnInitializedAsync()
{
await Task.Delay(1);
if (RecMSE != null)
{
IdxMaccSel = RecMSE.IdxMacchina;
CurrPeriodo = new Periodo(PeriodSet.ThisWeek);
await doUpdate();
}
var rawDest = config.GetValue<string>("AlarmDest");
if (!string.IsNullOrEmpty(rawDest))
{
AlarmsDest = rawDest.Split(",").ToList();
}
else
{
AlarmsDest = new List<string>() { "samuele@steamware.net" };
}
}
protected void SaveNumRec(int newNum)
{
NumRecPage = newNum;
UpdateTable();
}
protected void SavePage(int newNum)
{
PageNum = newNum;
UpdateTable();
}
protected async Task SendNotify(AlarmLogModel currAlarm)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler inviare notifica allarme?{Environment.NewLine}[{currAlarm.ValDecoded}]"))
return;
isSending = true;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
//List<string> dest = new List<string>();
//dest.Add("samuele@steamware.net");
string oggetto = $"Notifica allarme impianto {currAlarm.MachineId}";
StringBuilder sb = new StringBuilder();
sb.AppendLine("Attenzione: allarme presente per un periodo superiore alla soglia di controllo.");
sb.AppendLine();
sb.AppendLine($"<b>{currAlarm.ValDecoded}</b>");
sb.AppendLine();
sb.AppendLine($"Info Area: {currAlarm.MemAddress}.{currAlarm.MemIndex} | Status {currAlarm.StatusVal}");
sb.AppendLine();
string corpo = sb.ToString().Replace($"{Environment.NewLine}", "<br/>");
MailKitMailData mData = new MailKitMailData()
{
To = AlarmsDest,
Subject = oggetto,
Body = corpo
};
bool done = await MailServ.SendAsync(mData);
if (done)
{
// salvo invio Notifica allarme
TabDServ.AlarmLogSetNotify(currAlarm.AlarmLogId, DateTime.Now);
Log.Info($"Notifica allarme {currAlarm.AlarmLogId} inviato a {string.Join(",", AlarmsDest)}");
}
else
{
Log.Error($"Errore in invio email allarmi attivi per {currAlarm.AlarmLogId} | tentato invio a {string.Join(",", AlarmsDest)}");
}
isSending = false;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
protected async Task SetMacc(string selIdxMacc)
{
isProcessing = true;
await Task.Delay(10);
IdxMaccSel = selIdxMacc;
await doUpdate();
isProcessing = false;
await Task.Delay(10);
}
protected async Task SetPeriodo(Periodo newPeriodo)
{
CurrPeriodo = newPeriodo;
await doUpdate();
}
protected void UpdateTable()
{
// esegue paginazione
if (TotalCount > NumRecPage)
{
ListPaged = ListComplete.Skip((PageNum - 1) * NumRecPage).Take(NumRecPage).ToList();
}
else
{
ListPaged = ListComplete;
}
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private Periodo CurrPeriodo { get; set; } = new Periodo();
private string IdxMaccSel { get; set; } = "";
#endregion Private Properties
}
}
+62
View File
@@ -0,0 +1,62 @@
<div class="card shadow" style="width: 22rem">
<div class="card-header @CardCss">
<h3 class="card-title">
@if (DoPlaceholder)
{
<div class="placeholder-glow">
<span class="placeholder col-6"></span>
</div>
}
else
{
@Title
}
</h3>
</div>
<div class="card-body">
@if (DoPlaceholder)
{
<div class="placeholder-glow">
<span class="placeholder col-7"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-7"></span>
</div>
}
else
{
<p class="card-text">@ChildContent</p>
}
</div>
<div class="card-footer">
@if (DoPlaceholder)
{
<div class="placeholder-glow">
<button class="btn btn-sm btn-dark disabled placeholder col-2"></button>
</div>
}
else
{
<button class="btn btn-sm btn-dark" @onclick="OnYes">Yes!</button>
}
</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public string? Title { get; set; }
[Parameter]
public string CardCss { get; set; } = "";
[Parameter]
public bool DoPlaceholder { get; set; } = false;
private void OnYes()
{
Console.WriteLine($"{Title} | 'Yes' button selected.");
}
}
+9
View File
@@ -0,0 +1,9 @@
<div class="row bg-dark text-light px-2">
<div class="col-6 text-left">
<b>MP-TAB2 @(DateTime.Today.Year)</b> | <span class="small">v.@version</span>
</div>
<div class="col-6 text-end">
<span class="small">@($"{DateTime.Now:HH:mm:ss}")</span> | <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>
+59
View File
@@ -0,0 +1,59 @@
using NLog;
namespace MP_TAB_SERV.Components
{
public partial class CmpFooter : IDisposable
{
#region Public Methods
public void Dispose()
{
if (aTimer != null)
{
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);
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
}
public void StartTimer()
{
int tOutPeriod = 5000;
//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 Methods
protected override void OnInitialized()
{
var rawVers = typeof(Program).Assembly.GetName().Version; ;
version = rawVers != null ? rawVers : new Version("0.0.0.0");
}
#endregion Protected Methods
#region Private Fields
private System.Timers.Timer aTimer = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
private Version version = null!;
#endregion Private Fields
}
}
@@ -0,0 +1,39 @@
<h1> RIFARE X COMMENTI!!!</h1>
<div class="row mt-2">
@if (ShowBtn)
{
<div class="col-12">
<button class="btn btn-lg bg-info w-100" @onclick="ToggleCtrl">
<i class="fa-solid fa-star"></i>
&nbsp;
<span class="fs-4 fw-bold">@Title</span>
</button>
</div>
}
else
{
<div class="col-6">
<div class="input-group">
<span class="input-group-text" id="basic-addon1">Data Ora</span>
<input type="datetime-local" class="form-control" id="floatDate" @bind="@DateSel">
</div>
</div>
<div class="col-6">
<button class="btn btn-warning w-100 align-middle" @onclick="doCancel"><i class="fa-solid fa-ban"></i> Annulla</button>
</div>
<div class="col-12 my-1">
<div class="form-floating">
<textarea type="text" class="form-control" id="floatingComm" style="height: 6rem;" @bind="@UserComment"></textarea>
<label for="floatingComm">Commento</label>
</div>
</div>
<div class="col-12">
@if (CanSave)
{
<button class="btn btn-success w-100" @onclick="doSave"><i class="fa-solid fa-plus"></i> Salva</button>
}
</div>
}
</div>
@@ -0,0 +1,164 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class CommentEditor
{
#region Public Properties
[Parameter]
public bool CanSave { get; set; } = false;
[Parameter]
public EventCallback<string> E_CommRec { get; set; }
[Parameter]
public EventCallback<DateTime> E_DateSel { get; set; }
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
[Parameter]
public string Title { get; set; } = "NA";
[Parameter]
public EventListModel? CurrComm
{
//get;
set
{
if (value != null)
{
DateSel = value.InizioStato ?? DateTime.Now;
UserComment = value.Value;
}
}
}
#endregion Public Properties
#region Protected Properties
protected DateTime DateSel
{
get => dateSel.Round(TimeSpan.FromSeconds(1));
set
{
if (dateSel != value)
{
// arrotondo al secondo...
dateSel = value.AddMilliseconds(-value.Millisecond);
E_DateSel.InvokeAsync(value).ConfigureAwait(false);
}
}
}
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected SharedMemService SMServ { get; set; } = null!;
[Inject]
protected TabDataService TabServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void doCancel()
{
DoReset();
ToggleCtrl();
}
protected async Task doSave()
{
// registro evento
EventListModel newRec = new EventListModel()
{
IdxMacchina = IdxMacc,
InizioStato = DateSel,
IdxTipo = idxTipoCommento,
CodArticolo = CodArt,
Value = UserComment,
MatrOpr = MatrOpr,
pallet = "-"
};
// elimino vecchio se c'è...
await TabServ.EvListDelete(IdxMacc, DateSel, idxTipoCommento);
// inserisco
await TabServ.EvListInsert(newRec, MP.Data.Objects.Enums.tipoInputEvento.barcode);
// reset
DoReset();
ToggleCtrl();
}
protected override void OnInitialized()
{
idxTipoCommento = SMServ.GetConfInt("idxTipoCommento");
}
protected void ToggleCtrl()
{
ShowBtn = !ShowBtn;
}
#endregion Protected Methods
#region Private Fields
private int idxTipoCommento = 0;
#endregion Private Fields
#region Private Properties
private string CodArt
{
get => RecMSE != null ? RecMSE.CodArticolo : "";
}
private DateTime dateSel { get; set; } = DateTime.Now;
private string IdxMacc
{
get => RecMSE != null ? RecMSE.IdxMacchina : "";
}
private int MatrOpr
{
get => MServ.MatrOpr;
}
private bool ShowBtn { get; set; } = true;
private string userComment { get; set; } = "";
private string UserComment
{
get => userComment.Trim();
set
{
if (userComment != value)
{
userComment = value;
E_CommRec.InvokeAsync(value).ConfigureAwait(false);
}
}
}
#endregion Private Properties
#region Private Methods
private void DoReset()
{
UserComment = "";
DateSel = DateTime.Now;
}
#endregion Private Methods
}
}
+103
View File
@@ -0,0 +1,103 @@
<EgwCoreLib.Razor.PeriodoSel CurrPeriodo="CurrPeriodo" E_PeriodoSel="SetPeriodo"></EgwCoreLib.Razor.PeriodoSel>
<ShowProcessing Message="Caricamento" IsProcessing="@isProcessing"></ShowProcessing>
<div class="card">
<div class="card-header bg-dark">
<button class="btn btn-primary btn-lg text-light w-100" @onclick="ToggleBtn">
<i class="fa fa-wrench"></i> @ConfTitle
</button>
@if (showInsert)
{
@if (showNote)
{
<div class="row">
<div class="col-12">
<div class="">
@* </div>
<div class="form-floating"> *@
<label class="form-label text-light">Note controllo NON superato (opzionali)</label>
<textarea class="form-control" @bind="@noteKo" style="height: 6rem;"></textarea>
</div>
</div>
<div class="col-12">
<button class="btn btn-danger btn-lg w-100" @onclick="SaveKo">Conferma controllo KO</button>
</div>
</div>
}
else
{
<div class="row my-2">
<div class="col-6">
<button class="btn btn-success w-100" @onclick="SaveOk">OK</button>
</div>
<div class="col-6">
<button class="btn btn-danger w-100" @onclick="ShowKo">KO</button>
</div>
</div>
}
}
</div>
<div class="card-body bg-secondary p-1">
<div class="row">
<div class="col-12">
<table class="table table-dark table-sm table-striped">
<thead>
<tr class="text-start1">
<th>
Elenco Controlli
</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListPaged)
{
<tr>
<td>
<div class="row">
<div class="col-5 small">
<div>
Art: <b>@item.CodArticolo</b>
</div>
<div>
ODL: <b>@($"ODL{item.IdxOdl:000000000}")</b>
</div>
</div>
<div class="col-2 px-0 text-center">
@if (item.EsitoOk)
{
<i runat="server" class="fa fa-check-circle fs-1 text-success" aria-hidden="true"></i>
}
else
{
<i runat="server" class="fa fa-ban fs-1 text-danger" aria-hidden="true"></i>
}
</div>
<div class="col-5 text-end small">
<div class="text-truncate">
@($"{item.DataOra:ddd dd.MM.yy HH:mm:ss}") <i class="fa fa-clock-o" aria-hidden="true"></i>
</div>
<div class="text-truncate">
<b>@item.Operatore</b>
<i class="fa fa-user" aria-hidden="true"></i>
</div>
</div>
<div class="col-12 small">
@if (!string.IsNullOrEmpty(item.Note))
{
<div class="text-warning">@item.Note</div>
}
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<div class="cad-footer">
<EgwCoreLib.Razor.DataPager currPage="@PageNum" PageSize="@NumRecPage" totalCount="@TotalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
</div>
</div>
+176
View File
@@ -0,0 +1,176 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
using static EgwCoreLib.Utils.DtUtils;
namespace MP_TAB_SERV.Components
{
public partial class ControlsMan
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Public Methods
/// <summary>
/// Aggiorno valori produzione alla data richiesta...
/// </summary>
/// <param name="newDate"></param>
public async Task doUpdate()
{
isProcessing = true;
await Task.Delay(1);
if (!string.IsNullOrEmpty(IdxMaccSel))
{
ListComplete = await TabDServ.RegControlliFilt(IdxMaccSel, idxOdl, CurrPeriodo.Inizio, CurrPeriodo.Fine, false);
TotalCount = ListComplete.Count;
// esegue paginazione
UpdateTable();
}
isProcessing = false;
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Fields
protected int idxOdl = 0;
protected bool isProcessing = false;
protected string noteKo = "";
protected int NumRecPage = 10;
protected int PageNum = 1;
protected bool showNote = false;
protected int TotalCount = 0;
#endregion Protected Fields
#region Protected Properties
protected string ConfTitle
{
get => showInsert ? "Nascondi Controllo" : "Registra Controllo";
}
protected List<RegistroControlliModel> ListComplete { get; set; } = new List<RegistroControlliModel>();
protected List<RegistroControlliModel> ListPaged { get; set; } = new List<RegistroControlliModel>();
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await Task.Delay(1);
if (RecMSE != null)
{
IdxMaccSel = RecMSE.IdxMacchina;
CurrPeriodo = new Periodo(PeriodSet.ThisWeek);
await doUpdate();
}
}
protected async Task SaveKo()
{
isProcessing = true;
await TabDServ.RegControlliInsert(IdxMaccSel, MServ.MatrOpr, false, noteKo, DateTime.Now);
showInsert = false;
showNote = false;
await doUpdate();
isProcessing = false;
}
protected void SaveNumRec(int newNum)
{
NumRecPage = newNum;
UpdateTable();
}
protected async Task SaveOk()
{
isProcessing = true;
await TabDServ.RegControlliInsert(IdxMaccSel, MServ.MatrOpr, true, noteKo, DateTime.Now);
showInsert = false;
showNote = false;
await doUpdate();
isProcessing = false;
}
protected void SavePage(int newNum)
{
PageNum = newNum;
UpdateTable();
}
protected async Task SetMacc(string selIdxMacc)
{
isProcessing = true;
await Task.Delay(10);
IdxMaccSel = selIdxMacc;
await doUpdate();
isProcessing = false;
await Task.Delay(10);
}
protected async Task SetPeriodo(Periodo newPeriodo)
{
CurrPeriodo = newPeriodo;
await doUpdate();
}
protected void ShowKo()
{
showNote = true;
}
protected void ToggleBtn()
{
showInsert = !showInsert;
if (showInsert)
{
noteKo = "";
showNote = false;
}
}
protected void UpdateTable()
{
// esegue paginazione
if (TotalCount > NumRecPage)
{
ListPaged = ListComplete.Skip((PageNum - 1) * NumRecPage).Take(NumRecPage).ToList();
}
else
{
ListPaged = ListComplete;
}
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool showInsert = false;
#endregion Private Fields
#region Private Properties
private Periodo CurrPeriodo { get; set; } = new Periodo();
private string IdxMaccSel { get; set; } = "";
#endregion Private Properties
}
}
+6
View File
@@ -0,0 +1,6 @@
<h3>DeclarList</h3>
@code {
}
+34
View File
@@ -0,0 +1,34 @@
<div class="card">
<div class="card-header text-center">
<div>
<i class="fa-solid fa-microchip" style="font-size: 5rem;"></i>
</div>
<div>
<span>IOB Details</span>
</div>
</div>
<div class="card-body">
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between">
<div>Machine Code: </div>
<div class="fw-bold">@idxMacch</div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div>IOB Type: </div>
<div class="fw-bold"><i class="fa-brands fa-windows"></i> &nbsp; @infosIob.iType</div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div>IOB Name: </div>
<div class="fw-bold">@infosIob.name</div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div>IOB Address: </div>
<div class="fw-bold">@infosIob.IP</div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div>CNC Absolute counter: </div>
<div class="fw-bold">@infosIob.CNC_Counter</div>
</li>
</ul>
</div>
</div>
@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DTO;
using MP.Data.Objects;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class IobInfoMan
{
[Parameter]
public string idxMacch { get; set; } = "";
[Inject]
protected TabDataService TabSrv { get; set; } = null!;
protected IOB_data infosIob { get; set; } = new IOB_data();
protected override async Task OnInitializedAsync()
{
infosIob = await TabSrv.IobInfo(idxMacch);
}
}
}
+30
View File
@@ -0,0 +1,30 @@
@if (currFnq != null)
{
<div class="col-12 col-sm-6 col-lg-4 my-1 p-2">
<div class="card" @onclick="SelectFermo">
<div class="card-body @setSemaforo(currFnq.Semaforo)">
<div class="text-start fw-bold" style="font-size: 1.8rem;">
@currFnq.Stato
</div>
<div class="text-end" style="font-size: 1.5rem;">
@currFnq.CodArticolo
</div>
</div>
<div class="card-footer d-flex justify-content-between bg-dark text-light">
<div>
@($"{currFnq.InizioStato:yyyy/MM/dd HH:mm:ss}")
@*09.10.2023 00:30*@
</div>
<div>
@*7h 30m*@
@(MP.Data.Utils.FormDurata(currFnq.DurataMinuti))
</div>
</div>
</div>
</div>
}
@@ -0,0 +1,65 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using System.Reflection.Metadata;
namespace MP_TAB_SERV.Components
{
public partial class LongStopList
{
#region Public Properties
[Parameter]
public FermiNonQualModel currFnq { get; set; } = new FermiNonQualModel();
#endregion Public Properties
#region Protected Properties
[Inject]
protected MessageService MsgServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Rimanda alla pagina fermate selezionando periodo corretto...
/// </summary>
/// <returns></returns>
protected async Task SelectFermo()
{
await Task.Delay(1);
// salva la data-ora evento richiesto...
await MsgServ.CommentoDtRifSet(currFnq.InizioStato);
NavMan.NavigateTo("prod-stop");
}
#endregion Protected Methods
#region Private Methods
private string setSemaforo(string sem)
{
string answ = "";
if (sem == "sBl")
{
answ = "bg-primary text-warning";
}
else if (sem == "sGr")
{
answ = "bg-secondary text-dark";
}
else if (sem == "sGi")
{
answ = "bg-warning text-dark";
}
return answ;
}
#endregion Private Methods
}
}
+19
View File
@@ -0,0 +1,19 @@
@if (isMulti)
{
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Selezione Impianto</span>
<select class="form-select form-select-sm" @bind="@IdxMaccSel">
@if (ListMacchine == null)
{
<option value="" disabled>No record found</option>
}
else
{
@foreach (var item in ListMacchine)
{
<option value="@item.Key">@item.Value</option>
}
}
</select>
</div>
}
+84
View File
@@ -0,0 +1,84 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using System;
using System.Reflection.Metadata;
namespace MP_TAB_SERV.Components
{
public partial class MachSel
{
#region Public Properties
[Parameter]
public EventCallback<string> E_MachSel { get; set; }
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Protected Properties
protected string IdxMaccSel
{
get => idxMaccSel;
set
{
if (idxMaccSel != value)
{
idxMaccSel = value;
E_MachSel.InvokeAsync(value).ConfigureAwait(false);
}
}
}
private string idxMaccSel { get; set; } = "";
protected Dictionary<string, string>? ListMacchine { get; set; } = null;
[Inject]
protected SharedMemService MServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnParametersSetAsync()
{
// inizilamente riporto machcina corrente da MSE
if (RecMSE != null)
{
// verifico se la macchina sia configurata tra le MSFD...
if (MServ.DictMacchMulti.ContainsKey(RecMSE?.IdxMacchina))
{
isMulti = MServ.DictMacchMulti[RecMSE?.IdxMacchina] == 1;
}
if (isMulti)
{
var listMulti = await TDataService.VMSFDGetAll();
ListMacchine = listMulti.Where(x => x.IdxMacchina.Contains($"{RecMSE?.IdxMacchina}#")).ToDictionary(x => x.IdxMacchina, x => $"{x.IdxMacchina.Replace($"{RecMSE?.IdxMacchina}#", "")}");
if (ListMacchine.Count > 0 && string.IsNullOrEmpty(idxMaccSel))
{
IdxMaccSel = ListMacchine.FirstOrDefault().Key;
//await E_MachSel.InvokeAsync(idxMaccSel);
}
}
}
await Task.Delay(1);
}
[Inject]
protected TabDataService TDataService { get; set; } = null!;
#endregion Protected Methods
#region Private Fields
private bool isMulti = false;
#endregion Private Fields
}
}
+268
View File
@@ -0,0 +1,268 @@
@if (isLoading)
{
<div class="card text-white mapBlock shadow bg-secondary p-0 m-0">
<div class="card-body">
<div class="placeholder-glow">
<span class="placeholder col-7"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-7"></span>
</div>
</div>
</div>
}
else
{
@if (RecMSE == null)
{
<div class="card text-white mapBlock shadow bg-secondary p-0 m-0">
<div class="card-body">
<div class="alert alert-info w-100 fs-3">No data</div>
<div class="placeholder-glow">
<span class="placeholder col-7"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-7"></span>
</div>
</div>
</div>
}
else
{
@if (FullMode)
{
@*<div class="card mapBlock shadow @RecMSE.Semaforo p-0 m-0" @onclick="ShowDetail">
<img src="@ImgUrlMacc(RecMSE.Url)" class="card-img-top" alt="@RecMSE.CodMacchina">
<div class="m-1 bg-black">
<div class="card-img-overlay p-0 d-flex flex-row-reverse align-items-start rCTop">
<div class="labelTopDx px-2 w-100">
<div class="row">
<div class="col-3 text-start">
Art
</div>
<div class="col-9 text-end fw-bold">
@RecMSE.CodArticolo
</div>
</div>
<div class="row small">
<div class="col-6 text-start">
@($"PODL{RecMSE.IdxPOdl:00000000}")
</div>
<div class="col-6 text-end">
@($"ODL{RecMSE.IdxOdl:00000000}")
</div>
</div>
</div>
</div>
<div class="card bg-black text-light p-0 rCBot">
<div class="row justify-content-center mx-0">
<div class="col-12 px-1">
<h4 class="text-start mb-0 fw-bold">
@RecMSE.Nome
</h4>
</div>
<div class="col-12 p-1 @RecMSE.Semaforo">
<div class="d-flex justify-content-between">
<div class="p-0 mr-auto">
<b>@RecMSE.DescrizioneStato</b>
</div>
<div class="p-0">
@(formatDurata(RecMSE.Durata))
</div>
</div>
</div>
<div class="col-12 p-0 text-nowrap" style="font-size: 1.2em; line-height: 1.0em;">
<div class="row px-1 fw-bold" style="font-size:0.85em;">
<div class="col pe-0">
<small class="text-success">Confermati</small>
</div>
<div class="col text-center px-0">
<small class="text-warning">Prodotti</small>
</div>
<div class="col text-end ps-0">
<small class="text-light">Ordinati</small>
</div>
</div>
<div class="row px-1">
<div class="col pe-0 text-success">
@($"{RecMSE.PezziConf:N0}")
</div>
<div class="col text-center text-warning px-0">
@($"{RecMSE.PezziProd:N0}")
</div>
<div class="col text-end ps-0">
@($"{RecMSE.NumPezzi:N0}")
</div>
</div>
<div class="row">
<div class="col m-1">
<ProdAdvDispl CountData="@CurrCount"></ProdAdvDispl>
</div>
</div>
</div>
</div>
</div>
</div>
</div>*@
if (Width > 640)
{
<div class="card shadow" @onclick="ShowDetail" style="border-radius: 15px">
@*<img src="@ImgUrlMacc(RecMSE.Url)" class="card-img-top imgFitToSize" alt="@RecMSE.CodMacchina">*@
<img src="@ImgUrlMacc(RecMSE.Url)" class="card-img-top imgFitToSize" alt="@RecMSE.CodMacchina">
<div class="bg-black">
<div class="card-img-overlay p-0 d-flex flex-row-reverse align-items-start rCTop">
<div class="labelTopDx px-2 w-100">
<div class="text-center fs-2 fw-bold">
@RecMSE.Nome
</div>
</div>
</div>
</div>
<div class="card-body p-1" style="background-color: #212427; border-radius: 0 0 15px 15px">
<div class="@RecMSE.Semaforo p-1" style="border-radius: 15px">
<div class="d-flex justify-content-center fs-5">
<span><b>@RecMSE.DescrizioneStato</b>: &nbsp; @(formatDurata(RecMSE.Durata))</span>
</div>
</div>
<div class="d-flex justify-content-between">
<div class="col-4">
<EgwCoreLib.Razor.CircleGaugeMulti Titolo="@($"{currMaxVal}")" Testo="#pz rich" maxVal="@currMaxVal" ListInner="@innerCircleVals" ListOuter="@outerCircleVals" ShowCircleBtn="true"></EgwCoreLib.Razor.CircleGaugeMulti>
</div>
<div class="col-8" style="line-height: 1.6rem;">
<div class="d-flex justify-content-around">
<div class="text-center text-success ">
<div>
<i class="fa-regular fa-circle-check"></i>&nbsp; @($" {RecMSE.PezziConf:N0}")
</div>
</div>
<div class="text-center text-warning ">
<div>
<i class="fa-solid fa-layer-group"></i>&nbsp; @($" {RecMSE.PezziProd:N0}")
</div>
</div>
</div>
<div class="text-center text-light d-flex justify-content-between">
<div class="col-4"><span>ART:</span></div>
<div class="col-8">@($"{RecMSE.CodArticolo}")</div>
</div>
<div class="text-center text-light d-flex justify-content-between small lh-sm">
<div class="col-4">ODL:</div>
<div class="col-8">@($"ODL{RecMSE.IdxOdl:00000000}")</div>
</div>
<div class="text-center text-light d-flex justify-content-between small lh-sm">
<div class="col-4">PODL:</div>
<div class="col-8">@($"PODL{RecMSE.IdxPOdl:00000000}")</div>
</div>
</div>
</div>
</div>
</div>
}
else
{
<div class="card shadow" @onclick="ShowDetail" style="border-radius: 11px; background: linear-gradient(121deg, rgba(255, 255, 255, 0.20) -0.71%, rgba(255, 255, 255, 0.05) 97.66%); box-shadow: 0px 4px 24px -1px rgba(0, 0, 0, 0.25);">
<div class="card-body p-0">
<div style="border-radius: 11px;" class="@RecMSE.Semaforo p-1 text-center">
<div class="fs-2" style="line-height: 1.8rem;">
<b>@RecMSE.Nome</b>
<br />
<b>@RecMSE.DescrizioneStato</b>: &nbsp; @(formatDurata(RecMSE.Durata))
</div>
</div>
@if (showCard)
{
<div class="d-flex justify-content-between w-100" style="height: 100px; width: 100px;">
<div class="col-6">
<EgwCoreLib.Razor.CircleGaugeMulti Titolo="@($"{currMaxVal}")" Testo="#pz prod" maxVal="@currMaxVal" ListInner="@innerCircleVals" ListOuter="@outerCircleVals" ShowCircleBtn="true"></EgwCoreLib.Razor.CircleGaugeMulti>
</div>
<div style="font-size: 1rem" class="me-3 col-6">
<div class="text-center text-success d-flex justify-content-between">
<div class="col-4"><i class="fa-regular fa-circle-check"></i></div>
<div class="col-8">@($"{RecMSE.PezziConf:N0}")</div>
</div>
<div class="text-center text-warning d-flex justify-content-between">
<div class="col-4"><i class="fa-solid fa-layer-group"></i></div>
<div class="col-8">@($"{RecMSE.PezziProd:N0}")</div>
</div>
<div class="text-center text-light d-flex justify-content-between">
<div class="col-4"><span>ART.</span></div>
<div class="col-8">@RecMSE.CodArticolo</div>
</div>
<div class="text-center text-light d-flex justify-content-between small">
<div class="col-4">ORD.</div>
<div class="col-8">@($"ODL{RecMSE.IdxOdl:00000000}")</div>
</div>
</div>
</div>
}
</div>
</div>
}
}
else
{
<div class="d-flex justify-content-between">
<div class="card mapBlock shadow @RecMSE.Semaforo p-0 m-0 col-10">
<div class="m-1 bg-black">
<div class="card bg-black text-light p-0 rCBot">
<div class="row justify-content-center mx-0">
<div class="col-12 px-1">
<h4 class="text-start mb-0 fw-bold">
@RecMSE.Nome
</h4>
</div>
<div class="col-12 p-1 @RecMSE.Semaforo">
<div class="d-flex justify-content-between">
<div class="p-0 mr-auto">
<b>@RecMSE.DescrizioneStato</b>
</div>
<div class="p-0">
@(formatDurata(RecMSE.Durata))
</div>
</div>
</div>
<div class="col-12 p-0 text-nowrap" style="font-size: 1.2em; line-height: 1.0em;">
<div class="row px-1 fw-bold" style="font-size:0.85em;">
<div class="col pe-0">
<small class="text-success">Confermati</small>
</div>
<div class="col text-center px-0">
<small class="text-warning">Prodotti</small>
</div>
<div class="col text-end ps-0">
<small class="text-light">Ordinati</small>
</div>
</div>
<div class="row px-1">
<div class="col pe-0 text-success">
@($"{RecMSE.PezziConf:N0}")
</div>
<div class="col text-center text-warning px-0">
@($"{RecMSE.PezziProd:N0}")
</div>
<div class="col text-end ps-0">
@($"{RecMSE.NumPezzi:N0}")
</div>
</div>
<div class="row">
<div class="col m-1">
<ProdAdvDispl CountData="@CurrCount"></ProdAdvDispl>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-2 d-flex flex-wrap align-items-center justify-content-center p-1">
<button class="w-100 h-100 btn btn-secondary">
<i class="fa-solid fa-file-pdf" style="font-size: 4vw"></i>
</button>
</div>
</div>
}
}
}
@@ -0,0 +1,259 @@
using EgwCoreLib.Razor;
using global::Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog.Fluent;
using static MP_TAB_SERV.Pages.User;
namespace MP_TAB_SERV.Components
{
public partial class MachineBlock
{
#region Public Properties
[Parameter]
public bool FullMode { get; set; } = true;
[Parameter]
public int keepAliveMin { get; set; } = 5;
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
[Parameter]
public bool showCard { get; set; }
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Public Properties
protected List<CircleGaugeMulti.CircSegm> innerCircleVals = new List<CircleGaugeMulti.CircSegm>();
protected List<CircleGaugeMulti.CircSegm> outerCircleVals = new List<CircleGaugeMulti.CircSegm>();
protected int currVal1 = 1000;
protected int currMaxVal = 1000;
protected int maxVal = 1000;
public int Height { get; set; } = 0;
public int Width { get; set; } = 0;
public string currIpv4 { get; set; } = "";
public class WindowDimension
{
public int Width { get; set; }
public int Height { get; set; }
}
protected async Task getWDim()
{
var dimension = await JSRuntime.InvokeAsync<WindowDimension>("getWindowDimensions");
Height = dimension.Height;
Width = dimension.Width;
}
protected async Task setGaugeVals()
{
await Task.Delay(1);
if (RecMSE != null)
{
innerCircleVals.Clear();
outerCircleVals.Clear();
currMaxVal = int.Parse(RecMSE.NumPezzi.ToString()!);
innerCircleVals.Add(new CircleGaugeMulti.CircSegm() { Color = "#DCFD15", Value = RecMSE.PezziProd });
if (RecMSE.PezziConf > 0)
{
innerCircleVals.Add(new CircleGaugeMulti.CircSegm() { Color = "#13FD67", Value = RecMSE.PezziConf });
}
if (RecMSE.extraVal > 0)
{
outerCircleVals.Add(new CircleGaugeMulti.CircSegm() { Color = "#1367FD", Value = RecMSE.extraVal });
}
}
}
#region Public Methods
/// <summary>
/// formatta la durata in minuti in un modo "human readable" gg/ore/min
/// </summary>
/// <param name="minuti">minuti</param>
/// <returns></returns>
public static string formatDurata(double? minuti)
{
string answ = "??";
if (minuti != null)
{
DateTime tempo = new DateTime();
tempo = tempo.AddMinutes((double)minuti);
if (minuti < 60)
{
answ = $"{tempo.Minute:00}:{tempo.Second:00}";
}
else if (minuti < 1440)
{
answ = $"{tempo.Hour}h {tempo.Minute}m";
}
else
{
answ = $"{tempo.DayOfYear}g {tempo.Hour}h";
}
}
return answ;
}
/// <summary>
/// url completo immagine
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public string ImgUrlMacc(string url)
{
string answ = "";
if (string.IsNullOrEmpty(url.ToString()))
{
//url = "Steamware.png";
url = "SIMDP1.png";
}
// verifico esistenza macchina SMALL...
answ = $"images/macchine/small/{url}";
string fullPath = Path.Combine(imgBasePath, "wwwroot", answ);
if (!File.Exists(fullPath))
{
// se non ci fosse cerco immagine fullsize
answ = $"images/macchine/{url}";
fullPath = Path.Combine(imgBasePath, "wwwroot", answ);
}
// altrimenti metto default Steamware
if (!File.Exists(fullPath))
{
//answ = "images/macchine/Steamware.png";
answ = "images/macchine/SIMDP1.png";
}
return answ;
}
#endregion Public Methods
#region Protected Fields
protected string baseCss = "sem";
protected int kaFactor = 60 / 2;
#endregion Protected Fields
#region Protected Properties
protected ProdAdvDispl.ProdCounter CurrCount
{
get
{
ProdAdvDispl.ProdCounter answ = new ProdAdvDispl.ProdCounter()
{
numPzConf = (int)RecMSE.PezziConf,
numPzOrd = (int)RecMSE.NumPezzi,
numPzProd = (int)RecMSE.PezziProd
};
return answ;
}
}
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnAfterRenderAsync(bool firstRender)
{//await Task.Delay(500);
if (firstRender)
{
await getWDim();
StateHasChanged();
}
isLoading = RecMSE == null;
await Task.Delay(1);
//return base.OnAfterRenderAsync(firstRender);
}
protected override async void OnInitialized()
{
isLoading = true;
// se configurata uso cartella virtuale... altrimenti cartella processo
imgBasePath = Environment.CurrentDirectory; // @"C:\Steamware\macchine";
await setGaugeVals();
}
protected override async Task OnParametersSetAsync()
{
isLoading = RecMSE == null;
await Task.Delay(1);
}
protected async Task ShowDetail()
{
// salvo idxMacch
await MServ.IdxMaccSet(RecMSE!.IdxMacchina);
// navigo!
NavMan.NavigateTo($"machine-detail");
}
#endregion Protected Methods
#region Private Fields
private string imgBasePath = "";
private bool isLoading = false;
#endregion Private Fields
#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}";
return answ;
}
#endregion Private Methods
}
}
@@ -0,0 +1,88 @@
/* Bordi */
/*.rCAll {
border-radius: 10px;
}
.rCTop {
border-radius: 10px 10px 0 0;
}
.rCBot {
border-radius: 0 0 10px 10px;
}*/
.mapBlock {
font-family: 'Open Sans Condensed', sans-serif;
color: #FFF;
background-image: linear-gradient(#111, #000);
min-width: 8em;
}
.labelTopDx {
padding: 0.1em 0.4em;
width: auto;
min-height: 0;
top: 0;
left: auto;
bottom: auto;
color: #FFFFFF;
background: #2200DE;
background: rgba(33, 36, 39, 0.7);
border-radius: 15px 15px 0 0;
/*-webkit-border-top-right-radius: inherit;
border-top-right-radius: inherit;
-webkit-border-top-left-radius: inherit;
border-top-left-radius: inherit;
-webkit-border-bottom-left-radius: inherit;
border-bottom-left-radius: inherit;
-webkit-border-bottom-right-radius: 0;
border-bottom-right-radius: 0;*/
}
/* area semafori*/
.sVe {
text-align: left;
background: #009036;
background: #198754;
/*background: rgba(0,255,80,.6);*/
/*padding: 0px 4px 0px 4px;*/
/*color: Yellow;*/
color: #fff;
}
.sGi {
text-align: left;
background: #ffec00;
background: rgba(255, 220, 0, 0.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
.sRo {
text-align: left;
background-color: #e2001a;
background: rgba(240, 0, 10, 0.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
.sBl {
text-align: left;
background: #3690FF;
background: rgba(0, 80, 255, 0.6);
/*padding: 0px 4px 0px 4px;*/
/*color: Yellow;*/
color: #fff;
}
.sGr {
text-align: left;
background-color: #bcbcbc;
background: rgba(180, 180, 180, 0.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
/*end semafori */
.imgFitToSize {
height: 7.5rem;
object-fit: cover;
border-radius: 15px 15px 0 0;
}
@media (max-width: 640.98px) {
.imgFitToSize {
height: 5rem;
}
}
@@ -0,0 +1,98 @@
/* Bordi */
/*.rCAll {
border-radius: 10px;
}
.rCTop {
border-radius: 10px 10px 0 0;
}
.rCBot {
border-radius: 0 0 10px 10px;
}*/
.mapBlock {
font-family: 'Open Sans Condensed', sans-serif;
color: #FFF;
background-image: linear-gradient(#111, #000);
min-width: 8em;
}
.labelTopDx {
padding: 0.1em 0.4em;
width: auto;
min-height: 0;
top: 0;
left: auto;
bottom: auto;
color: #FFFFFF;
background: #2200DE;
background: rgba(33,36,39,.7);
border-radius: 15px 15px 0 0;
/*-webkit-border-top-right-radius: inherit;
border-top-right-radius: inherit;
-webkit-border-top-left-radius: inherit;
border-top-left-radius: inherit;
-webkit-border-bottom-left-radius: inherit;
border-bottom-left-radius: inherit;
-webkit-border-bottom-right-radius: 0;
border-bottom-right-radius: 0;*/
}
/* area semafori*/
.sVe {
text-align: left;
background: #009036;
background: #198754;
/*background: rgba(0,255,80,.6);*/
/*padding: 0px 4px 0px 4px;*/
/*color: Yellow;*/
color: #fff;
}
.sGi {
text-align: left;
background: #ffec00;
background: rgba(255,220,0,.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
.sRo {
text-align: left;
background-color: #e2001a;
background: rgba(240,0,10,.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
.sBl {
text-align: left;
background: #3690FF;
background: rgba(0,80,255,.6);
/*padding: 0px 4px 0px 4px;*/
/*color: Yellow;*/
color: #fff;
}
.sGr {
text-align: left;
background-color: #bcbcbc;
background: rgba(180,180,180,.6);
color: #fff;
/*padding: 0px 4px 0px 4px;*/
}
/*end semafori */
.imgFitToSize {
height: 7.5rem;
object-fit: cover;
border-radius: 15px 15px 0 0;
}
@media (max-width: 640.98px){
.imgFitToSize{
height: 5rem;
}
}
+1
View File
@@ -0,0 +1 @@
.mapBlock{font-family:'Open Sans Condensed',sans-serif;color:#fff;background-image:linear-gradient(#111,#000);min-width:8em;}.labelTopDx{padding:.1em .4em;width:auto;min-height:0;top:0;left:auto;bottom:auto;color:#fff;background:#2200de;background:rgba(33,36,39,.7);border-radius:15px 15px 0 0;}.sVe{text-align:left;background:#009036;background:#198754;color:#fff;}.sGi{text-align:left;background:#ffec00;background:rgba(255,220,0,.6);color:#fff;}.sRo{text-align:left;background-color:#e2001a;background:rgba(240,0,10,.6);color:#fff;}.sBl{text-align:left;background:#3690ff;background:rgba(0,80,255,.6);color:#fff;}.sGr{text-align:left;background-color:#bcbcbc;background:rgba(180,180,180,.6);color:#fff;}.imgFitToSize{height:7.5rem;object-fit:cover;border-radius:15px 15px 0 0;}@media(max-width:640.98px){.imgFitToSize{height:5rem;}}
+36
View File
@@ -0,0 +1,36 @@
<div class="row mt-2">
@if (ShowBtn)
{
<div class="col-12">
<button class="btn btn-lg bg-info w-100" @onclick="ToggleCtrl">
<i class="fa-solid fa-star"></i>
&nbsp;
<span class="fs-4 fw-bold">@Title</span>
</button>
</div>
}
else
{
<div class="col-6">
<div class="input-group">
<span class="input-group-text" id="basic-addon1">Data Ora</span>
<input type="datetime-local" class="form-control" id="floatDate" @bind="@DateSel">
</div>
</div>
<div class="col-6">
<button class="btn btn-warning w-100 align-middle" @onclick="doCancel"><i class="fa-solid fa-ban"></i> Annulla</button>
</div>
<div class="col-12 my-1">
<div class="form-floating">
<textarea type="text" class="form-control" id="floatingComm" style="height: 6rem;" @bind="@UserComment"></textarea>
<label for="floatingComm">Commento</label>
</div>
</div>
<div class="col-12">
@if (CanSave)
{
<button class="btn btn-success w-100" @onclick="doSave"><i class="fa-solid fa-plus"></i> Salva</button>
}
</div>
}
</div>
+240
View File
@@ -0,0 +1,240 @@
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::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 MP_TAB_SERV;
using MP_TAB_SERV.Shared;
using MP_TAB_SERV.Components;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.Data.Services;
using Newtonsoft.Json;
using NLog;
namespace MP_TAB_SERV.Components
{
public partial class NotesEditor
{
#region Public Properties
[Parameter]
public bool CanSave { get; set; } = false;
[Parameter]
public EventCallback<string> E_CommRec { get; set; }
[Parameter]
public EventCallback<DateTime> E_DateSel { get; set; }
[Parameter]
public EventCallback<bool> E_Updated { get; set; }
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
[Parameter]
public string Title { get; set; } = "NA";
[Parameter]
public EventListModel? CurrRecord
{
set
{
if (value != null)
{
DateSel = value.InizioStato ?? DateTime.Now;
UserComment = value.Value;
ShowBtn = false;
}
}
}
#endregion Public Properties
#region Protected Properties
protected DateTime DateSel
{
get => dateSel.Round(TimeSpan.FromSeconds(1));
set
{
if (dateSel != value)
{
dateSel = value;
E_DateSel.InvokeAsync(value).ConfigureAwait(false);
}
}
}
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected SharedMemService SMServ { get; set; } = null!;
[Inject]
protected TabDataService TabServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void doCancel()
{
DoReset();
}
/// <summary>
/// Forza salvataggio impostando data-ora
/// </summary>
/// <param name="dtRif"></param>
/// <returns></returns>
public async Task ForceSave(DateTime dtRif)
{
DateSel = dtRif;
// ora salvo
await doSave();
}
protected async Task doSave()
{
// registro evento
EventListModel newRec = new EventListModel()
{
IdxMacchina = IdxMacc,
InizioStato = DateSel,
IdxTipo = idxTipoCommento,
CodArticolo = CodArt,
Value = UserComment,
MatrOpr = MatrOpr,
pallet = "-"
};
// elimino vecchio se c'è...
await TabServ.EvListDelete(IdxMacc, DateSel, idxTipoCommento);
// inserisco
await TabServ.EvListInsert(newRec, MP.Data.Objects.Enums.tipoInputEvento.commento);
// reset
DoReset();
//ToggleCtrl();
await E_Updated.InvokeAsync(true);
}
protected override void OnInitialized()
{
idxTipoCommento = SMServ.GetConfInt("idxTipoCommento");
dltMinRealtime = SMServ.GetConfInt("dltMinRealtime");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// verifico SE ci sia una data da usare...
bool hasDtRif = await MServ.SessHasVal(MessageService.KeyCommDtRif);
if (hasDtRif)
{
await Task.Delay(1);
ShowBtn = false;
UserComment = await MServ.CommentoValGet(true);
DateSel = await MServ.CommentoDtRifGet(true);
await InvokeAsync(StateHasChanged);
}
}
protected int dltMinRealtime = 1;
/// <summary>
/// Determina se insert sia Realtime o batch con DataOra (in base a diff tra DataOra
/// selezionata e realtime, se superiore ad X minuti NON realtime)
/// </summary>
protected bool insRealtime
{
get
{
bool answ = true;
try
{
if (Math.Abs(DateSel.Subtract(DateTime.Now).TotalMinutes) > dltMinRealtime)
{
answ = false;
}
}
catch
{ }
return answ;
}
}
protected void ToggleCtrl()
{
ShowBtn = !ShowBtn;
if (ShowBtn)
{
DateSel = DateTime.Now;
}
}
#endregion Protected Methods
#region Private Fields
private int idxTipoCommento = 0;
#endregion Private Fields
#region Private Properties
private string CodArt
{
get => RecMSE != null ? RecMSE.CodArticolo : "";
}
private DateTime dateSel { get; set; } = DateTime.Now;
private string IdxMacc
{
get => RecMSE != null ? RecMSE.IdxMacchina : "";
}
private int MatrOpr
{
get => MServ.MatrOpr;
}
private bool ShowBtn { get; set; } = true;
private string userComment { get; set; } = "";
private string UserComment
{
get => userComment.Trim();
set
{
if (userComment != value)
{
userComment = value;
E_CommRec.InvokeAsync(value).ConfigureAwait(false);
}
}
}
#endregion Private Properties
#region Private Methods
private void DoReset()
{
UserComment = "";
DateSel = DateTime.Now;
ShowBtn = true;
}
#endregion Private Methods
}
}
+107
View File
@@ -0,0 +1,107 @@

<NotesEditor CanSave="true" Title="Nuovo Commento" RecMSE="@RecMSE" E_Updated="DoUpdate" CurrRecord="@currEv"></NotesEditor>
<div class="row mt-1">
<div class="col-7 col-sm-8 col-lg-9 pr-1">
<div class="row">
<div class="col-6">
<div class="form-floating">
<select class="form-select" @bind="@NumGiorni" id="floatingLabelGG" style="background-color: #4d5052; color: #FFF;">
@for (int i = 1; i < 11; i++)
{
<option label="@i" value="@i"></option>
}
<option label="15" value="15"></option>
<option label="30" value="30"></option>
<option label="60" value="60"></option>
<option label="90" value="90"></option>
<option label="180" value="180"></option>
<option label="360" value="360"></option>
</select>
<label for="floatingLabelGG">Ultimi gg</label>
</div>
</div>
<div class="col-6">
<div class="form-floating">
<select class="form-select" @bind="@DurataMin" id="floatingLabelDurMin" style="background-color: #4d5052; color: #FFF;">
@for (int i = 1; i < 7; i++)
{
<option label="@(5*i)'" value="@(5*i)"></option>
}
<option label="2h" value="120"></option>
<option label="4h" value="240"></option>
<option label="8h" value="480"></option>
<option label="1gg" value="1440"></option>
<option label="2gg" value="2880"></option>
</select>
<label for="floatingLabelDurMin">Durata min</label>
</div>
</div>
</div>
<div class="d-flex justify-content-between flex-wrap">
@foreach (var item in RecordListFnq)
{
<LongStopList currFnq="@item"></LongStopList>
}
</div>
</div>
<div class="col-5 col-sm-4 col-lg-3 pl-1">
<div class="form-floating">
<input type="number" class="form-control" @bind="@NumComm" id="commentsNum" style="background-color: #212427; color: #FFF;">
<span for="commentsNum"># Commenti</span>
</div>
@if (RecordListComments == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (RecordListComments.Count == 0)
{
<div class="alert alert-warning">Nessun record trovato</div>
}
else
{
foreach (var item in RecordListComments)
{
<div class="my-1 w-100">
<div class="card text-white w-100" style="font-size: 1.5rem">
<div class="card-header py-0 px-2 mb-0 rCTop fs-3" style="background-color: rgba(33,36,39, .8)">
<b>@item.Operatore</b>
</div>
<div class="card-body bg-dark p-1">
<div class="bg-dark p-1">
@item.Value
</div>
<div class="d-flex justify-content-between">
<div class="col-6 p-2">
<button class="btn btn-sm btn-info w-100" @onclick="() => EditRec(item)"><i class="fa fa-edit"></i></button>
</div>
<div class="col-6 p-2">
<button class="btn btn-sm btn-danger w-100" @onclick="() => DeteleRec(item)"><i class="fa fa-trash"></i></button>
</div>
</div>
</div>
<div class="card-footer bg-dark d-flex justify-content-between" style="font-size: .8rem">
<div class="text-start p-0">
@($"{item.InizioStato:yyyy/MM/dd HH:mm:ss}")
</div>
<div class="text-end p-0">
@item.CodArticolo
@($"ODL{item.IdxODL:000000000}")
</div>
</div>
</div>
</div>
}
}
</div>
</div>
+171
View File
@@ -0,0 +1,171 @@
using global::Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class NotesMan
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Protected Properties
protected int DurataMin
{
get => _durataMin;
set
{
if (_durataMin != value)
{
_durataMin = value;
var pUpd = Task.Run(async () =>
{
await ReloadFnq();
});
pUpd.Wait();
}
}
}
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MessageService MsgServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
protected int NumComm
{
get => numComm;
set
{
if (numComm != value)
{
numComm = value;
var pUpd = Task.Run(async () =>
{
await ReloadComments();
});
pUpd.Wait();
}
}
}
protected int NumGiorni
{
get => _numGiorni;
set
{
if (_numGiorni != value)
{
_numGiorni = value;
var pUpd = Task.Run(async () =>
{
await ReloadFnq();
});
pUpd.Wait();
}
}
}
protected List<CommentiModel>? RecordListComments { get; set; } = new List<CommentiModel>();
protected List<FermiNonQualModel> RecordListFnq { get; set; } = new List<FermiNonQualModel>();
[Inject]
protected TabDataService TabServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DeteleRec(CommentiModel currRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler eliminare il record?"))
return;
RecordListComments = null;
await Task.Delay(1);
await TabServ.EvListDelete(currRec.IdxMacchina, currRec.InizioStato, currRec.IdxTipo);
// ricarico
await ReloadComments();
await ReloadFnq();
}
protected async Task EditRec(CommentiModel currRec)
{
await Task.Delay(1);
currEv = new EventListModel()
{
InizioStato = currRec.InizioStato,
Value = currRec.Value
};
}
protected override async Task OnParametersSetAsync()
{
await ReloadComments();
await ReloadFnq();
}
protected EventListModel? currEv { get; set; } = null;
#endregion Protected Methods
#region Private Properties
private int _durataMin { get; set; } = 5;
private int _numGiorni { get; set; } = 1;
private int numComm { get; set; } = 5;
#endregion Private Properties
#region Private Methods
private async Task DoUpdate(bool forceReload)
{
if (forceReload)
{
currEv = null;
await ReloadComments();
}
}
private async Task ReloadComments()
{
RecordListComments = await TabServ.CommentiGetLastByMacc(RecMSE?.IdxMacchina, NumComm);
}
private async Task ReloadFnq()
{
RecordListFnq = await TabServ.FermiNonQualificatiFilt(RecMSE?.IdxMacchina, NumGiorni, DurataMin);
}
private string setSemaforo(string sem)
{
string answ = "";
if (sem == "sBl")
{
answ = "bg-primary text-warning";
}
else if (sem == "sGr")
{
answ = "bg-secondary text-dark";
}
else if (sem == "sGi")
{
answ = "bg-warning text-dark";
}
return answ;
}
#endregion Private Methods
}
}
+5
View File
@@ -0,0 +1,5 @@
<h3>OdlProdFix</h3>
@code {
}
+5
View File
@@ -0,0 +1,5 @@
<h3>OdlSetup</h3>
@code {
}
+5
View File
@@ -0,0 +1,5 @@
<h3>ParamsMan</h3>
@code {
}
+12
View File
@@ -0,0 +1,12 @@
<div class="row textCondens mb-1">
<div class="col-6 text-end">
<b>Gestione stampa etichette <i class="fa fa-long-arrow-right" aria-hidden="true"></i></b>
<br />
Gestione etichette per l'ODL con modulo MAG
</div>
<div class="col-6">
<a runat="server" href="@navUrl" target="_blank" class="btn btn-success btn-lg w-100">MAG <i class="fa fa-print"></i></a>
</div>
</div>
+108
View File
@@ -0,0 +1,108 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class PrintMag
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Protected Properties
[Inject]
protected IConfiguration config { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
protected int QtaUdc { get; set; } = 0;
[Inject]
protected SharedMemService SMServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task FixQtyUdc()
{
int answ = 1;
string codGrp = "IMB";
string codVal = "NUM_PZ_CONT";
// recupero dato da scheda tecnica della quantità per UDC
var tabSTAR = await TabDServ.STAR_byGrpOdlLbl(codGrp, codVal, IdxOdl);
if (tabSTAR.Count > 0)
{
try
{
int.TryParse(tabSTAR[0].Value, out answ);
}
catch
{ }
}
QtaUdc = answ;
}
protected override async Task OnInitializedAsync()
{
await FixQtyUdc();
var currUrl = NavMan.Uri;
string baseUrl = config["OptConf:BaseUrl"];
string UrlTabJumpMag = SMServ.GetConf("UrlTabJumpMag");
if (string.IsNullOrEmpty(UrlTabJumpMag))
{
UrlTabJumpMag = "MP/MAG/jumper";
}
// recupero base path dall'URL SENZA baseUrl
string baseUri = NavMan.BaseUri.Replace(baseUrl, "");
// completare con config valda metodo base
navUrl = $"{baseUri}{UrlTabJumpMag}?MatrOpr={MatrOpr}&UserAuthKey={UserAuthKey}&IdxOdl={IdxOdl}&IdxMacchina={IdxMacc}&QtaUdc={QtaUdc}";
//navUrl = $"{currUrl.Scheme}://{currUrl.Authority}/{UrlTabJumpMag}?MatrOpr={MatrOpr}&UserAuthKey={UserAuthKey}&IdxOdl={idxOdl}&IdxMacchina={idxMacchina}&QtaUdc={QtaUdc}";
await Task.Delay(1);
}
#endregion Protected Methods
#region Private Fields
private string navUrl = "";
#endregion Private Fields
#region Private Properties
private string IdxMacc
{
get => RecMSE != null ? RecMSE.IdxMacchina : "";
}
private int IdxOdl
{
get => RecMSE != null ? RecMSE.IdxOdl ?? 0 : 0;
}
private int MatrOpr
{
get => MServ.MatrOpr;
}
private string UserAuthKey
{
get => MServ.UserAuthKey;
}
#endregion Private Properties
}
}
+24
View File
@@ -0,0 +1,24 @@
<div class="progress">
<div runat="server" id="divGreen" class="progress-bar bg-success" style="width: @(NumGreen)%">
@($"{NumGreen}%")
</div>
<div runat="server" id="divYellow" class="progress-bar bg-warning text-dark" style="width: @(NumYellow)%">
@($"{NumYellow}%")
</div>
<div runat="server" id="divGray" class="progress-bar bg-secondary" style="width: @(NumGray)%">
@($"{NumGray}%")
</div>
<div runat="server" id="divBlue" class="progress-bar bg-primary" style="width: @(NumBlue)%">
@if (NumGreen >0)
{
@($"+ {NumBlue}%")
}
else
{
@($"{NumBlue}%")
}
</div>
</div>
<asp:HiddenField runat="server" ID="hfProdCount" />
@@ -0,0 +1,139 @@
using global::Microsoft.AspNetCore.Components;
namespace MP_TAB_SERV.Components
{
public partial class ProdAdvDispl
{
#region Public Properties
/// <summary>
/// Conteggio dati produzione da mostrare
/// </summary>
[Parameter]
public ProdCounter CountData { get; set; } = null!;
#endregion Public Properties
#region Public Classes
/// <summary>
/// Classe gesitone conteggi produzione
/// </summary>
public class ProdCounter
{
#region Public Properties
/// <summary>
/// NUmero pezzi CONFERMATI
/// </summary>
public int numPzConf { get; set; } = 0;
/// <summary>
/// Numero pezzi ORDINATI
/// </summary>
public int numPzOrd { get; set; } = 0;
/// <summary>
/// Numero pezzi PRODOTTI
/// </summary>
public int numPzProd { get; set; } = 0;
#endregion Public Properties
}
#endregion Public Classes
#region Protected Fields
protected int nBlue = 0;
protected int nGray = 0;
protected int nGreen = 0;
protected int nYellow = 0;
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Numero pezzi per display BLU
/// </summary>
protected int NumBlue { get; set; } = 0;
/// <summary>
/// Numero pezzi per display GRIGIO
/// </summary>
protected int NumGray { get; set; } = 40;
/// <summary>
/// Numero pezzi per display VERDE
/// </summary>
protected int NumGreen { get; set; } = 20;
/// <summary>
/// Numero pezzi CONFERMATI
/// </summary>
protected int NumPzConf { get; set; } = 0;
/// <summary>
/// Numero pezzi ORDINATI
/// </summary>
protected int NumPzOrd { get; set; } = 0;
/// <summary>
/// Numero pezzi PRODOTTI
/// </summary>
protected int NumPzProd { get; set; } = 0;
/// <summary>
/// Numero pezzi per display GIALLO
/// </summary>
protected int NumYellow { get; set; } = 30;
#endregion Protected Properties
#region Protected Methods
protected override void OnParametersSet()
{
decimal denom = (decimal)CountData.numPzOrd / 100; //CountData.numPzProd > CountData.numPzOrd ? (decimal)CountData.numPzProd / 100 : (decimal)CountData.numPzOrd / 100;
denom = denom == 0 ? 1 : denom;
// calcolo se sono nel caso prod < ordinati o se sono andato OVER
if (CountData.numPzProd <= CountData.numPzOrd)
{
nGreen = (int)Math.Floor((decimal)CountData.numPzConf / denom);
nYellow = (int)Math.Floor((decimal)(CountData.numPzProd - CountData.numPzConf) / denom);
nGray = 100 - (nGreen + nYellow);
nBlue = 0;
}
else
{
// green: confermati verdi
nGreen = (int)Math.Floor((decimal)CountData.numPzConf / denom);
// gialli: extra prodotti fino a 100...
if (CountData.numPzProd < CountData.numPzOrd)
{
nYellow = (int)Math.Floor((decimal)(CountData.numPzProd - CountData.numPzConf) / denom);
}
else
{
nYellow = 100 - nGreen;
}
// blu: quanti sono "extra" e da confermare
nBlue = (int)Math.Floor((decimal)(CountData.numPzProd - CountData.numPzOrd) / denom);
nGray = 0;
}
// disegno!
NumGreen = nGreen;
NumYellow = nYellow;
NumGray = nGray;
NumBlue = nBlue;
// base.OnParametersSet();
}
#endregion Protected Methods
}
}
+165
View File
@@ -0,0 +1,165 @@

<MachSel RecMSE="RecMSE" E_MachSel="SetMacc"></MachSel>
<div class="card bg-secondary">
<div class="card-header p-0 bg-success">
@if (odlOk)
{
<div class="row">
<div class="col-12">
<button class="btn btn-lg text-light w-100" @onclick="ToggleConfProd">
<i class="fa fa-check"></i> @ConfTitle
</button>
</div>
</div>
}
else
{
<div class="alert alert-warning fs-3">MANCA ODL: conferma NON permessa</div>
}
</div>
<div class="card-body p-0 text-light">
@if (showInnov)
{
<div class="row textCondens text-end bg-dark m-1 p-1" runat="server" id="divInnovazioni" onloadeddata="showConfirmButton()">
<div class="col-6 py-1 text-start text-uppercase">
<b>Dati Incrementali</b>
</div>
<div class="col-6 text-end">
<sub>
ultima conferma --> @dtReqUpdate.ToString()
</sub>
</div>
<div class="col-6 col-sm-3 px-0 align-self-end fw-bold">
<label>Pz Prodotti CONFERMATI</label>
<input class="form-control fs-2 text-end alert alert-warning py-0 mb-0" @bind="numPzProdotti2Rec" @onblur="() => setConfirmBtn(true)" @onfocus="() => setConfirmBtn(false)">
</div>
<div class="col-6 col-sm-3 px-0 align-self-end fw-bold">
<div class="d-flex justify-content-around">
<div>
<span class="text-danger">Pz Scarto</span>
+
<span class="text-success">Pz Buoni</span>
</div>
</div>
<div class="px-2 fs-4">
<div class="d-flex justify-content-around">
<div>
<span runat="server" class="text-danger py-0">@lblPz2RecScarto</span>
+
<span runat="server" class="text-success py-0">@lblPz2RecBuoni</span>
</div>
</div>
</div>
</div>
<div class="col-6 col-sm-3 pr-1 align-self-end fw-bold">
@if (enablePzProdLasciati)
{
<label ID="lblNumLasciati" class="mb-0">Pz Prodotti LASCIATI</label>
<input class="form-control fs-2 text-end alert alert-warning py-0 mb-0" @bind="numPzLasciati" @onblur="() => setConfirmBtn(true)" @onfocus="() => setConfirmBtn(false)">
}
else
{
<label class="btn btn-dark text-light btn-lg w-100" Visible="false">&nbsp;</label>
}
</div>
<div class="col-6 col-sm-3 px-0 align-self-end fw-bold">
@if (showConfirm)
{
<button class="btn btn-success text-light btn-lg w-100" @onclick="SalvaConfPz"><i class="fa-regular fa-floppy-disk"></i> CONFERMA</button>
}
</div>
</div>
}
</div>
</div>
<div class="row textCondens">
<div class="col-6 py-1 text-start text-uppercase">
<b>Dati Globali ODL</b>
</div>
<div class="col-6 text-end" id="divPeriodo">
<sub>
Periodo ODL calcolato:
<span>@dtInizio</span>
-
<span>@dtFine</span>
</sub>
</div>
<div class="col-6 col-sm-3 pr-1 py-0 text-end">
<div class="alert alert-warning py-1">
<div class="text-truncate">
[A] NUOVI Pz.Prod
</div>
<div class="my-0 fw-bold fs-2">
@if (isProcessing)
{
<i class="fa-solid fa-spinner span"></i>
}
else
{
<span>@numPz2Rec.ToString("N0")</span>
}
</div>
</div>
</div>
<div class="col-6 col-sm-3 pl-1 px-sm-1 py-0 text-end">
<div class="alert alert-info py-1">
<div class="text-truncate">
Pz Prodotti TOT [A+B+C]
</div>
<div class="my-0 fw-bold fs-2">
@if (isProcessing)
{
<i class="fa-solid fa-spinner span"></i>
}
else
{
<span>@numPzProdotti.ToString("N0")</span>
}
</div>
</div>
</div>
<div class="col-6 col-sm-3 pr-1 px-sm-1 py-0 text-end">
<div class="alert alert-danger py-1">
<div class="text-truncate">
[B] Scarti VERS.
</div>
<div class="my-0 fw-bold fs-2">
@if (isProcessing)
{
<i class="fa-solid fa-spinner span"></i>
}
else
{
<span>@numPzScaConf.ToString("N0")</span>
}
</div>
</div>
</div>
<div class="col-6 col-sm-3 pl-1 py-0 text-end">
<div class="alert alert-success py-1">
<div class="text-truncate">
[C] Pz Buoni VERS.
</div>
<div class="my-0 fw-bold fs-2">
@if (isProcessing)
{
<i class="fa-solid fa-spinner span"></i>
}
else
{
<span>@numPzBuoniConf.ToString("N0")</span>
}
</div>
</div>
</div>
</div>
@if (!string.IsNullOrEmpty(lblOut))
{
<div class="d-flex justify-content-around my-2">
<div class="alert alert-info py-1 w-100 text-center">
@lblOut
</div>
</div>
}
<ShowProcessing IsProcessing="@isProcessing"></ShowProcessing>
+704
View File
@@ -0,0 +1,704 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class ProdConfirm
{
#region Public Properties
/// <summary>
/// registrato nuovo valore
/// </summary>
[Parameter]
public EventCallback<bool> E_inserting { get; set; }
/// <summary>
/// registrato nuovo valore
/// </summary>
[Parameter]
public EventCallback<bool> E_newVal { get; set; }
/// <summary>
/// registrato nuovo valore
/// </summary>
[Parameter]
public EventCallback<bool> E_reset { get; set; }
/// <summary>
/// Verifica ODL OK (ovvero caricato x macchina...)
/// </summary>
public bool odlOk
{
get => (RecMSE != null && RecMSE.IdxOdl > 0);
}
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Public Methods
/// <summary>
/// Aggiorno valori produzione alla data richiesta...
/// </summary>
/// <param name="newDate"></param>
public async Task doUpdate()
{
isProcessing = true;
await Task.Delay(1);
datiProdAct = await TabDServ.StatoProdMacchina(IdxMaccSel, dtReqUpdate);
// aggiorno visualizzazione...
numPzProdotti = datiProdAct.PzTotODL;
numPz2Rec = datiProdAct.Pz2RecTot;
numPzScaConf = datiProdAct.PzConfScarto;
numPzBuoniConf = datiProdAct.PzConfBuoni;
numPzProdotti2Rec = datiProdAct.Pz2RecTot;
numPzScarto2Rec = datiProdAct.Pz2RecScarto;
dtInizio = RecMSE?.DataInizioOdl ?? DateTime.Today.AddMonths(-2);
dtFine = dtReqUpdate;
isProcessing = false;
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Properties
protected string ConfTitle
{
get => showInnov ? "Nascondi Conferma" : "Mostra Conferma";
}
/// <summary>
/// Dati produzioen rilevati
/// </summary>
protected StatoProdModel? datiProdAct { get; set; } = null;
protected DateTime dtFine { get; set; } = DateTime.Today.AddMonths(-1);
protected DateTime dtInizio { get; set; } = DateTime.Today.AddMonths(-2);
protected int lblPz2RecBuoni
{
get => numPzConfermati - numPzLasciati;
}
//protected int lblPzBuo2Rec { get; set; } = 0;
protected int lblPz2RecScarto
{
get => numPzScarto2Rec;
}
[Inject]
protected StatusData MDataService { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
protected int numPz2Rec { get; set; } = 0;
protected int numPzBuoniConf { get; set; } = 0;
/// <summary>
/// Numero pezzi confermati (buoni - scarto)
/// </summary>
protected int numPzConfermati
{
get
{
return numPzProdotti2Rec - numPzScarto2Rec;
}
}
protected int numPzLasciati
{
get => numPzLasc;
set
{
if (value <= numPzConfermati)
{
numPzLasc = value;
}
}
}
protected int numPzProdotti { get; set; } = 0;
protected int numPzProdotti2Rec { get; set; } = 0;
protected int numPzScaConf { get; set; } = 0;
protected int numPzScarto2Rec { get; set; } = 0;
[Inject]
protected SharedMemService SMServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
lblOut = "";
numPzLasciati = 0;
if (RecMSE != null)
{
IdxMaccSel = RecMSE.IdxMacchina;
enablePzProdLasciati = SMServ.GetConfBool("enablePzProdLasciati");
confRett = SMServ.GetConfBool("confRett");
modoConfProd = SMServ.GetConfInt("modoConfProd");
await doUpdate();
}
}
protected async Task SalvaConfPz()
{
isProcessing = true;
await Task.Delay(1);
// effettua conferma con conf da DB del tipo (giorni / turni / periodo
bool fatto = effettuaConfermaProd();
// refresh tabella dati tablet...
TabDServ.RicalcMse(IdxMaccSel, 0);
// rileggo e salvo..
var ListMSE = await MDataService.MseGetAll();
if (ListMSE != null)
{
// salvo in LocalStorage...
await MServ.SaveMse(ListMSE);
// aggiorno MSE attuale
RecMSE = ListMSE.Find(x => x.IdxMacchina == IdxMaccSel);
}
// mostro output
lblOut = $"Confermata produzione {numPzConfermati - numPzLasciati} pezzi (+{numPzLasciati} pz lasciati, +{numPzScarto2Rec:N0} pz scarto) |{dtReqUpdate:HH:mm:ss} | {dtReqUpdate:ddd yyyy.MM.dd}";
// cambio button conferma...
showInnov = false;
// sollevo evento!
dtReqUpdate = DateTime.Now;
numPzLasciati = 0;
await doUpdate();
isProcessing = false;
await Task.Delay(1);
await E_newVal.InvokeAsync(true);
}
protected void setConfirmBtn(bool newVal)
{
showConfirm = newVal;
}
protected async Task SetMacc(string selIdxMacc)
{
isProcessing = true;
await Task.Delay(10);
IdxMaccSel = selIdxMacc;
await doUpdate();
isProcessing = false;
await Task.Delay(10);
}
/// <summary>
/// Cambio stato visibilità pannello e testo button
/// </summary>
protected void ToggleConfProd()
{
showInnov = !showInnov;
dtReqUpdate = DateTime.Now;
}
#endregion Protected Methods
#region Private Fields
private bool confRett = false;
private bool enablePzProdLasciati = false;
private string lblOut = "";
private int modoConfProd = 0;
#endregion Private Fields
#region Private Properties
private DateTime dtReqUpdate { get; set; } = DateTime.Now;
private string IdxMaccSel { get; set; } = "";
private bool isProcessing { get; set; } = false;
private int MatrOpr
{
get => MServ.MatrOpr;
}
private int numPzLasc { get; set; } = 0;
private bool showConfirm { get; set; } = true;
private bool showInnov { get; set; } = false;
#endregion Private Properties
#region Private Methods
/// <summary>
/// Registra conferma produzione in modalità nuova (con rettifica pezzi lasciati) o legacy
/// (con anticipo periodo)
/// </summary>
private bool effettuaConfermaProd()
{
bool fatto = false;
if (confRett)
{
// confermo al netto dei pezzi lasciati...
fatto = TabDServ.ConfermaProdMacchinaFull(IdxMaccSel, modoConfProd, numPzConfermati - numPzLasciati, numPzLasciati, numPzScarto2Rec, dtReqUpdate, MatrOpr);
}
else
{
fatto = TabDServ.ConfermaProdMacchina(IdxMaccSel, modoConfProd, numPzConfermati, numPzScarto2Rec, dtReqUpdate, MatrOpr);
}
return fatto;
}
#endregion Private Methods
#if false
/// <summary>
/// restituisce css disabled SE odl NON OK...
/// </summary>
public string cssBtnConf
{
get
{
return odlOk ? "" : "disabled";
}
}
/// <summary>
/// Data-Ora ultimo update valori produzione
/// </summary>
public DateTime dtReqUpdate
{
get
{
DateTime answ = DateTime.Now;
DateTime.TryParse(hfDtReqUpdate.Value, out answ);
return answ;
}
set
{
hfDtReqUpdate.Value = $"{value}";
}
}
protected DateTime dtFine
{
set
{
lblFine.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi PRODOTTI da ultima conferma
/// </summary>
protected DateTime dtInizio
{
set
{
lblInizio.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi PRODOTTI da ultima conferma
/// </summary>
protected int numPz2Rec
{
set
{
lblPz2RecTot.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi BUONI già confermati
/// </summary>
protected int numPzBuoniConf
{
set
{
lblPzConfBuoni.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi confermati (buoni - scarto)
/// </summary>
protected int numPzConfermati
{
get
{
return numPzProdotti2Rec - numPzScarto2Rec;
}
}
/// <summary>
/// Numero pezzi da LASCIARE non dichiarati
/// </summary>
protected int numPzLasciati
{
set
{
txtNumLasciati.Text = value.ToString();
}
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtNumLasciati.Text);
}
catch
{ }
return answ;
}
}
/// <summary>
/// Numero pezzi PRODOTTI GLOBALI
/// </summary>
protected int numPzProdotti
{
set
{
lblPzTotODL.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi PRODOTTI da registrare
/// </summary>
/// da ultima conferma
protected int numPzProdotti2Rec
{
set
{
txtNumPezzi.Text = value.ToString();
}
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtNumPezzi.Text);
}
catch
{ }
return answ;
}
}
/// <summary>
/// Numero pezzi SCARTO già confermati
/// </summary>
protected int numPzScaConf
{
set
{
lblPzConfScarto.Text = value.ToString();
}
}
/// <summary>
/// Numero pezzi SCARTATI da registrare
/// </summary>
protected int numPzScarto2Rec
{
set
{
lblPz2RecScarto.Text = value.ToString();
memLayer.ML.setSessionVal("lblPz2RecScarto", value);
}
get
{
int answ = 0;
try
{
answ = memLayer.ML.IntSessionObj("lblPz2RecScarto");
}
catch
{ }
return answ;
}
}
protected void ddlSubMacc_DataBound(object sender, EventArgs e)
{
// se ho in memoria un valore LO REIMPOSTO...
if (!string.IsNullOrEmpty(subMaccSel))
{
// se è una SUB machcina (contiene "#")
if (subMaccSel.Contains("#"))
{
// provo a preselezionare...
try
{
ddlSubMacc.SelectedValue = subMaccSel;
}
catch
{ }
}
// altrimenti salvo!
else
{
subMaccSel = ddlSubMacc.SelectedValue;
}
}
}
protected void ddlSubMacc_SelectedIndexChanged(object sender, EventArgs e)
{
subMaccSel = ddlSubMacc.SelectedValue;
// salvo ODL
DataLayerObj.taMSE.getByIdxMaccAndSub(idxMacchinaSel, subMaccSel);
//altri controlli
checkAll();
}
/// <summary>
/// salvo produzione
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtSalva_Click(object sender, EventArgs e)
{
// effettua conferma con conf da DB del tipo (giorni / turni / periodo
bool fatto = effettuaConfermaProd();
// refresh tabella dati tablet...
DataLayerObj.taMSE.forceRecalc(0, idxMacchinaSel);
// mostro output
lblOut.Text = string.Format("Confermata la produzione per {0} pezzi! (+{1} pz scarto) alle {2:yyyy-MM-dd HH:mm:ss}", numPzConfermati, numPzScarto2Rec, dtReqUpdate);
// cambio button conferma...
switchBtnConferma(!txtNumPezzi.Enabled);
// sollevo evento!
if (eh_newVal != null)
{
eh_newVal(this, new EventArgs());
}
dtReqUpdate = DateTime.Now;
doUpdate();
}
/// <summary>
/// caricamento pagina
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
checkAll();
if (isMulti)
{
// sollevo evento!
if (eh_reset != null)
{
eh_reset(this, new EventArgs());
}
}
}
}
/// <summary>
/// Update pz lasciati --&gt; aggiorno!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void txtNumLasciati_TextChanged(object sender, EventArgs e)
{
lblOut.Text = "";
updatePzBuoni();
}
/// <summary>
/// update post modifica pz buoni
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void txtNumPezzi_TextChanged(object sender, EventArgs e)
{
lblOut.Text = "";
updatePzBuoni();
}
/// <summary>
/// ODL correntemente sulla macchina
/// - cerca in Redis (TTL 5 sec)
/// - altrimenti recupera da DB...
/// </summary>
protected void updateOdl()
{
// userò ODL del turno
int answ = 0;
// cerco da redis...
int.TryParse(DataLayerObj.currODL(idxMacchinaSel, true), out answ);
// salvo!
idxOdl = answ;
}
private void checkAll()
{
updateOdl();
checkConfig();
fixSelMacc();
checkOdl();
lblOut.Text = "";
switchBtnConferma(false);
lbtShowConfProd.Visible = odlOk;
lblConfProd.Visible = !odlOk;
}
/// <summary>
/// verifica config x modalità permesse
/// </summary>
private void checkConfig()
{
// verifico SE sia permesso gestire i "Pezzi lasciati" in macchina...
lblNumLasciati.Visible = enablePzProdLasciati;
txtNumLasciati.Visible = enablePzProdLasciati;
lblEmptyNumLasciati.Visible = !enablePzProdLasciati;
}
/// <summary>
/// Verifica se abbia un ODL ATTIVO
/// </summary>
private void checkOdl()
{
lbtShowConfProd.Visible = odlOk;
lblConfProd.Visible = !odlOk;
lblMancaODL.Visible = !odlOk;
}
/// <summary>
/// Registra conferma produzione in modalità nuova (con rettifica pezzi lasciati) o legacy
/// (con anticipo periodo)
/// </summary>
private bool effettuaConfermaProd()
{
bool fatto = false;
if (confRett)
{
// confermo al netto dei pezzi lasciati...
fatto = DataLayerObj.confermaProdMacchinaFull(idxMacchinaSel, memLayer.ML.CRI("modoConfProd"), numPzConfermati - numPzLasciati, numPzLasciati, numPzScarto2Rec, dtReqUpdate);
}
else
{
fatto = DataLayerObj.confermaProdMacchina(idxMacchinaSel, memLayer.ML.CRI("modoConfProd"), numPzConfermati, numPzScarto2Rec, dtReqUpdate);
}
return fatto;
}
/// <summary>
/// Se la machcina è MULTI --&gt; mostro selettore
/// </summary>
private void fixSelMacc()
{
divSelMacc.Visible = isMulti;
if (isMulti)
{
try
{
// salvo selezione submacc
ddlSubMacc.DataBind();
subMaccSel = ddlSubMacc.SelectedValue;
}
catch
{ }
}
updateOdl();
}
/// <summary>
/// Reset parametri x calcolo pezzi (no pezzi lasciati, dataora attuale...)
/// </summary>
private void resetParam()
{
dtReqUpdate = DateTime.Now;
numPzLasciati = 0;
}
/// <summary>
/// determina comportamento btn conferma
/// </summary>
private void switchBtnConferma(bool showConf)
{
// aggiorno valori rilevati
resetParam();
doUpdate();
divInnovazioni.Visible = showConf;
if (showConf)
{
try
{
updatePzBuoni();
// sollevo evento!
if (eh_inserting != null)
{
eh_inserting(this, new EventArgs());
}
}
catch
{
txtNumPezzi.Text = "0";
logger.lg.scriviLog(string.Format("Errore recupero pezzi da confermare per la macchina {0}", idxMacchinaSel), tipoLog.ERROR);
}
}
if (showConf)
{
lblShowConfProd.Text = "Nascondi Conferma";
}
else
{
lblShowConfProd.Text = "Mostra Conferma";
// sollevo evento!
if (eh_reset != null)
{
eh_reset(this, new EventArgs());
}
}
}
/// <summary>
/// aggiorna visualizzazione pz buoni /prodotti - scarti)
/// </summary>
private void updatePzBuoni()
{
if (confRett)
{
// cambio le qta di pezzi confermati...
lblPz2RecBuoni.Text = (numPzConfermati - numPzLasciati).ToString();
}
else
{
// se ho dei pezzi lasciati RICALCOLO la data...
if (numPzLasciati > 0)
{
// calcolo la data..
DS_ProdTempi.TempiCicloRilevatiDataTable tab = DataLayerObj.taTempiCicloRilevati.getLastPzByMaccQta(idxMacchinaSel, DateTime.Now, numPzLasciati);
if (tab.Rows.Count > 0)
{
dtReqUpdate = tab[0].DataOraRif.AddSeconds(1);
}
// aggiorno
doUpdate();
}
lblPz2RecBuoni.Text = numPzConfermati.ToString();
}
// aggiorno la data calcolo + pezzi buoni...
lblDtRec.Text = dtReqUpdate.ToString();
}
#endif
}
}
+96
View File
@@ -0,0 +1,96 @@
<h2>Piano Produzione - PODL</h2>
<div class="row">
<div class="col-6">
<MachSel RecMSE="RecMSE" E_MachSel="SetMacc"></MachSel>
</div>
<div class="col-6">
<div class="form-check form-switch fs-3">
<input class="form-check-input" type="checkbox" @bind="@OnlyDirect">
<label class="form-check-label">Solo Assegnazione Diretta</label>
</div>
</div>
</div>
@if (isProcessing)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div class="row">
<div class="col-12">
@if (ListPodl.Count == 0)
{
<div class="alert alert-info fs-4">Nessun record trovato</div>
}
else
{
<table class="table table-dark table-sm table-striped text-center">
<thead>
<tr class="text-center">
<th>
Data
</th>
<th>
Articolo
</th>
<th>
Macchina
</th>
<th>
Pezzi
</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListPodl)
{
<tr>
<td>
<div>@($"{item.DueDate:dd.MM.yyyy}")</div>
<small>[@item.IdxPromessa]</small>
</td>
<td>
<div class="row">
<div class="col-6 text-start">
<b>@item.CodArticolo</b>
</div>
<div class="col-6 text-end text-nowrap">
@item.KeyRichiesta
</div>
<div class="col-12 text-center textCondens text-warning">
@item.DescArticolo
</div>
</div>
</td>
<td>
<div>
<b>@item.CodMacchina</b>
</div>
<small class="text-warning">@item.Nome</small>
</td>
<td>
<div class="row">
<div class="col-12 col-lg-6 text-nowrap text-success">
Tot: @($"{item.NumPezzi:N0}")
<div class="text-secondary textCondens">
@item.PzPallet pz/pal
</div>
</div>
<div class="col-12 col-lg-6 text-nowrap text-success">
TC: @($"{item.Tcassegnato:N2}")
<div class="text-secondary textCondens">
@TCMinSec(item.Tcassegnato) (min:sec)
</div>
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
}
+116
View File
@@ -0,0 +1,116 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Components
{
public partial class ProdPlanMan
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Public Methods
/// <summary>
/// Aggiorno valori produzione alla data richiesta...
/// </summary>
/// <param name="newDate"></param>
public async Task doUpdate()
{
isProcessing = true;
await Task.Delay(1);
ListPodl = await TabDServ.ListPODLByMacc(IdxMaccSel, true, OnlyDirect);
isProcessing = false;
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Fields
protected bool OnlyDirect
{
get => onlyDirect;
set
{
if (onlyDirect != value)
{
onlyDirect = value;
var pUpd = Task.Run(async () =>
{
await doUpdate();
});
pUpd.Wait();
}
}
}
private bool onlyDirect { get; set; } = true;
#endregion Protected Fields
#region Protected Properties
protected List<PODLExpModel> ListPodl { get; set; } = new List<PODLExpModel>();
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await Task.Delay(1);
if (RecMSE != null)
{
IdxMaccSel = RecMSE.IdxMacchina;
await doUpdate();
}
}
protected async Task SetMacc(string selIdxMacc)
{
isProcessing = true;
await Task.Delay(10);
IdxMaccSel = selIdxMacc;
await doUpdate();
isProcessing = false;
await Task.Delay(10);
}
protected string TCMinSec(object _TC)
{
string TC_MinSec = "-";
if (_TC != null)
{
double TC = 0;
bool fatto = double.TryParse($"{_TC}", out TC);
if (fatto)
{
TimeSpan ts = TimeSpan.FromMinutes(TC);
TC_MinSec = $"{ts.TotalMinutes}:{ts.Seconds:00}";
}
}
return TC_MinSec;
}
#endregion Protected Methods
#region Private Fields
private bool isProcessing = false;
#endregion Private Fields
#region Private Properties
private string IdxMaccSel { get; set; } = "";
#endregion Private Properties
}
}
+130
View File
@@ -0,0 +1,130 @@
<div class="accordion my-2" id="accProd">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
<i class="fa fa-gear"></i><b>Statistiche produzione</b>
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accProd">
<div class="accordion-body p-1">
@if (RecMSE != null)
{
<div class="bg-dark text-light text-center fw-bold">
<div colspan="4">
@($"ODL num: {RecMSE.IdxOdl}, iniziato {RecMSE.DataInizioOdl:ddd yyyy.MM.dd, HH:mm}")
</div>
</div>
<table class="table table-sm table-striped text-center">
<thead>
<tr class="stdFont" style="text-align: center; font-size: x-small">
<td>
Cod articolo
</td>
<td>
Nr pezzi lanciati
</td>
<td>
Nr pezzi confermati
</td>
<td>
Nr pezzi fatti
</td>
</tr>
</thead>
<tbody>
<tr class="rowStyle stdFont fw-bold">
<td>
@RecMSE.CodArticolo
</td>
<td>
@($"{RecMSE.NumPezzi:N0}") pz.
</td>
<td>
@RecMSE.PezziConf pz.
</td>
<td>
(@($"{RecMSE.PezziProd:N0}") pz.)
</td>
</tr>
<tr class="stdFont" style="text-align: center;">
<td>
Efficienza Globale
</td>
<td>
Efficienza Lavoro
</td>
<td>
Efficienza Teorica
</td>
<td></td>
</tr>
<tr class="stdFont">
<td>
<div>
@RecMSE.OEE_tot
</div>
(@RecMSE.OEE_RT_tot)
</td>
<td>
<div>
@RecMSE.OEE_wrk
</div>
(@RecMSE.OEE_RT_wrk)
</td>
<td>
<div>
@RecMSE.OEE_run
</div>
(@RecMSE.OEE_RT_run)
</td>
<td></td>
</tr>
<tr class="stdFont" style="text-align: center;">
<td>
Tc Medio
</td>
<td>
Tc Lavoro
</td>
<td>
Tc Tecnico
</td>
<td>
Tc impostato
</td>
</tr>
</tbody>
@*<tr class="stdFont">
<td>
<div class="fw-bold">
@($"{RecMSE.TCMedio:0.###}")
</div>
(@($"{RecMSE.TCMedioRt:0.###}"))
</td>
<td>
<div class="fw-bold">
@($"{RecMSE.TCLav:0.###}")
</div>
(@($"{RecMSE.TCLavRT:0.###}"))
</td>
<td>
<div class="fw-bold">
@($"{RecMSE.TCEff:0.###}")
</div>
(@($"{RecMSE.TCEffRT:0.###}"))
</td>
<td>
<div class="fw-bold">
@($"{RecMSE.TCAssegnato:0.###}")
</div>
</td>
</tr>*@
</table>
}
</div>
</div>
</div>
</div>
+25
View File
@@ -0,0 +1,25 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
namespace MP_TAB_SERV.Components
{
public partial class ProdStat
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE { get; set; } = null;
#endregion Public Properties
#region Protected Methods
protected override async Task OnParametersSetAsync()
{
await Task.Delay(1);
}
#endregion Protected Methods
}
}
+10
View File
@@ -0,0 +1,10 @@
<div class="p-2 col-3 col-sm-3 col-md-3 col-lg-2 flex-fill">
<div class="@objCss text-center card w-100" @onclick="() => ReportSelected()">
<div class="card-body text-light">
<i class="@objIcon" style="font-size: 8vw"></i>
</div>
<div class="card-footer text-center h-100 bg-dark text-light opacity-50 p-1">
<span class=" text-center" style="font-size: .9rem;">@objTxt</span>
</div>
</div>
</div>
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Components;
namespace MP_TAB_SERV.Components
{
public partial class ProdStopMan
{
#region Public Properties
[Parameter]
public EventCallback<int> E_EventSelected { get; set; }
[Parameter]
public int IdxEvento { get; set; } = 0;
[Parameter]
public string objCss { get; set; } = "";
[Parameter]
public string objIcon { get; set; } = "";
[Parameter]
public string objTxt { get; set; } = "";
#endregion Public Properties
#region Protected Methods
protected async Task ReportSelected()
{
await E_EventSelected.InvokeAsync(IdxEvento);
}
#endregion Protected Methods
}
}
+5
View File
@@ -0,0 +1,5 @@
<h3>ScrapMan</h3>
@code {
}
@@ -0,0 +1,20 @@
@if (IsProcessing)
{
<div class="row textCondens mb-2">
<div class="col-12">
<div class="text-center text-warning align-middle">
<div class="progress" style="height:2rem;">
<div class="progress-bar progress-bar-striped bg-primary progress-bar-animated" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 75%;">
<b>@Message</b>
</div>
</div>
</div>
</div>
</div>
}
@code {
[Parameter]
public bool IsProcessing { get; set; } = false;
[Parameter]
public string Message { get; set; } = "ELABORAZIONE IN CORSO";
}
+46
View File
@@ -0,0 +1,46 @@
<button class="btn btn-link text-light p-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasTabMenu" aria-controls="offcanvasTabMenu">
<span class="fa fa-bars fa-lg"></span>
</button>
<div class="offcanvas offcanvas-end text-start" tabindex="-1" id="offcanvasTabMenu" aria-labelledby="offcanvasTabMenuLabel">
<div class="offcanvas-header bg-secondary text-light">
<div class="d-flex flex-row">
<div class="p-0">
<img src="images/LogoSteamware.png" class="img-fluid" width="40px" />
</div>
<div class="p-0 pl-1">
<div class="flex-row">
<b class="modal-title fs-2">EgalWare</b>
</div>
<div class="flex-row">
<small>Main Menu</small>
</div>
</div>
</div>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="d-flex flex-row">
<div class="p-2">
<b class="text-danger">LINK DIRETTI</b>
</div>
</div>
<div class="d-flex flex-column">
<div class="list-group">
@foreach (var item in MenuItems)
{
<a class="p-2 list-group-item list-group-item-action" href="@item.NavigateUrl"><i class="fa fa-lg @item.icona pe-2"></i> @item.Testo</a>
}
</div>
</div>
<div class="my-4">
<button type="button" class="btn btn-secondary w-100" data-bs-dismiss="offcanvas" aria-label="Close">Chiudi</button>
</div>
</div>
</div>
@code {
[Parameter]
public List<LinkMenu> MenuItems { get; set; } = new List<LinkMenu>();
}
@@ -0,0 +1,65 @@
@using MP.Data.Services;
@using NLog;
@using System.Net.Http
@using System.Net.Http.Json
@inject SharedMemService MServ
@inject IConfiguration config
<div class="row small">
<div class="col-12 col-sm-6 col-xl-3 mb-2">
<div class="form-floating">
<select class="form-select form-select-sm" @bind="@IdxMaccSel">
<option value="*" selected>-- Tutti --</option>
@if (ListMacchineAll == null)
{
<option value="" disabled>No record found</option>
}
else
{
@foreach (var item in ListMacchineAll)
{
<option value="@item.Key">@item.Value</option>
}
}
</select>
<label for="floatingSelect">Selezione Impianto (ODL/ART)</label>
</div>
</div>
<div class="col-12 col-sm-6 col-xl-3 mb-2">
<div class="row">
<div class="col-8 col-md-9 pe-0">
<div class="form-floating small">
<input type="text" class="form-control" @bind="SearchVal">
<label><i class="fa-solid fa-magnifying-glass"></i> Articolo (3+ char)</label>
</div>
</div>
<div class="col-4 col-md-3 ps-0">
<div class="form-floating small">
<input type="number" class="form-control text-end" @bind="Num2Displ">
<label># Displ</label>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6 mb-2">
<div class="form-floating">
<select class="form-select form-select-sm" disabled="@ListArtDisabled" @bind="@CodArtSel">
<option value="" selected>-- Nessuno --</option>
@if (ListArticoli == null)
{
<option value="" disabled>No record found</option>
}
else
{
@foreach (var item in ListArticoli)
{
<option value="@item.Key">@item.Value</option>
}
}
</select>
<label for="floatingSelect">Selezione Articolo (@DisplayCount / <b>@TotalCount</b>)</label>
</div>
</div>
</div>
@@ -0,0 +1,200 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.Services;
using NLog;
namespace MP_TAB_SERV.Components
{
public partial class TcHistoryFilter
{
#region Public Properties
[Parameter]
public EventCallback<string> E_CodArt { get; set; }
[Parameter]
public EventCallback<string> E_IdxMacc { get; set; }
[Parameter]
public int MatrOpr { get; set; } = 102;
[Parameter]
public int SearchMinChar { get; set; }
[Parameter]
public string Title { get; set; } = "TC History";
#endregion Public Properties
#region Protected Fields
protected string BaseAddr = "";
#endregion Protected Fields
#region Protected Properties
protected string CodArtSel
{
get => codArtSel;
set
{
if (codArtSel != value)
{
codArtSel = value;
E_CodArt.InvokeAsync(CodArtSel).ConfigureAwait(false);
}
}
}
[Inject]
protected ListSelectDataSrv MDataService { get; set; } = null!;
protected int DisplayCount { get; set; } = 0;
protected string IdxMaccSel
{
get => idxMaccSel;
set
{
if (idxMaccSel != value)
{
idxMaccSel = value;
E_IdxMacc.InvokeAsync(value).ConfigureAwait(false);
}
}
}
protected bool ListArtDisabled { get => string.IsNullOrEmpty(SearchVal) || SearchVal.Length < SearchMinChar; }
protected Dictionary<string, string>? ListArticoli { get; set; } = null;
protected Dictionary<string, string> ListArticoliAll { get; set; } = new Dictionary<string, string>();
protected Dictionary<string, string> ListMacchineAll {
get => MServ.DictMacchine;
set => MServ.DictMacchine = value;
}
protected int Num2Displ
{
get => num2Displ;
set
{
if (num2Displ != value)
{
num2Displ = value;
FiltArticoli();
}
}
}
protected string SearchVal
{
get => searchVal;
set
{
if (searchVal != value)
{
searchVal = value;
var pUpd = Task.Run(async () =>
{
await ReloadArticoli();
});
pUpd.Wait();
}
}
}
protected int TotalCount { get; set; } = 0;
#endregion Protected Properties
#region Protected Methods
protected void FiltArticoli()
{
bool done = false;
if (!ListArtDisabled)
{
if (ListArticoliAll != null)
{
TotalCount = ListArticoliAll.Count;
ListArticoli = ListArticoliAll.Take(Num2Displ).ToDictionary(x => x.Key, x => x.Value);
DisplayCount = ListArticoli.Count;
done = true;
}
}
if (!done)
{
TotalCount = 0;
ListArticoli = new Dictionary<string, string>();
DisplayCount = 0;
}
}
protected async Task GetArticoli()
{
if (!ListArtDisabled)
{
Log.Debug("START GetArticoli");
var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal);
// trasformo!
if (rawData != null)
{
ListArticoliAll = rawData.ToDictionary(x => x.CodArticolo, x => $"{x.CodArticolo} | {x.DescArticolo} | {x.Disegno}");
}
Log.Debug("END GetArticoli");
}
}
protected override async Task OnInitializedAsync()
{
BaseAddr = config.GetValue<string>("OptConf:BaseAddr") ?? "";
await ReloadAllData();
}
protected async Task ReloadAllData()
{
await ReloadArticoli();
await ReloadMacchine();
}
protected async Task ReloadArticoli()
{
await GetArticoli();
FiltArticoli();
}
protected async Task ReloadMacchine()
{
if (ListMacchineAll == null || ListMacchineAll.Count == 0)
{
Log.Debug("START ReloadMacchine");
var rawData = await MDataService.MacchineByMatrOper(MatrOpr);
// trasformo!
if (rawData != null)
{
ListMacchineAll = rawData.ToDictionary(x => x.IdxMacchina, x => $"{x.IdxMacchina} | {x.Nome}");
}
Log.Debug("END ReloadMacchine");
}
}
#endregion Protected Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private string codArtSel { get; set; } = "";
private string idxMaccSel { get; set; } = "";
private int num2Displ { get; set; } = 20;
private string searchVal { get; set; } = "";
#endregion Private Properties
}
}
@@ -0,0 +1,19 @@
<div class="card mt-2">
<div class="card-header fs-4 bg-info fw-bold">
Scheda Tecnica
</div>
<div class="card-body d-flex justify-content-between flex-wrap">
<div class="col-6 p-1">
<button class="w-100 btn btn-light shadow p-3">Dati Articolo</button>
</div>
<div class="col-6 p-1">
<button class="w-100 btn btn-light shadow p-3">Materiali</button>
</div>
<div class="col-6 p-1">
<button class="w-100 btn btn-light shadow p-3">Attrezzatura</button>
</div>
<div class="col-6 p-1">
<button class="w-100 btn btn-light shadow p-3">Imballi</button>
</div>
</div>
</div>
@@ -0,0 +1,6 @@
namespace MP_TAB_SERV.Components
{
public partial class TechSheetDetail
{
}
}
+56
View File
@@ -0,0 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<Version>6.16.2310.1318</Version>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP_TAB_SERV</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS01.pubxml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2310.1312" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.4.2310.1312" />
<PackageReference Include="StackExchange.Redis" Version="2.2.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="Data\" />
<Folder Include="Controllers\" />
<Folder Include="wwwroot\lib\" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
<None Include="wwwroot\css\fonts\lato-v17-latin-regular.svg" />
<None Include="wwwroot\css\fonts\lato-v17-latin-regular.woff2" />
<None Include="wwwroot\css\fonts\roboto-condensed-v19-latin-regular.svg" />
<None Include="wwwroot\css\fonts\roboto-condensed-v19-latin-regular.woff2" />
<None Include="wwwroot\css\fonts\roboto-v27-latin-regular.svg" />
<None Include="wwwroot\css\fonts\roboto-v27-latin-regular.woff2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="logs\.placeholder">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
</Target>
</Project>
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue" />
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<!--
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target xsi:type="File" name="fileTarget" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" />
<target xsi:type="ColoredConsole" name="consoleTarget" layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" />
</targets>
<rules>
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
<logger name="*" minlevel="Trace" writeTo="consoleTarget" />
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
<logger name="*" minlevel="Info" writeTo="fileTarget" />
</rules>
</nlog>
+11
View File
@@ -0,0 +1,11 @@
@page "/alarms"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
<AlarmsMan RecMSE="CurrMSE"></AlarmsMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class Alarms
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+58
View File
@@ -0,0 +1,58 @@
@page "/CardDemo"
@if (CardTitles == null || CardTitles.Count == 0)
{
<div class="row">
<div class="col-12 my-2 alert alert-secondary fs-3">
waiting on browser
</div>
@for (int i = 0; i < 9; i++)
{
<div class="col-4 my-2">
<CardTest Title="Loading" DoPlaceholder="true" CardCss="bg-secondary">
</CardTest>
</div>
}
</div>
}
else
{
<div class="row">
<div class="col-12 my-2 alert alert-success fs-3">
loaded on browser
</div>
@foreach (var item in CardTitles)
{
<div class="col-4 my-2">
<CardTest Title="@item">
<div>
Demo content page for <b>@item</b>
</div>
<div>
This is an example Blazor component!
</div>
</CardTest>
</div>
}
</div>
}
@code {
protected List<string>? CardTitles { get; set; }
protected override async Task OnInitializedAsync()
{
CardTitles = null;
await Task.Delay(300);
CardTitles = new List<string>();
await InvokeAsync(StateHasChanged);
await Task.Delay(300);
for (int i = 0; i < 9; i++)
{
CardTitles.Add($"Card {i + 1:00}");
}
await Task.Delay(10);
}
}
+11
View File
@@ -0,0 +1,11 @@
@page "/controls"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
<ControlsMan RecMSE="CurrMSE"></ControlsMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class Controls
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+13
View File
@@ -0,0 +1,13 @@
@page "/declarations"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<DeclarMan></DeclarMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class Declarations
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+42
View File
@@ -0,0 +1,42 @@
@page
@model MP_TAB_SERV.Pages.ErrorModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head>
<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace MP_TAB_SERV.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
+7
View File
@@ -0,0 +1,7 @@
@page "/hw-sw-info"
<h3>HwSwInfo</h3>
@code {
}
+13
View File
@@ -0,0 +1,13 @@
@page "/iob-info"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<IobInfoMan idxMacch="@IdxMacc"></IobInfoMan>
}
+63
View File
@@ -0,0 +1,63 @@
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::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 MP_TAB_SERV;
using MP_TAB_SERV.Shared;
using MP_TAB_SERV.Components;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.Data.Services;
using NLog;
namespace MP_TAB_SERV.Pages
{
public partial class IobInfo
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+8
View File
@@ -0,0 +1,8 @@
@page "/logout"
<h3>logout</h3>
@code {
}
+24
View File
@@ -0,0 +1,24 @@
@page "/machine-detail"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<ProdStat RecMSE="CurrMSE"></ProdStat>
<PrintMag RecMSE="CurrMSE"></PrintMag>
<ProdConfirm RecMSE="CurrMSE" E_newVal="RefreshMBlock"></ProdConfirm>
<div class="row">
<div class="col-6">
<a class="btn btn-info btn-lg w-100" href="scrap"><i class="fa fa-bug"></i> Reg. SCARTI</a>
</div>
<div class="col-6">
<a class="btn btn-primary btn-lg w-100" href="controls"><i class="fa fa-wrench"></i> Reg. CONTROLLI</a>
</div>
</div>
}
+115
View File
@@ -0,0 +1,115 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
namespace MP_TAB_SERV.Pages
{
public partial class MachineDetail
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
[Inject]
protected SharedMemService MStor { get; set; } = null!;
[Inject]
protected TabDataService TabServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
if (enableSchedaTecnica)
{
checkLottiOdl();
}
}
protected async Task RefreshMBlock()
{
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
await Task.Delay(1);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool enableMagLotti = false;
private bool enableSchedaTecnica = false;
#endregion Private Fields
#region Private Methods
private void checkLottiOdl()
{
#if false
// controlla se abilitato check LOTTI MAG
if (enableMagLotti)
{
if (idxOdl > 0)
{
// controlla se ci sia lotto x ODL
if (DataLayerObj.taMagELotti.getByODL(idxOdl).Rows.Count == 0)
{
try
{
// se non c'è chiama stored x rigenerare
DataLayerObj.taMagELotti.UpsertByOdl(idxOdl, true);
}
catch
{ }
}
}
}
#endif
}
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
try
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in ReloadData{Environment.NewLine}{exc}");
}
}
// recupero parametri configurazione...
await setupConf();
}
private async Task setupConf()
{
enableSchedaTecnica = MStor.GetConfBool("enableSchedaTecnica");
enableMagLotti = MStor.GetConfBool("enableMagLotti");
await Task.Delay(1);
}
#endregion Private Methods
}
}
+14
View File
@@ -0,0 +1,14 @@
@page "/notes"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<NotesMan RecMSE="CurrMSE"></NotesMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class Notes
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+15
View File
@@ -0,0 +1,15 @@
@page "/odl"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<MachSel></MachSel>
<OdlProdFix></OdlProdFix>
<OdlSetup></OdlSetup>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class ODL
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+14
View File
@@ -0,0 +1,14 @@
@page "/parameters"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<ParamsMan></ParamsMan>
}
+63
View File
@@ -0,0 +1,63 @@
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::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 MP_TAB_SERV;
using MP_TAB_SERV.Shared;
using MP_TAB_SERV.Components;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.Data.Services;
using NLog;
namespace MP_TAB_SERV.Pages
{
public partial class Parameters
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+13
View File
@@ -0,0 +1,13 @@
@page "/prod-plan"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<ProdPlanMan RecMSE="CurrMSE"></ProdPlanMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class ProdPlan
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+28
View File
@@ -0,0 +1,28 @@
@page "/prod-stop"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<NotesEditor @ref="noteEdit" Title="Dichiarazione Fermo Retroattiva + Commento" RecMSE="CurrMSE" CanSave="false" E_DateSel="SetDate"></NotesEditor>
<ShowProcessing IsProcessing="@isProcessing"></ShowProcessing>
<div class="d-flex justify-content-between flex-wrap align-items-center mb-3">
@if (!string.IsNullOrEmpty(lblOut))
{
<div class="alert @alertCss fs-5 w-100">
@lblOut
</div>
}
@foreach (var item in events2show)
{
<ProdStopMan objCss="@item.CssClass" objIcon="@item.Icon" objTxt="@(item.Label)" IdxEvento="@item.IdxTipo" E_EventSelected="EventRecord"></ProdStopMan>
}
</div>
}
+268
View File
@@ -0,0 +1,268 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using MP_TAB_SERV.Components;
using NLog;
namespace MP_TAB_SERV.Pages
{
public partial class ProdStop
{
#region Protected Fields
protected int dltMinRealtime = 1;
protected bool isProcessing = false;
protected int minAnticipoRicalcolo = 1;
protected bool rdm_ChkOnly = false;
protected int rdm_nEvCheck = 1;
protected int rdm_nEvStep = 1;
#endregion Protected Fields
#region Protected Properties
protected string alertCss { get; set; } = "alert-danger";
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected DateTime DtRif { get; set; } = DateTime.Now;
protected List<vSelEventiBCodeModel> events2show { get; set; } = new List<vSelEventiBCodeModel>();
protected string IdxMacc { get; set; } = "";
/// <summary>
/// Determina se insert sia Realtime o batch con DataOra (in base a diff tra DataOra
/// selezionata e realtime, se superiore ad X minuti NON realtime)
/// </summary>
protected bool insRealtime
{
get
{
bool answ = true;
if (Math.Abs(DtRif.Subtract(DateTime.Now).TotalMinutes) > dltMinRealtime)
{
answ = false;
}
return answ;
}
}
protected string lblOut { get; set; } = "";
[Inject]
protected StatusData MDataService { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
protected NotesEditor? noteEdit { get; set; }
[Inject]
protected SharedMemService SMServ { get; set; } = null!;
[Inject]
protected TabDataService TabServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Processo registrazione eventi
/// </summary>
/// <param name="IdxEv"></param>
/// <returns></returns>
protected async Task EventRecord(int IdxEv)
{
isProcessing = true;
await Task.Delay(1);
// salvo evento e processo...
if (IdxEv > 0)
{
var rigaEvento = SMServ.GetEventRow(IdxEv);
if (rigaEvento != null)
{
var rigaStato = await TabServ.StatoMacchina(IdxMacc);
// processo evento...
if (insRealtime)
{
DateTime adesso = DateTime.Now.Floor(TimeSpan.FromSeconds(1));
EventListModel newRec = new EventListModel()
{
IdxMacchina = IdxMacc,
InizioStato = adesso,
IdxTipo = IdxEv,
CodArticolo = rigaStato.CodArticolo,
Value = "DRT",
MatrOpr = MatrOpr,
pallet = rigaStato.pallet
};
// se realtime
await TabServ.EvListInsert(newRec, MP.Data.Objects.Enums.tipoInputEvento.barcode);
// resetta il microstato in modo da ricevere successive info HW
TabServ.resetMicrostatoMacchina(IdxMacc);
}
else
{
// in primis disabilito insert...
TabServ.MacchinaSetInsEnab(IdxMacc, false);
// calcolo evento
string evento = $"{IdxEv}";
string commento = "";
try
{
evento = rigaEvento.Nome.Replace("Barcode - ", "");
}
catch
{ }
// genero stringa pseudo-univoca
string codRich = $"{DateTime.Now:yyMMddHHmmss}-{IdxEv}";
// x prima cosa scrivo un evento tipo "1" x chiudere la durata appena prima
// dell'evento successivo
try
{
// cerco da 1 sec DOPO evento...
var tabNext = TabServ.DDB_getNext(IdxMacc, DtRif.AddSeconds(1));
DateTime nextEvDT = tabNext != null ? tabNext.InizioStato : DateTime.Now.AddMinutes(-1);
// fix salvo la dichiarazione di chiusura
commento = $"999 - M.Lav EndEvt: {evento} [{codRich}]";
// 1 hard-coded x resettare
EventListModel newRec = new EventListModel()
{
IdxMacchina = IdxMacc,
InizioStato = nextEvDT.AddSeconds(-1),
IdxTipo = 1,
CodArticolo = rigaStato.CodArticolo,
Value = commento,
MatrOpr = MatrOpr,
pallet = rigaStato.pallet
};
await TabServ.EvListInsert(newRec, MP.Data.Objects.Enums.tipoInputEvento.barcode);
// update commento apertura!
commento = $"999 - Dich StartEvt: {evento} [{codRich}]";
newRec = new EventListModel()
{
IdxMacchina = IdxMacc,
InizioStato = DtRif.AddSeconds(1),
IdxTipo = IdxEv,
CodArticolo = rigaStato.CodArticolo,
Value = commento,
MatrOpr = MatrOpr,
pallet = rigaStato.pallet
};
await TabServ.EvListInsert(newRec, MP.Data.Objects.Enums.tipoInputEvento.barcode);
// eseguo ricalcolo!
DateTime startRicalcolo = DtRif.AddMinutes(minAnticipoRicalcolo);
// eseguo ricalcolo periodo..
await TabServ.DDB_DoRecalc(IdxMacc, startRicalcolo, 1, rdm_nEvStep, rdm_nEvCheck, rdm_ChkOnly);
// chiamo registrazione commento...
if (noteEdit != null)
{
await noteEdit.ForceSave(DtRif.AddSeconds(5));
DtRif = DateTime.Now;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in fase di riqualifica fermi{Environment.NewLine}{exc}");
}
// riabilito insert... anche se non dovrebbe servire x stored ricalcolo precedente...
TabServ.MacchinaSetInsEnab(IdxMacc, true);
}
// mostro esito
alertCss = "alert-succes";
lblOut = $"Registrata dichiarazione fermata alle {DateTime.Now:HH:mm:ss}";
}
else
{
alertCss = "alert-danger";
lblOut = $"Codice evento non valido! {IdxEv}";
}
}
// faccio refresh x singola macchina 2019.03.26
TabServ.RicalcMse(IdxMacc, 0);
// rileggo e salvo..
var ListMSE = await MDataService.MseGetAll();
if (ListMSE != null)
{
// salvo in LocalStorage...
await MServ.SaveMse(ListMSE);
// aggiorno MSE attuale
CurrMSE = ListMSE.Find(x => x.IdxMacchina == IdxMacc);
}
isProcessing = false;
}
protected override async Task OnInitializedAsync()
{
dltMinRealtime = SMServ.GetConfInt("dltMinRealtime");
minAnticipoRicalcolo = SMServ.GetConfInt("minAnticipoRicalcolo");
rdm_nEvStep = SMServ.GetConfInt("rdm_nEvStep");
rdm_nEvCheck = SMServ.GetConfInt("rdm_nEvCheck");
rdm_ChkOnly = SMServ.GetConfBool("rdm_ChkOnly");
// leggo gli altri dati
await ReloadData();
}
protected void SetDate(DateTime newDate)
{
DtRif = newDate;
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private int MatrOpr
{
get => MServ.MatrOpr;
}
#endregion Private Properties
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
try
{
IdxMacc = await MServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MServ.GetMachineMse(IdxMacc);
}
var eventsAll = await TabServ.AnagEventiGetByMacch(IdxMacc);
if (eventsAll != null)
{
events2show = eventsAll.Where(x => x.EventoTablet).OrderBy(x => x.Label).ToList();
}
}
catch
{
NavMan.NavigateTo("/", true);
}
}
}
#endregion Private Methods
}
}
+13
View File
@@ -0,0 +1,13 @@
@page "/scrap"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<ProdStopMan></ProdStopMan>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class Scrap
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+31
View File
@@ -0,0 +1,31 @@
@page "/"
@page "/home"
@page "/status-map"
<div class="row">
@if (ListMSE == null || ListMSE.Count == 0)
{
@for (int i = 0; i < 10; i++)
{
<div class="col-6 col-sm-6 col-md-4 col-lg-3 col-xl-2 mb-2 px-1 bloccoMacc">
<MachineBlock></MachineBlock>
</div>
}
}
else
{
<div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckDefault" @bind="ShowCard">
<label class="form-check-label" for="flexSwitchCheckDefault">Default switch checkbox input</label>
</div>
</div>
@foreach (var item in ListMSE)
{
<div class="col-6 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2 px-1 bloccoMacc">
<MachineBlock RecMSE="@item" FullMode="true" showCard="@ShowCard"></MachineBlock>
</div>
}
}
</div>
+235
View File
@@ -0,0 +1,235 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.Conf;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
using System.Drawing.Imaging;
using System;
namespace MP_TAB_SERV.Pages
{
public partial class StatusMap : IDisposable
{
#region Protected Fields
protected bool doAnimate = true;
protected int keepAliveMin = 1;
protected int maxCol = 6;
protected string showArt = "";
protected int slowRefreshSec = 300;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected StatusData MDataService { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
protected int slowRefreshMs
{
get
{
// tempo variabile tra +/- 10% del target
int answ = rnd.Next(900, 1100) * slowRefreshSec;
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Recupera il valore e se trovato aggiorna
/// </summary>
/// <param name="chiave">Valore da cercare</param>
/// <param name="varObj">String in cui salvare il valore se trovato</param>
/// <returns></returns>
protected bool getConfVal(string chiave, ref string varObj)
{
bool answ = false;
if (CurrConfig != null && CurrConfig.Count > 0)
{
// sistemo i parametri opzionali...
ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave);
if (risultato != null)
{
varObj = risultato.Valore;
answ = !string.IsNullOrEmpty(risultato.Valore);
}
}
return answ;
}
/// <summary>
/// Recupera il valore e se trovato aggiorna
/// </summary>
/// <param name="chiave">Valore da cercare</param>
/// <param name="varObj">Int in cui salvare il valore se trovato</param>
/// <returns></returns>
protected bool getConfValInt(string chiave, ref int varObj)
{
bool answ = false;
if (CurrConfig != null && CurrConfig.Count > 0)
{
// sistemo i parametri opzionali...
ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave);
if (risultato != null)
{
answ = int.TryParse(risultato.Valore, out varObj);
}
}
return answ;
}
/// <summary>
/// Recupera da conf eventuale setup tag dell'IOB indicato
/// </summary>
/// <param name="codIob"></param>
/// <returns></returns>
protected List<TagData>? getIobTag(string codIob)
{
List<TagData>? answ = null;
if (MDataService.currTagConf != null)
{
// cerco x chiave IOB...
if (MDataService.currTagConf.ContainsKey(codIob))
{
answ = MDataService.currTagConf[codIob];
}
}
return answ;
}
/// <summary>
/// Recupera da redis (in una chiamata soltanto) tutti i valori richiesti e compone un
/// dizionario x ottimizzare visualizzazione
/// </summary>
/// <param name="codIob"></param>
/// <returns></returns>
protected Dictionary<string, string> getTagVal(string codIob)
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// recupero conf tags...
var currTags = getIobTag(codIob);
if (currTags != null && currTags.Count > 0)
{
// FIXME TODO !!!! FARE !!!! - da verificare
answ = currTags.ToDictionary(x => x.TagLocation, x => MDataService.getTagConf(x.TagLocation));
}
return answ;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (ListMSE != null)
{
// salvo in LocalStorage...
await MServ.SaveMse(ListMSE);
}
}
protected override async Task OnInitializedAsync()
{
ListMSE = null;
await setupConf();
StartTimer();
await ReloadData();
}
public void StartTimer()
{
int tOutPeriod = 3000;
//int.TryParse(Configuration["ReloadStatusTimer"], out tOutPeriod);
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
Log.Info("Timer started!");
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
await ReloadData();
await MServ.SaveMse(ListMSE);
await InvokeAsync(StateHasChanged);
Log.Debug("Timer elapsed");
});
pUpd.Wait();
}
private System.Timers.Timer aTimer = null!;
public void Dispose()
{
if (aTimer != null)
{
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
Log.Info("Timer Disposed!");
}
}
#endregion Protected Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private static System.Timers.Timer slowTimer = new System.Timers.Timer(300000);
private List<ConfigModel>? CurrConfig = null;
private Random rnd = new Random();
#endregion Private Fields
#region Private Properties
private List<MappaStatoExpl>? ListMSE { get; set; } = null;
#endregion Private Properties
#region Private Methods
private async Task ReloadData()
{
ListMSE = await MDataService.MseGetAll();
}
//protected bool ShowCard { get; set; } = false;
protected bool _showCard = false;
protected bool ShowCard
{
get => _showCard;
set
{
_showCard = value;
StateHasChanged();
}
}
private async Task setupConf()
{
CurrConfig = await MDataService.ConfigGetAll();
if (CurrConfig != null && CurrConfig.Count > 0)
{
// sistemo i parametri opzionali...
getConfValInt("keepAliveMin", ref keepAliveMin);
getConfValInt("MON_maxCol", ref maxCol);
int intDoAnim = 0;
getConfValInt("doAnimate", ref intDoAnim);
doAnimate = intDoAnim == 1;
getConfValInt("pageRefreshSec", ref slowRefreshSec);
getConfVal("sART", ref showArt);
Log.Info($"setupConf | Effettuato setup parametri | keepAlive: {keepAliveMin} | MaxCol: {maxCol} | doAnimate: {doAnimate} | slowRefreshSec: {slowRefreshSec}");
}
}
#endregion Private Methods
}
}
+98
View File
@@ -0,0 +1,98 @@
@page "/tc-history"
<div class="card">
<div class="card-header px-2">
<TcHistoryFilter Title="Storico Tempi Ciclo" SearchMinChar="@SearchMinChar" E_CodArt="SelCodArt" E_IdxMacc="SelIdxMacc" MatrOpr="@MatrOpr"></TcHistoryFilter>
</div>
<div class="card-body px-2">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Articolo</th>
<th>Informazioni</th>
@* <th>TCiclo</th> *@
@* <th>Note</th> *@
@* <th class="text-end">Impianto</th> *@
<th>Periodo</th>
</tr>
</thead>
<tbody>
@if (isLoading)
{
@for (int i = 0; i < NumRecPage; i++)
{
<tr class="placeholder-glow">
<td>
<div class="placeholder col-4"></div>
<small class="placeholder col-8"></small>
</td>
<td>
<div class="placeholder col-6"></div>
<small class="placeholder col-6"></small>
</td>
@* <td><span class="placeholder col-12"></span></td> *@
<td><span class="placeholder col-12"></span></td>
<td class="text-end">
<div class="placeholder col-10"></div>
<small class="placeholder col-10"></small>
</td>
</tr>
}
}
else
{
@if (ListODL == null || ListODL.Count == 0)
{
<tr>
<td colspan="5">
<div class="alert alert-warning fs-3 w-100">Nessun record trovato</div>
</td>
</tr>
}
else
{
foreach (var item in ListODL)
{
<tr>
<td>
<div>@item.CodArticolo</div>
<small class="text-secondary">@item.DescArticolo</small>
</td>
<td>
<div>
<small><b>Impianto:</b> @item.IdxMacchina</small>
</div>
<div>
<small><b>TC:</b> @item.Tcassegnato.ToString("N3")</small>
</div>
<div>
<small><b>N° pz:</b> @item.NumPezzi pz</small>
</div>
<div class="badge text-bg-light border border-primary">
<small class="text-secondary">@item.Note</small>
</div>
</td>
@* <td></td> *@
<td>
<div>
<small><b>Inizio:</b> @item.DataInizio</small>
</div>
<div>
<small><b>Fine:</b> @item.DataFine</small>
</div>
</td>
@* <td class="text-end">
</td> *@
</tr>
}
}
}
</tbody>
</table>
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager currPage="@PageNum" PageSize="@NumRecPage" totalCount="@TotalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
</div>
</div>
+126
View File
@@ -0,0 +1,126 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
namespace MP_TAB_SERV.Pages
{
public partial class TCHistory
{
#region Protected Fields
protected string BaseAddr = "";
protected string CodArt = "";
protected string IdxMacc = "*";
protected bool isLoading = false;
protected int NumRecPage = 5;
protected int PageNum = 1;
protected int SearchMinChar = 3;
protected int TotalCount = 0;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected IConfiguration config { get; set; } = null!;
[Inject]
protected OrderDataSrv CtrDataServ { get; set; } = null!;
protected List<ODLExpModel> ListComplete { get; set; } = new List<ODLExpModel>();
protected List<ODLExpModel> ListODL { get; set; } = new List<ODLExpModel>();
protected int MatrOpr
{
get => MServ.MatrOpr;
}
[Inject]
protected MessageService MServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
BaseAddr = config.GetValue<string>("OptConf:BaseAddr") ?? "";
await ReloadData();
}
protected async Task ReloadData()
{
isLoading = true;
if (!string.IsNullOrEmpty(CodArt))
{
try
{
ListComplete = await CtrDataServ.ListODLFilt(CodArt, IdxMacc);
TotalCount = ListComplete.Count;
// esegue paginazione
UpdateTable();
}
catch (Exception exc)
{
Log.Error($"Error on dataload{Environment.NewLine}{exc}");
}
}
isLoading = false;
}
protected void SaveNumRec(int newNum)
{
NumRecPage = newNum;
UpdateTable();
}
protected void SavePage(int newNum)
{
PageNum = newNum;
UpdateTable();
}
protected async Task SelCodArt(string newCodArt)
{
CodArt = newCodArt;
await ReloadData();
}
protected async Task SelIdxMacc(string newIdxMacc)
{
IdxMacc = newIdxMacc;
await ReloadData();
}
protected void UpdateTable()
{
// esegue paginazione
if (TotalCount > NumRecPage)
{
ListODL = ListComplete.Skip((PageNum - 1) * NumRecPage).Take(NumRecPage).ToList();
}
else
{
ListODL = ListComplete;
}
}
#endregion Protected Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
+15
View File
@@ -0,0 +1,15 @@
@page "/tech-sheet"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<TechSheetDetail></TechSheetDetail>
}
+45
View File
@@ -0,0 +1,45 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class TechSheet
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
}
}
#endregion Private Methods
}
}
+119
View File
@@ -0,0 +1,119 @@
@page "/user"
@inject IJSRuntime JSRuntime
@inject IHttpContextAccessor httpContextAccessor
<h3>User</h3>
<div class="d-flex">
@if (Width > 1021)
{
<div class="col-3"></div>
}
<div class="card @mainSize">
<div class="card-header text-center">
<div style="font-size: 4rem;">
<i class="fa-solid fa-user"></i>
</div>
<div style="font-size: 1.5rem;">
<span>USER DATA</span>
</div>
</div>
<div class="card-body">
<div>
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between">
<div class="text-start">User</div>
<div class="text-end"><b>USERNAME[999]</b></div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div class="text-start">Server Time</div>
<div class="text-end"><b>@($"{DateTime.Now.ToString("dddd dd.MM.yyyy HH:mm.ss")}")</b></div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div class="text-start">Client IP</div>
<div class="text-end"><b>@currIpv4</b></div>
</li>
<li class="list-group-item d-flex justify-content-between">
<div class="text-start">Browser Size</div>
<div class="text-end"><b>@($"{Width}x{Height}")</b></div>
</li>
</ul>
</div>
</div>
<div class="card-footer">
<button class="w-100 btn btn-success">
<i class="fa-solid fa-gear"></i> &nbsp; ABOUT PAGE
</button>
<hr />
<button class="w-100 btn btn-danger">
<i class="fa-solid fa-right-from-bracket"></i> &nbsp; LOGOUT
</button>
</div>
</div>
@if (Width > 1021)
{
<div class="col-3"></div>
}
</div>
@code {
public int Height { get; set; } = 0;
public int Width { get; set; } = 0;
public string currIpv4 { get; set; } = "";
public class WindowDimension
{
public int Width { get; set; }
public int Height { get; set; }
}
protected async override Task OnAfterRenderAsync(bool firstRender)
{
//await Task.Delay(500);
if (firstRender)
{
await getWDim();
StateHasChanged();
Log.Debug($"Dimensioni schermo: {Width}x{Height}");
}
}
protected async override Task OnInitializedAsync()
{
await Task.Delay(1);
if (string.IsNullOrEmpty(currIpv4))
{
// ricalcolo e salvo...
if (httpContextAccessor.HttpContext != null)
{
var remoteIp = $"{httpContextAccessor.HttpContext.Connection?.RemoteIpAddress}";
// provo a recuperare ipV4...
currIpv4 = EgwCoreLib.Razor.Data.IpUtils.getLocalIpv4(remoteIp);
}
}
}
protected async Task getWDim()
{
var dimension = await JSRuntime.InvokeAsync<WindowDimension>("getWindowDimensions");
Height = dimension.Height;
Width = dimension.Width;
}
protected string mainSize
{
get
{
string answ = "col-12";
if (Width > 1021)
{
answ = "col-6";
}
return answ;
}
}
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
}
+69
View File
@@ -0,0 +1,69 @@
@page "/workshift"
@if (string.IsNullOrEmpty(IdxMacc) || CurrMSE == null)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else
{
<div>
<MachineBlock RecMSE="CurrMSE" FullMode="false"></MachineBlock>
</div>
<div class="row my-2">
<div class="col-12 col-md-6 my-2">
<div class="d-flex justify-content-around">
<div class="form-check form-switch fs-2">
<input class="form-check-input" type="checkbox" @bind="@T1">
<label class="form-check-label" >Turno 1</label>
</div>
</div>
<div class="d-flex justify-content-around">
<div class="form-check form-switch fs-2">
<input class="form-check-input" type="checkbox" @bind="@T2">
<label class="form-check-label" >Turno 2</label>
</div>
</div>
<div class="d-flex justify-content-around">
<div class="form-check form-switch fs-2">
<input class="form-check-input" type="checkbox" @bind="@T3">
<label class="form-check-label" >Turno 3</label>
</div>
</div>
</div>
<div class="col-12 col-md-6 my-2 text-center">
<div class="row">
<div class="col-2"></div>
<div class="col-8">
<h2><b>Stato Turni Attivi</b></h2>
</div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-8 fs-5 @cssByState(T1)">
Turno 1
</div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-8 fs-5 @cssByState(T2)">
Turno 2
</div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-8 fs-5 @cssByState(T3)">
Turno 3
</div>
<div class="col-2"></div>
</div>
<div class="row my-2">
<div class="col-2"></div>
<div class="col-4 bg-success text-warning px-2">
Turno Aperto
</div>
<div class="col-4 bg-secondary px-2">
Turno Chiuso
</div>
<div class="col-2"></div>
</div>
</div>
</div>
}
+93
View File
@@ -0,0 +1,93 @@
using global::Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.Data.Services;
namespace MP_TAB_SERV.Pages
{
public partial class WorkShift
{
#region Protected Properties
protected MappaStatoExpl? CurrMSE { get; set; } = null;
protected string IdxMacc { get; set; } = "";
[Inject]
protected MessageService MsgServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
#region Private Methods
private async Task ReloadData()
{
if (string.IsNullOrEmpty(IdxMacc))
{
IdxMacc = await MsgServ.IdxMaccGet();
// recupero MSE macchina....
if (!string.IsNullOrEmpty(IdxMacc))
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
// recupero turni
currTurni = await TabServ.TurnoMacchinaGet(IdxMacc);
}
}
}
protected bool T1
{
get => currTurni.T1;
set
{
if (currTurni.T1 != value)
{
currTurni.T1 = value;
TabServ.TurnoMacchinaToggle(IdxMacc, 1);
}
}
}
protected bool T2
{
get => currTurni.T2;
set
{
if (currTurni.T2 != value)
{
currTurni.T2 = value;
TabServ.TurnoMacchinaToggle(IdxMacc, 2);
}
}
}
protected bool T3
{
get => currTurni.T3;
set
{
if (currTurni.T3 != value)
{
currTurni.T3 = value;
TabServ.TurnoMacchinaToggle(IdxMacc, 3);
}
}
}
protected string cssByState(bool isActive)
{
return isActive ? "bg-success text-warning" : "bg-secondary";
}
[Inject]
protected TabDataService TabServ { get; set; } = null!;
protected TurniMaccModel currTurni { get; set; } = new TurniMaccModel();
#endregion Private Methods
}
}
+9
View File
@@ -0,0 +1,9 @@
@page "/"
@namespace MP_TAB_SERV.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
}
<component type="typeof(App)" render-mode="Server" />
@* <component type="typeof(App)" render-mode="ServerPrerendered" /> *@
+40
View File
@@ -0,0 +1,40 @@
@using Microsoft.AspNetCore.Components.Web
@namespace MP_TAB_SERV.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="mobile-web-app-capable" content="yes" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="lib/font-awesome/css/all.min.css" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/font.min.css" />
<link rel="stylesheet" href="css/site.css" />
<link href="MP-TAB-SERV.styles.css" rel="stylesheet" />
<component type="typeof(HeadOutlet)" render-mode="Server" />
@* <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> *@
</head>
<body>
@RenderBody()
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="lib/WindowSize.js"></script>
<script src="lib/bootstrap/js/bootstrap.bundle.js"></script>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
+65
View File
@@ -0,0 +1,65 @@
using Blazored.LocalStorage;
using Blazored.SessionStorage;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MP.Data;
using MP.Data.Services;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
// REDIS setup
var cString = configuration.GetConnectionString("Redis");
string connStringRedis = cString ?? "localhost:6379, DefaultDatabase=1, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false";
//string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
// avvio oggetto shared x redis...
var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
// Add services x accesso dati
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<StatusData>();
builder.Services.AddSingleton<ListSelectDataSrv>();
builder.Services.AddSingleton<OrderDataSrv>();
builder.Services.AddSingleton<SharedMemService>();
builder.Services.AddSingleton<TabDataService>();
builder.Services.AddScoped<MessageService>();
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddBlazoredSessionStorage();
// gestione email
builder.Services.Configure<MailKitMailSettings>(builder.Configuration.GetSection(nameof(MailKitMailSettings)));
builder.Services.AddScoped<MailService>();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
// aggiunt base URL x routing corretto
app.UsePathBase(configuration["OptConf:BaseUrl"]);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>https://iis01.egalware.com/MP/TAB3</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>e7a7c262-7807-4503-949d-5a6fe3df4400</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://iis01.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/TAB3</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>true</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>true</EnableMSDeployBackup>
<EnableMsDeployAppOffline>true</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>true</_SavePWD>
<_TargetId>IISWebDeploy</_TargetId>
</PropertyGroup>
</Project>
@@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52632",
"sslPort": 44318
}
},
"profiles": {
"MP-TAB-SERV": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7295;http://localhost:5189",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,25 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: {{CURRENT-REL}}</h4>
<br /> Note di rilascio:
<ul>
<li>
<b>Ultime modifiche:</b>
<ul>{{LAST-CHANGES}}</ul>
</li>
<li>
<b>v.6.15.* &rarr;</b>
<ul>
<li>Prima release dotnet6</li>
</ul>
</li>
</ul>
<div>
<div style="float: left;">
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2023</a>
</div>
</div>
</body>
+25
View File
@@ -0,0 +1,25 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2310.1318</h4>
<br /> Note di rilascio:
<ul>
<li>
<b>Ultime modifiche:</b>
<ul>{{LAST-CHANGES}}</ul>
</li>
<li>
<b>v.6.15.* &rarr;</b>
<ul>
<li>Prima release dotnet6</li>
</ul>
</li>
</ul>
<div>
<div style="float: left;">
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2023</a>
</div>
</div>
</body>
+1
View File
@@ -0,0 +1 @@
6.16.2310.1318
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.0.0.0</version>
<url>https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
<mandatory>false</mandatory>
</item>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2310.1318</version>
<url>https://nexus.steamware.net/repository/SWS/MP-TAB-SERV/stable/LAST/MP-TAB-SERV.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-TAB-SERV/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
</item>
+47
View File
@@ -0,0 +1,47 @@
@using System.Diagnostics;
@inherits LayoutComponentBase
<PageTitle>MP-TAB-SERV</PageTitle>
<div class="page">
<main>
<div class="top-row d-flex justify-content-between text-light">
<div class="col-4">
<span>
<button class="btn btn-sm @ResetClass" @onclick="() => ForceReload()" title="Update"><i class="fa-solid fa-rotate"></i></button>
Username
</span>
<sub>[999]</sub>
</div>
<div class="col-4 text-center d-flex justify-content-center">
<a href="status-map" class="text-decoration-none text-light">
<i class="fa-solid fa-house"></i> &nbsp;
MapoTAB2
&nbsp;
<img src="images/LogoSteamware.png" style="height: 1rem" />
</a>
</div>
<div class="col-4 text-end">
<div class="row w-100 slideMen">
<div class="p-0">
<SlideMenu MenuItems="@CurrMenuItems"></SlideMenu>
</div>
</div>
</div>
</div>
<article class="content pt-1 d-flex mb-5">
<div class="" id="mainBody">
@Body
</div>
<div class="sidebar" id="barLat">
<NavMenu MenuItems="@CurrMenuItems"></NavMenu>
</div>
</article>
</main>
</div>
<div class="fixed-bottom">
<CmpFooter></CmpFooter>
</div>
+159
View File
@@ -0,0 +1,159 @@
using global::Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using NLog;
using System.Diagnostics;
namespace MP_TAB_SERV.Shared
{
public partial class MainLayout : IDisposable
{
#region Public Methods
public void Dispose()
{
NavMan.LocationChanged -= HandleLocationChanged;
}
#endregion Public Methods
#region Protected Fields
protected string ResetClass = "btn-primary";
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Livello corrente del menu
/// </summary>
protected string CurrLevel { get; set; } = "";
/// <summary>
/// Elenco items da menù per pagina corrente...
/// </summary>
protected List<LinkMenu> CurrMenuItems { get; set; } = new List<LinkMenu>();
[Inject]
protected ListSelectDataSrv MDataService { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected SharedMemService MStor { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
[Inject]
protected TabDataService TDataService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task ForceReload()
{
Stopwatch sw = new Stopwatch();
sw.Start();
Log.Info("Start ForceReload");
ResetClass = "btn-warning";
await InvokeAsync(StateHasChanged);
// reset cache varie
await MServ.ClearLocalStor();
await MServ.ClearSessionStor();
await MDataService.FlushCache();
// reload MStor
await ReloadMemStor();
// calcolo tempo esecuzione
sw.Stop();
int delta = 500 - (int)sw.ElapsedMilliseconds;
delta = delta > 0 ? delta : 50;
await Task.Delay(delta);
ResetClass = "btn-primary";
// await InvokeAsync(StateHasChanged);
Log.Info($"ForceReload completed in {sw.ElapsedMilliseconds}ms");
// ricarica pagina!
NavMan.NavigateTo("/", true);
}
/// <summary>
/// Init struttura dati
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
{
NavMan.LocationChanged += HandleLocationChanged;
// verifica preliminare setup mdati
if (!MStor.MenuOk)
{
await ReloadMemStor();
}
CurrLevel = MStor.PageLevel(NavMan.Uri);
// recupero menù
if (MStor.DictMenu.ContainsKey(CurrLevel))
{
CurrMenuItems = MStor.DictMenu[CurrLevel];
}
await Task.Delay(1);
}
protected async Task ReloadMemStor()
{
// in primis svuoto...
MStor.ClearCache();
// rileggo link
var allData = await MDataService.ListLinkAll();
MStor.SetupMenu(allData);
// fix config...
var allConf = await MDataService.ConfigGetAll();
MStor.SetConfig(allConf);
// fix MSFD...
var allMSFD = await TDataService.VMSFDGetAll();
MStor.SetMsfd(allMSFD);
// fix elenco eventi
var allEvents = await TDataService.AnagEventiGetAll();
MStor.SetEventi(allEvents);
// fix elenco stati
var allStati = await TDataService.AnaStatiGetAll();
MStor.SetStati(allStati);
// non da farsi globalmente // fix macchine var allMach = await
// MDataService.MacchineByMatrOper(0); MStor.DictMacchine = allMach.ToDictionary(x =>
// x.IdxMacchina, x => $"{x.IdxMacchina} | {x.Nome}");
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Methods
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
{
// Logger.LogInformation("URL of new location: {Location}", e.Location);
CurrLevel = MStor.PageLevel(NavMan.Uri);
// recupero menù
if (MStor.DictMenu.ContainsKey(CurrLevel))
{
CurrMenuItems = MStor.DictMenu[CurrLevel];
InvokeAsync(StateHasChanged).ConfigureAwait(false);
}
}
private void OnYes()
{
Console.WriteLine($"{DateTime.Now} | 'Yes' button selected.");
}
#endregion Private Methods
}
}

Some files were not shown because too many files have changed in this diff Show More