Merge branch 'release/AppTask_07'

This commit is contained in:
2025-01-18 14:58:20 +01:00
20 changed files with 285 additions and 43 deletions
+2 -1
View File
@@ -12,6 +12,7 @@ namespace Core
// classi utilità x cache REDIS dati DB
public const string redisBaseAddr = "LiMan:Ui";
public const string rKeyConfig = $"{redisBaseAddr}:Cache";
public const string ENR_MSG_PIPE = $"{redisBaseAddr}:Enroll:Messages";
public const string ENRL_MSG_PIPE = $"{redisBaseAddr}:MPipe:Enroll";
public const string TASK_MSG_PIPE = $"{redisBaseAddr}:MPipe:Tasks";
}
}
+12 -1
View File
@@ -65,7 +65,8 @@ namespace LiMan.APi.Data
};
// conf messagepipe: setup canali pub/sub
EnrollMessPipe = new MessagePipe(redisConn, Const.ENR_MSG_PIPE);
EnrollMessPipe = new MessagePipe(redisConn, Const.ENRL_MSG_PIPE);
TaskMessPipe = new MessagePipe(redisConn, Const.TASK_MSG_PIPE);
// conf DB
string connStrDB = _configuration.GetConnectionString("LiMan.DB");
@@ -88,6 +89,10 @@ namespace LiMan.APi.Data
/// Wrapper x invio/ricezione messaggi sul canale dedicato agli eventi enroll
/// </summary>
public MessagePipe EnrollMessPipe { get; set; } = null!;
/// <summary>
/// Wrapper x invio/ricezione messaggi sul canale dedicato agli eventi Task
/// </summary>
public MessagePipe TaskMessPipe { get; set; } = null!;
#endregion Public Properties
@@ -1127,6 +1132,8 @@ namespace LiMan.APi.Data
redisHashKeyDelete(reqKey, res.Key);
done += answ ? 1 : 0;
}
// invio string in messagepipe x forzare refresh...
TaskMessPipe.sendMessage(CodImp);
return done;
}
@@ -1151,6 +1158,8 @@ namespace LiMan.APi.Data
redisHashKeyDelete(runKey, res.Key);
done += answ ? 1 : 0;
}
// invio string in messagepipe x forzare refresh...
TaskMessPipe.sendMessage(CodImp);
return done;
}
@@ -1190,6 +1199,8 @@ namespace LiMan.APi.Data
{
answ.TryAdd(item.Key, item.Value);
}
// invio string in messagepipe x forzare refresh...
TaskMessPipe.sendMessage(CodImp);
return answ;
}
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 2.1.2501.1717</h4>
<h4>Versione: 2.1.2501.1814</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
2.1.2501.1717
2.1.2501.1814
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>2.1.2501.1717</version>
<version>2.1.2501.1814</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 2.1.2501.1717</h4>
<h4>Versione: 2.1.2501.1814</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
2.1.2501.1717
2.1.2501.1814
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>2.1.2501.1717</version>
<version>2.1.2501.1814</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.Transfer.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
-1
View File
@@ -43,7 +43,6 @@ namespace LiMan.UI.Components
/// </summary>
public virtual void Dispose()
{
//LMDService.EnrollMessPipe.EA_NewMessage -= EnrollMessPipe_EA_NewMessage;
LMDService.EnrollMessPipe.EA_NewMessage -= async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
}
+25 -10
View File
@@ -16,7 +16,8 @@
<button class="btn btn-sm btn-primary @CssResetImp" title="Rimuovi Filtro Dispositivo" @onclick="ResetCodImp"><i class="fa-solid fa-rotate-right"></i> Dispositivo</button>
<Sorter ParamName="PcInst" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter>
</th>
<th># Lic.
<th>
# Lic.
<Sorter ParamName="NumImp" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter>
</th>
<th class="text-end">
@@ -55,6 +56,7 @@
<div class="card-body p-2">
<div class="row">
<div class="col-6">
<ListAppShort AppList="AppInstList"></ListAppShort>
<div class="card shadow mb-2">
<div class="card-header">
<b>Task</b>
@@ -63,26 +65,28 @@
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div>
<button class="btn btn-sm btn-info" @onclick="showDetReq">D</button>
Request
</div>
<span class="badge text-bg-primary rounded-pill">@TaskReq.Count</span>
<span class="badge @cssNumPill(TaskReq.Count) rounded-pill">@TaskReq.Count</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div>
<button class="btn btn-sm btn-info" @onclick="showDetRun">D</button>
Running
</div>
<span class="badge text-bg-primary rounded-pill">@TaskRun.Count</span>
<span class="badge @cssNumPill(TaskRun.Count) rounded-pill">@TaskRun.Count</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div>
<button class="btn btn-sm btn-info" @onclick="showDetDone">D</button>
Completed
</div>
<span class="badge text-bg-primary rounded-pill">@TaskDone.Count</span>
<span class="badge @cssNumPill(TaskDone.Count) rounded-pill">@TaskDone.Count</span>
</li>
</ul>
</div>
</div>
<ListAppShort AppList="AppInstList"></ListAppShort>
</div>
<div class="col-6">
<div class="card shadow">
@@ -90,11 +94,22 @@
<b>Detail Info</b>
</div>
<div class="card-body p-1">
<ul class="list-group">
<li class="list-group-item">TDB Info 1</li>
<li class="list-group-item">TDB Info 2</li>
<li class="list-group-item">TDB Info 3</li>
</ul>
@if (showDetail)
{
<ul class="list-group">
@foreach (var item in DetailData)
{
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="px-1">
@item.Key
</div>
<div class="px-1">
<b>@item.Value</b>
</div>
</li>
}
</ul>
}
</div>
</div>
<div class="card shadow mt-2">
+63 -2
View File
@@ -1,4 +1,5 @@
using EgwCoreLib.Razor.Data;
using LiMan.DB;
using LiMan.DB.DTO;
using LiMan.UI.Data;
using Microsoft.AspNetCore.Components;
@@ -27,7 +28,7 @@ namespace LiMan.UI.Components
public void Dispose()
{
//MServ.EA_TaskUpdate -= MServ_EA_TaskUpdate;
LMDService.TaskMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
}
#endregion Public Methods
@@ -50,7 +51,30 @@ namespace LiMan.UI.Components
protected override void OnInitialized()
{
//MServ.EA_TaskUpdate += MServ_EA_TaskUpdate;
LMDService.TaskMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
}
/// <summary>
/// Evento refresh legato a ricezione evento da MessagePipe
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async Task TaskMessPipe_EA_NewMessage(object sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// qualsiasi messaggio fa scattare reload data
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
// verifico se sia il cod impianto selezionato, nel faso forzo refreesh...
if (!string.IsNullOrEmpty(CodImpSel) && CodImpSel.Equals(currArgs.newMessage))
{
isLoading = true;
ReloadTaskStatus();
await ReloadTaskResults();
isLoading = false;
await InvokeAsync(StateHasChanged);
}
}
}
protected override void OnParametersSet()
@@ -191,6 +215,31 @@ namespace LiMan.UI.Components
#endregion Private Fields
private string cssNumPill(int numRec)
{
return numRec > 0 ? "text-bg-primary" : "text-bg-secondary";
}
private bool showDetail = false;
private Dictionary<string, string> DetailData = new Dictionary<string, string>();
private void showDetReq()
{
showDetail = true;
DetailData = new Dictionary<string, string>(TaskReq);
}
private void showDetRun()
{
showDetail = true;
DetailData = new Dictionary<string, string>(TaskRun);
}
private void showDetDone()
{
showDetail = true;
DetailData = new Dictionary<string, string>(TaskDone);
}
#region Private Properties
private string CssDivDetail
@@ -421,6 +470,18 @@ namespace LiMan.UI.Components
}
}
/// <summary>
/// Rilegge risultato task come obj specifici in area DONE...
/// </summary>
/// <returns></returns>
private async Task ReloadTaskResults()
{
if (TaskDone != null && TaskDone.Count > 0)
{
await Task.Delay(100);
}
}
#endregion Private Methods
}
}
+10 -11
View File
@@ -96,15 +96,7 @@
@if (HasFiltImpiego)
{
<div class="card shadow mt-2">
<div class="card-header">
@* <div class="d-flex justify-content-between">
<div class="px-1">
Dettaglio Inst.
</div>
<div class="px-1">
<button class="btn btn-light btn-sm" title="Click per chiudere dettaglio" @onclick="()=> CloseDetail()"><i class="fa-solid fa-xmark"></i></button>
</div>
</div> *@
<div class="card-header px-2">
<div class="py-0">
@foreach (var item in DetailFilt)
{
@@ -119,7 +111,7 @@
}
</div>
</div>
<div class="card-body px-1">
<div class="card-body px-2">
<div class="py-1">
<button class="btn w-100 btn-sm btn-primary" @onclick="() => SendTask(Core.Enum.EgwAccTask.ForceCheck)">Update App Info</button>
</div>
@@ -130,13 +122,20 @@
<button class="btn w-100 btn-sm btn-warning disabled" @onclick="() => SendTask(Core.Enum.EgwAccTask.OxyLicenseGet)">Update Info Licenza</button>
</div>
<div class="py-1">
<button class="btn w-100 btn-sm btn-danger disabled" @onclick="() => SendTask(Core.Enum.EgwAccTask.ForceUpdate)">Force Reboot</button>
<button class="btn w-100 btn-sm btn-danger" @onclick="() => SendTask(Core.Enum.EgwAccTask.ForceUpdate)">Force Reboot</button>
</div>
<div class="py-2">
<button class="btn w-100 btn-sm btn-success" @onclick="() => ResetTaskReq()">Reset Task Assegnati</button>
</div>
</div>
<div class="card-footer px-2">
<div class="btn-group w-100" role="group">
<button class="btn disabled btn-sm @BtnState(TaskReq.Count)">Req. <b>@TaskReq.Count</b></button>
<button class="btn disabled btn-sm @BtnState(TaskRun.Count)">Run. <b>@TaskRun.Count</b></button>
<button class="btn disabled btn-sm @BtnState(TaskDone.Count)">Done <b>@TaskDone.Count</b></button>
</div>
</div>
</div>
}
</div>
@@ -18,6 +18,7 @@ namespace LiMan.UI.Components
public void Dispose()
{
LMDService.EnrollMessPipe.EA_NewMessage -= async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
LMDService.TaskMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
MServ.EA_SelCodImp -= async () => await MServ_EA_SelCodImp();
MServ.EA_SelCodInst -= async () => await MServ_EA_SelCodInst();
}
@@ -61,6 +62,7 @@ namespace LiMan.UI.Components
protected override async Task OnInitializedAsync()
{
LMDService.EnrollMessPipe.EA_NewMessage += async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
LMDService.TaskMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
MServ.EA_SelCodImp += async () => await MServ_EA_SelCodImp();
MServ.EA_SelCodInst += async () => await MServ_EA_SelCodInst();
await ReloadLicData();
@@ -134,6 +136,64 @@ namespace LiMan.UI.Components
}
}
/// <summary>
/// Evento refresh legato a ricezione evento da MessagePipe
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async Task TaskMessPipe_EA_NewMessage(object sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// qualsiasi messaggio fa scattare reload data
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
// verifico se sia il cod impianto selezionato, nel faso forzo refreesh...
if (!string.IsNullOrEmpty(CodImpSel) && CodImpSel.Equals(currArgs.newMessage))
{
isLoading = true;
ReloadTaskStatus();
isLoading = false;
await InvokeAsync(StateHasChanged);
}
}
}
/// <summary>
/// Esegue update stato task
/// </summary>
private void ReloadTaskStatus()
{
TaskReq = new Dictionary<string, string>();
TaskRun = new Dictionary<string, string>();
TaskDone = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(CodImpSel))
{
TaskReq = LMDService.TaskReqGet(CodImpSel);
TaskRun = LMDService.TaskRunGet(CodImpSel);
TaskDone = LMDService.TaskDoneGet(CodImpSel);
}
}
private string BtnState(int numRec)
{
return numRec > 0 ? "btn-primary" : "btn-secondary";
}
/// <summary>
/// Lista Task in stato DONE
/// </summary>
private Dictionary<string, string> TaskDone = new Dictionary<string, string>();
/// <summary>
/// Lista Task in stato REQUESTED
/// </summary>
private Dictionary<string, string> TaskReq = new Dictionary<string, string>();
/// <summary>
/// Lista Task in stato RUNNING
/// </summary>
private Dictionary<string, string> TaskRun = new Dictionary<string, string>();
/// <summary>
/// Selezionato CodImp (PC)
/// </summary>
@@ -147,6 +207,7 @@ namespace LiMan.UI.Components
DetailFilt.Clear();
DetailFilt.Add("Cliente", MServ.UsrParamGet("Cliente"));
DetailFilt.Add("PC", MServ.UsrParamGet("PcInst"));
ReloadTaskStatus();
isLoading = false;
await InvokeAsync(StateHasChanged);
}
@@ -230,8 +291,14 @@ namespace LiMan.UI.Components
optPar = string.IsNullOrEmpty(optPar) ? $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}" : optPar;
// registro la richiesta
LMDService.TaskReqAdd(CodImpSel, reqTask, optPar);
// aggiorno stato...
ReloadTaskStatus();
// mando notifica con messageservice...
MServ.ReportTaskChange();
#if false
// invio string in messagepipe x forzare refresh...
LMDService.TaskMessPipe.sendMessage(CodImpSel);
#endif
}
}
+10 -4
View File
@@ -3,16 +3,22 @@
<table class="table table-sm table-striped table-responsive-lg small">
<thead>
<tr>
<th>Applicazioni Gestite</th>
<th>
Applicazione
<Sorter ParamName="CodApp" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter>
</th>
<th class="text-right">
Versione
<Sorter ParamName="VersNumInstall" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter>
</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecord)
{
<tr>
<td>
@item.CodApp
</td>
<td>@item.CodApp</td>
<td class="text-right small">@item.VersNumInstall</td>
</tr>
}
</tbody>
+80 -2
View File
@@ -1,7 +1,9 @@
using LiMan.DB.DTO;
using LiMan.UI.Data;
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.Linq;
using static EgwCoreLib.Razor.Sorter;
namespace LiMan.UI.Components
{
@@ -14,6 +16,13 @@ namespace LiMan.UI.Components
#endregion Public Properties
#region Protected Properties
[Inject]
protected MessageService MServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override void OnParametersSet()
@@ -35,6 +44,18 @@ namespace LiMan.UI.Components
isLoading = false;
}
protected void SortRequested(SortCallBack e)
{
isLoading = true;
if (sortField == e.ParamName)
{
sortAsc = e.IsAscending;
}
sortField = e.ParamName;
ReloadData();
isLoading = false;
}
#endregion Protected Methods
#region Private Fields
@@ -44,20 +65,77 @@ namespace LiMan.UI.Components
private List<AppRelStatusDTO> ListRecord = new List<AppRelStatusDTO>();
private int numRecord = 10;
private List<AppRelStatusDTO> SearchRecord = new List<AppRelStatusDTO>();
private string sKey = "ListAppShort";
private int totalCount = 0;
#endregion Private Fields
#region Private Properties
private bool sortAsc
{
get
{
bool answ = false;
var sVal = MServ.UsrParamGet($"{sKey}_sort");
if (!string.IsNullOrEmpty(sVal))
{
bool.TryParse(sVal, out answ);
}
return answ;
}
set => MServ.UsrParamSet($"{sKey}_sort", $"{value}");
}
private string sortField
{
get => MServ.UsrParamGet($"{sKey}_field");
set => MServ.UsrParamSet($"{sKey}_field", $"{value}");
}
#endregion Private Properties
#region Private Methods
private void ReloadData()
{
totalCount = AppList.Count;
SearchRecord = AppList
.OrderBy(x => x.CodApp)
.ToList();
totalCount = SearchRecord.Count;
// sistemo tabella
ListRecord = AppList
switch (sortField)
{
case "CodApp":
if (sortAsc)
{
SearchRecord = SearchRecord.OrderBy(x => x.CodApp).ThenByDescending(x => x.VersNumInstall).ToList();
}
else
{
SearchRecord = SearchRecord.OrderByDescending(x => x.CodApp).ThenByDescending(x => x.VersNumInstall).ToList();
}
break;
case "VersNumInstall":
if (sortAsc)
{
SearchRecord = SearchRecord.OrderBy(x => x.VersNumInstall).ThenByDescending(x => x.CodApp).ToList();
}
else
{
SearchRecord = SearchRecord.OrderByDescending(x => x.VersNumInstall).ThenByDescending(x => x.CodApp).ToList();
}
break;
default:
SearchRecord = SearchRecord
.OrderBy(x => x.CodApp)
.ThenByDescending(x => x.VersNumInstall)
.ToList();
break;
}
ListRecord = SearchRecord
.Skip((currPage - 1) * numRecord)
.Take(numRecord)
.ToList();
+6 -1
View File
@@ -53,7 +53,8 @@ namespace LiMan.UI.Data
};
// conf messagepipe: setup canali pub/sub
EnrollMessPipe = new MessagePipe(redisConn, Const.ENR_MSG_PIPE);
EnrollMessPipe = new MessagePipe(redisConn, Const.ENRL_MSG_PIPE);
TaskMessPipe = new MessagePipe(redisConn, Const.TASK_MSG_PIPE);
_emailSender = emailSender;
// conf cache
@@ -82,6 +83,10 @@ namespace LiMan.UI.Data
/// Wrapper x invio/ricezione messaggi sul canale dedicato agli eventi enroll
/// </summary>
public MessagePipe EnrollMessPipe { get; set; } = null!;
/// <summary>
/// Wrapper x invio/ricezione messaggi sul canale dedicato agli eventi Task
/// </summary>
public MessagePipe TaskMessPipe { get; set; } = null!;
#endregion Public Properties
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>2.1.2501.1717</Version>
<Version>2.1.2501.1814</Version>
<RootNamespace>LiMan.UI</RootNamespace>
<AssemblyName>LiMan.UI</AssemblyName>
</PropertyGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 2.1.2501.1717</h4>
<h4>Versione: 2.1.2501.1814</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
2.1.2501.1717
2.1.2501.1814
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>2.1.2501.1717</version>
<version>2.1.2501.1814</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>