Merge branch 'release/FixUpdatePipe_10'
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>License Manager</i>
|
||||
<h4>Versione: 2.1.2512.0319</h4>
|
||||
<h4>Versione: 2.1.2512.0409</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.1.2512.0319
|
||||
2.1.2512.0409
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>2.1.2512.0319</version>
|
||||
<version>2.1.2512.0409</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,6 +1,6 @@
|
||||
<body>
|
||||
<i>License Manager</i>
|
||||
<h4>Versione: 2.1.2512.0318</h4>
|
||||
<h4>Versione: 2.1.2512.0409</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.1.2512.0318
|
||||
2.1.2512.0409
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>2.1.2512.0318</version>
|
||||
<version>2.1.2512.0409</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>
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace LiMan.UI.Components
|
||||
public void Dispose()
|
||||
{
|
||||
LMDService.EnrollMessPipe.EA_NewMessage -= async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage -= async (sender, e) => await UpdActMessPipe_EA_NewMessage(sender, e);
|
||||
MServ.EA_SelCodImp -= async () => await MServ_EA_SelCodImp();
|
||||
MServ.EA_SelCodInst -= async () => await MServ_EA_SelCodInst();
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace LiMan.UI.Components
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
LMDService.EnrollMessPipe.EA_NewMessage += async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage += async (sender, e) => await UpdActMessPipe_EA_NewMessage(sender, e);
|
||||
MServ.EA_SelCodImp += async () => await MServ_EA_SelCodImp();
|
||||
MServ.EA_SelCodInst += async () => await MServ_EA_SelCodInst();
|
||||
await ReloadLicData();
|
||||
@@ -127,6 +127,11 @@ namespace LiMan.UI.Components
|
||||
/// </summary>
|
||||
private Dictionary<string, string> TaskRun = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Status degli udpater da mostrare
|
||||
/// </summary>
|
||||
private Core.Enum.UpdStatus UpdStatusReq = Core.Enum.UpdStatus.None;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
@@ -151,9 +156,8 @@ namespace LiMan.UI.Components
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
private Dictionary<string, DeviceDTO> ListDevices { get; set; } = new Dictionary<string, DeviceDTO>();
|
||||
private List<DeviceDTO> ListDev2Show { get; set; } = new List<DeviceDTO>();
|
||||
|
||||
private Dictionary<string, DeviceDTO> ListDevices { get; set; } = new Dictionary<string, DeviceDTO>();
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
@@ -164,6 +168,21 @@ namespace LiMan.UI.Components
|
||||
return numRec > 0 ? cssAct : "text-secondary";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// lancio richiesta udpate app info x ogni IMP gestito...
|
||||
/// </summary>
|
||||
private async Task DoMassiveRequest(Core.Enum.EgwAccTask reqType)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler inviare un comando di {reqType} a tutti i devices?"))
|
||||
return;
|
||||
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler proseguire? Verranno interesati {InfoStats.TotalUpdaterAct} devices."))
|
||||
return;
|
||||
|
||||
var listCodImp = InfoStats.InstDevices.Select(x => x.Value.CodImp).ToList();
|
||||
LMDService.TaskReqAdd(listCodImp, reqType, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe
|
||||
/// </summary>
|
||||
@@ -184,55 +203,6 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Status degli udpater da mostrare
|
||||
/// </summary>
|
||||
private Core.Enum.UpdStatus UpdStatusReq = Core.Enum.UpdStatus.None;
|
||||
|
||||
/// <summary>
|
||||
/// Imposta status visualizzazione dettaglio
|
||||
/// </summary>
|
||||
/// <param name="newStatus"></param>
|
||||
private async void ShowDetail(Core.Enum.UpdStatus newStatus)
|
||||
{
|
||||
UpdStatusReq = newStatus;
|
||||
ListDev2Show = new List<DeviceDTO>();
|
||||
Dictionary<string, string> dictCurr = new Dictionary<string, string>();
|
||||
switch (UpdStatusReq)
|
||||
{
|
||||
case Core.Enum.UpdStatus.Pending:
|
||||
dictCurr = TaskReq;
|
||||
break;
|
||||
case Core.Enum.UpdStatus.Running:
|
||||
dictCurr = TaskRun;
|
||||
break;
|
||||
case Core.Enum.UpdStatus.Done:
|
||||
dictCurr = TaskDone;
|
||||
break;
|
||||
case Core.Enum.UpdStatus.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// filtro x stato richiesto...
|
||||
List<DeviceDTO> list2show = new List<DeviceDTO>();
|
||||
foreach (var item in ListDevices)
|
||||
{
|
||||
if (dictCurr.ContainsKey(item.Key))
|
||||
{
|
||||
// sistemo dataora in obj...
|
||||
string rawDate = dictCurr[item.Key];
|
||||
if (DateTime.TryParse(rawDate, out var date))
|
||||
{
|
||||
item.Value.LastUpdate = date;
|
||||
}
|
||||
list2show.Add(item.Value);
|
||||
}
|
||||
}
|
||||
ListDev2Show = list2show;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Selezionato CodImp (PC)
|
||||
/// </summary>
|
||||
@@ -318,18 +288,49 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// lancio richiesta udpate app info x ogni IMP gestito...
|
||||
/// Imposta status visualizzazione dettaglio
|
||||
/// </summary>
|
||||
private async Task DoMassiveRequest(Core.Enum.EgwAccTask reqType)
|
||||
/// <param name="newStatus"></param>
|
||||
private async void ShowDetail(Core.Enum.UpdStatus newStatus)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler inviare un comando di {reqType} a tutti i devices?"))
|
||||
return;
|
||||
UpdStatusReq = newStatus;
|
||||
ListDev2Show = new List<DeviceDTO>();
|
||||
Dictionary<string, string> dictCurr = new Dictionary<string, string>();
|
||||
switch (UpdStatusReq)
|
||||
{
|
||||
case Core.Enum.UpdStatus.Pending:
|
||||
dictCurr = TaskReq;
|
||||
break;
|
||||
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler proseguire? Verranno interesati {InfoStats.TotalUpdaterAct} devices."))
|
||||
return;
|
||||
case Core.Enum.UpdStatus.Running:
|
||||
dictCurr = TaskRun;
|
||||
break;
|
||||
|
||||
var listCodImp = InfoStats.InstDevices.Select(x => x.Value.CodImp).ToList();
|
||||
LMDService.TaskReqAdd(listCodImp, reqType, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||
case Core.Enum.UpdStatus.Done:
|
||||
dictCurr = TaskDone;
|
||||
break;
|
||||
|
||||
case Core.Enum.UpdStatus.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// filtro x stato richiesto...
|
||||
List<DeviceDTO> list2show = new List<DeviceDTO>();
|
||||
foreach (var item in ListDevices)
|
||||
{
|
||||
if (dictCurr.ContainsKey(item.Key))
|
||||
{
|
||||
// sistemo dataora in obj...
|
||||
string rawDate = dictCurr[item.Key];
|
||||
if (DateTime.TryParse(rawDate, out var date))
|
||||
{
|
||||
item.Value.LastUpdate = date;
|
||||
}
|
||||
list2show.Add(item.Value);
|
||||
}
|
||||
}
|
||||
ListDev2Show = list2show;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -337,7 +338,7 @@ namespace LiMan.UI.Components
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private async Task TaskMessPipe_EA_NewMessage(object sender, EventArgs e)
|
||||
private async Task UpdActMessPipe_EA_NewMessage(object sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
// qualsiasi messaggio fa scattare reload data
|
||||
|
||||
@@ -32,13 +32,16 @@ namespace LiMan.UI.Components
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
LMDService.UpdActMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.TaskMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
protected List<AppRelStatusDTO> ListRecord { get; set; } = new List<AppRelStatusDTO>();
|
||||
|
||||
[Inject]
|
||||
@@ -51,34 +54,11 @@ namespace LiMan.UI.Components
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Registrazione richiesta update app remota
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task ProcReqUpdate(AppRelStatusDTO selRec)
|
||||
{
|
||||
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler forzare update applicativo {selRec.CodApp} sul Device? Eventuali configurazioni presenti saranno ripristinate, altrimenti andrà verificato manualmente l'esito dell'operazione."))
|
||||
return;
|
||||
|
||||
// invio task update applicazione
|
||||
LMDService.TaskReqAdd(CodImpSel, EgwAccTask.TargetAppUpdate, selRec.CodApp);
|
||||
ReloadTaskStatus();
|
||||
ReloadTaskResults();
|
||||
// invio notifica update...
|
||||
LMDService.UpdActMessPipe.sendMessage(selRec.CodApp);
|
||||
}
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
LMDService.UpdActMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.TaskMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
@@ -378,6 +358,24 @@ namespace LiMan.UI.Components
|
||||
ReloadTaskResults();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registrazione richiesta update app remota
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task ProcReqUpdate(AppRelStatusDTO selRec)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler forzare update applicativo {selRec.CodApp} sul Device? Eventuali configurazioni presenti saranno ripristinate, altrimenti andrà verificato manualmente l'esito dell'operazione."))
|
||||
return;
|
||||
|
||||
// invio task update applicazione
|
||||
LMDService.TaskReqAdd(CodImpSel, EgwAccTask.TargetAppUpdate, selRec.CodApp);
|
||||
ReloadTaskStatus();
|
||||
ReloadTaskResults();
|
||||
// invio notifica update...
|
||||
LMDService.UpdActMessPipe.sendMessage(selRec.CodApp);
|
||||
}
|
||||
|
||||
private void ReloadCharts()
|
||||
{
|
||||
// sistemo info x grafico... se ho impieghi uso quello, altrimenti istanze...
|
||||
@@ -488,7 +486,7 @@ namespace LiMan.UI.Components
|
||||
default:
|
||||
SearchRecord = SearchRecord
|
||||
.OrderByDescending(x => x.VersNumInstall)
|
||||
.ThenBy(x=>x.CodInst)
|
||||
.ThenBy(x => x.CodInst)
|
||||
.ThenBy(x => x.PcInst)
|
||||
.ToList();
|
||||
break;
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
using Core.Models;
|
||||
using LiMan.DB;
|
||||
using LiMan.DB.DBModels;
|
||||
using LiMan.DB.DTO;
|
||||
using LiMan.UI.Data;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ZXing.OneD;
|
||||
using static Core.Enum;
|
||||
|
||||
namespace LiMan.UI.Components
|
||||
@@ -22,7 +19,8 @@ namespace LiMan.UI.Components
|
||||
public void Dispose()
|
||||
{
|
||||
LMDService.EnrollMessPipe.EA_NewMessage -= async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.TaskMessPipe.EA_NewMessage -= async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage -= async (sender, e) => await UpdActMessPipe_EA_NewMessage(sender, e);
|
||||
MServ.EA_SelCodApp -= async () => await MServ_EA_SelCodApp();
|
||||
MServ.EA_SelCodImp -= async () => await MServ_EA_SelCodImp();
|
||||
MServ.EA_SelCodInst -= async () => await MServ_EA_SelCodInst();
|
||||
@@ -97,7 +95,8 @@ namespace LiMan.UI.Components
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
LMDService.EnrollMessPipe.EA_NewMessage += async (sender, e) => await EnrollMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.TaskMessPipe.EA_NewMessage += async (sender, e) => await TaskMessPipe_EA_NewMessage(sender, e);
|
||||
LMDService.UpdActMessPipe.EA_NewMessage += async (sender, e) => await UpdActMessPipe_EA_NewMessage(sender, e);
|
||||
MServ.EA_SelCodApp += async () => await MServ_EA_SelCodApp();
|
||||
MServ.EA_SelCodImp += async () => await MServ_EA_SelCodImp();
|
||||
MServ.EA_SelCodInst += async () => await MServ_EA_SelCodInst();
|
||||
@@ -111,6 +110,12 @@ namespace LiMan.UI.Components
|
||||
|
||||
private string CodDeviceSel = "";
|
||||
private string codInstSel = "";
|
||||
|
||||
/// <summary>
|
||||
/// Secondi di debounce x evitare reload continui
|
||||
/// </summary>
|
||||
private int debounceSec = 5;
|
||||
|
||||
private Dictionary<string, string> DetailFilt = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
@@ -120,6 +125,12 @@ namespace LiMan.UI.Components
|
||||
|
||||
private bool HasFiltClienti = false;
|
||||
private bool HasFiltImpiego = false;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultimo reload
|
||||
/// </summary>
|
||||
private DateTime lastReload = DateTime.Now;
|
||||
|
||||
private List<InstallazioneModel> ListInstall;
|
||||
|
||||
/// <summary>
|
||||
@@ -205,7 +216,7 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe di Enroll
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
@@ -224,8 +235,6 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Selezionato CodApp (Singola app, molti PC)
|
||||
/// </summary>
|
||||
@@ -397,7 +406,6 @@ namespace LiMan.UI.Components
|
||||
/// <param name="optPar">Parametri opzionali x svolgiimento</param>
|
||||
private async Task SendTask(EgwAccTask reqTask, string optPar = "")
|
||||
{
|
||||
|
||||
// se parametro vuoto metto dataora...
|
||||
optPar = string.IsNullOrEmpty(optPar) ? $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}" : optPar;
|
||||
if (!string.IsNullOrEmpty(CodImpSel))
|
||||
@@ -429,24 +437,17 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe TASK
|
||||
/// </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
|
||||
// qualsiasi messaggio TASK fa scattare...
|
||||
if (!string.IsNullOrEmpty(currArgs.newMessage))
|
||||
{
|
||||
isLoading = true;
|
||||
InfoStats = null;
|
||||
#if false
|
||||
// svuoto cache preliminarmente
|
||||
await LMDService.ResetInstallStatus();
|
||||
#endif
|
||||
await ReloadLicData();
|
||||
await ReloadData();
|
||||
ReloadTaskStatus();
|
||||
isLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
@@ -473,6 +474,30 @@ namespace LiMan.UI.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evento refresh legato a ricezione evento da MessagePipe Update
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private async Task UpdActMessPipe_EA_NewMessage(object sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
DateTime adesso = DateTime.Now;
|
||||
// qualsiasi messaggio (dopo debounceSec sec dal precedente) fa scattare reload data
|
||||
if (!string.IsNullOrEmpty(currArgs.newMessage) && adesso.Subtract(lastReload).TotalSeconds > debounceSec)
|
||||
{
|
||||
lastReload = adesso;
|
||||
isLoading = true;
|
||||
#if false
|
||||
InfoStats = null;
|
||||
#endif
|
||||
await ReloadLicData();
|
||||
await ReloadData();
|
||||
isLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>2.1.2512.0318</Version>
|
||||
<Version>2.1.2512.0409</Version>
|
||||
<RootNamespace>LiMan.UI</RootNamespace>
|
||||
<AssemblyName>LiMan.UI</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>License Manager</i>
|
||||
<h4>Versione: 2.1.2512.0318</h4>
|
||||
<h4>Versione: 2.1.2512.0409</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.1.2512.0318
|
||||
2.1.2512.0409
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>2.1.2512.0318</version>
|
||||
<version>2.1.2512.0409</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>
|
||||
|
||||
Reference in New Issue
Block a user