Merge branch 'Release/SpecAddOdlFolder03'
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.AppAuth.DTO
|
||||
{
|
||||
|
||||
public class UploadResult
|
||||
{
|
||||
public bool Uploaded { get; set; }
|
||||
public string FileName { get; set; } = "";
|
||||
public string StoredFileName { get; set; } = "";
|
||||
public int ErrorCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.AppAuth
|
||||
{
|
||||
public class MeasureUtils
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
public static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Calcola dimensione file automaticamwente secondo dimensione
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="decimalPlaces"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public static string SizeSuffix(Int64 value, int decimalPlaces = 1)
|
||||
{
|
||||
if (decimalPlaces < 0) { throw new ArgumentOutOfRangeException("decimalPlaces"); }
|
||||
if (value < 0) { return "-" + SizeSuffix(-value, decimalPlaces); }
|
||||
if (value == 0) { return string.Format("{0:n" + decimalPlaces + "} bytes", 0); }
|
||||
|
||||
// mag is 0 for bytes, 1 for KB, 2, for MB, etc.
|
||||
int mag = (int)Math.Log(value, 1024);
|
||||
|
||||
// 1L << (mag * 10) == 2 ^ (10 * mag) [i.e. the number of bytes in the unit
|
||||
// corresponding to mag]
|
||||
decimal adjustedSize = (decimal)value / (1L << (mag * 10));
|
||||
|
||||
// make adjustment when the value is large enough that it would round up to 1000 or more
|
||||
if (Math.Round(adjustedSize, decimalPlaces) >= 1000)
|
||||
{
|
||||
mag += 1;
|
||||
adjustedSize /= 1024;
|
||||
}
|
||||
|
||||
return string.Format("{0:n" + decimalPlaces + "} {1}",
|
||||
adjustedSize,
|
||||
SizeSuffixes[mag]);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2408.2710" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2409.2607" />
|
||||
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Common" Version="6.0.33" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.33" />
|
||||
@@ -33,7 +33,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.19.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.3.3" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
|
||||
<PackageReference Include="NLog" Version="5.3.4" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.12" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+128
-37
@@ -2,37 +2,55 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MP.AppAuth.DTO;
|
||||
using MP.AppAuth.Models;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using static Egw.Core.LiManObj;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace MP.Land.Data
|
||||
{
|
||||
public class SyncService
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Init classe
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="logger"></param>
|
||||
public SyncService(IConfiguration configuration, ILogger<LicenseService> logger)
|
||||
public SyncService(IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private static ILogger<LicenseService> _logger { get; set; } = null!;
|
||||
private static IConfiguration? _configuration;
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public List<AnagKeyValueModel> AKVList { get; set; } = new List<AnagKeyValueModel>();
|
||||
public string Applicazione { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// URL dell'API x chiamate gestione licenze
|
||||
/// Codice cliente/installazione
|
||||
/// </summary>
|
||||
private static string apiUrl = "https://liman.egalware.com/ELM.API/";
|
||||
public string Installazione { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Master key licenza principale
|
||||
/// </summary>
|
||||
public string MasterKey { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Stato server gestione licenze
|
||||
@@ -55,30 +73,7 @@ namespace MP.Land.Data
|
||||
}
|
||||
return await Task.FromResult(answ);
|
||||
}
|
||||
public List<AnagKeyValueModel> AKVList { get; set; } = new List<AnagKeyValueModel>();
|
||||
public string Applicazione { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Codice cliente/installazione
|
||||
/// </summary>
|
||||
public string Installazione { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore string da elenco AKV
|
||||
/// </summary>
|
||||
/// <param name="varReq">Chiave AKV richiesta</param>
|
||||
/// <returns></returns>
|
||||
protected string getAVKStr(string varReq)
|
||||
{
|
||||
string answ = "";
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
answ = $"{currRec.ValString}";
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init della classe con variabili di base da Redis/DB
|
||||
/// </summary>
|
||||
@@ -92,11 +87,6 @@ namespace MP.Land.Data
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Master key licenza principale
|
||||
/// </summary>
|
||||
public string MasterKey { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Lista record AnagKeyVal
|
||||
/// </summary>
|
||||
@@ -159,5 +149,106 @@ namespace MP.Land.Data
|
||||
}
|
||||
return await Task.FromResult(answ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invio file zip di backup al server centrale
|
||||
/// </summary>
|
||||
/// <param name="CodApp">Cod Applicazione</param>
|
||||
/// <param name="CodInst">CLiente / Installazione</param>
|
||||
/// <param name="DoUnzip">Invia richiesta UnZip</param>
|
||||
/// <param name="ForceApprov">Invia richiesta Approvazione</param>
|
||||
/// <param name="ZipFile">ZipFile da inviare</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> SendZipFile(string CodApp, string CodInst, bool DoUnzip, bool ForceApprov, FileInfo ZipFile)
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
// client chiamate rest
|
||||
var client = new RestClient(restOptStd);
|
||||
// Chiamo il metodo!
|
||||
var actReq = new RestRequest($"/api/filesave/zipbackup", Method.Post);
|
||||
actReq.AddParameter("CodApp", $"{CodApp}");
|
||||
actReq.AddParameter("CodInst", $"{CodInst}");
|
||||
actReq.AddParameter("DoUnzip", $"{DoUnzip}");
|
||||
actReq.AddParameter("ForceApprov", $"{ForceApprov}");
|
||||
actReq.AddFile("ZipFile", ZipFile.FullName);
|
||||
actReq.AddHeader("Content-Type", "multipart/form-data");
|
||||
// effettuo vera chiamata
|
||||
var currResp = await client.ExecuteAsync(actReq);
|
||||
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
||||
{
|
||||
// mi restituisce esito upload
|
||||
var currList = JsonConvert.DeserializeObject<List<UploadResult>>(currResp.Content);
|
||||
if (currList != null)
|
||||
{
|
||||
// se contiene anche la richiesta è ok...
|
||||
var recUpd = currList.FirstOrDefault(x => x.FileName == ZipFile.Name);
|
||||
if (recUpd != null)
|
||||
{
|
||||
answ = recUpd.Uploaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in fase gestione REST services SendZipFile{Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore string da elenco AKV
|
||||
/// </summary>
|
||||
/// <param name="varReq">Chiave AKV richiesta</param>
|
||||
/// <returns></returns>
|
||||
protected string getAVKStr(string varReq)
|
||||
{
|
||||
string answ = "";
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
answ = $"{currRec.ValString}";
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration? _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// URL dell'API x chiamate gestione licenze
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
private static string apiUrl = "https://localhost:5003/";
|
||||
#else
|
||||
private static string apiUrl = "https://liman.egalware.com/ELM.API/";
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Classe logger
|
||||
/// </summary>
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Conf client RestSharp standard:
|
||||
/// - base URI al sito
|
||||
/// - timeout 1 min
|
||||
/// </summary>
|
||||
private static RestClientOptions restOptStd = new RestClientOptions { Timeout = TimeSpan.FromSeconds(60), BaseUrl = new Uri(apiUrl) };
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>MP.Land</RootNamespace>
|
||||
<Version>6.16.2409.1212</Version>
|
||||
<Version>6.16.2410.1815</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -55,6 +55,7 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.12" />
|
||||
<PackageReference Include="RestSharp" Version="112.0.0" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.12" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -63,9 +64,15 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="logs\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="post-build.ps1">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="temp\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
@page "/About"
|
||||
@using MP.Land.Data
|
||||
|
||||
@inject MessageService AppMService
|
||||
@inject LicenseService LicServ
|
||||
|
||||
<div class="row mx-2">
|
||||
<div class="col-12 col-xl-10 offset-xl-1">
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MP.Land.Data;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.Land.Pages
|
||||
{
|
||||
public partial class About
|
||||
{
|
||||
|
||||
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMService { get; set; } = null!;
|
||||
[Inject]
|
||||
protected LicenseService LicServ{get;set;}=null!;
|
||||
#region Protected Methods
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
||||
@@ -14,22 +14,23 @@
|
||||
<p>Scaricare uno o più pacchetti selezionando dall'elenco riportato.</p>
|
||||
</div>
|
||||
<div class="col-12 col-md-3 text-center">
|
||||
<button class="btn btn-primary w-100" @onclick="() => UploadBackupConfig()"><i class="fas fa-upload"></i> Upload Config Backup <i class="fas fa-upload"></i></button>
|
||||
<div class="h2">
|
||||
ALL Packages <i class="fas fa-download"></i>
|
||||
ALL Packages
|
||||
</div>
|
||||
<button class="btn btn-success w-100" @onclick="() => DownloadAll()">Download ALL Latest</button>
|
||||
<button class="btn btn-success w-100" @onclick="() => DownloadAll()"> <i class="fas fa-download"></i> Download ALL Latest <i class="fas fa-download"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (showUpdate)
|
||||
{
|
||||
<div class="alert alert-success alert-dismissible fade show">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<button type="button" class="btn-close" @onclick="CloseProgUpdate"></button>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
@outMessages
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div class="px-0" style="min-width: 20rem;">
|
||||
@if (showProgress)
|
||||
{
|
||||
<div class="progress">
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.AppAuth;
|
||||
using MP.Land.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.Land.Pages
|
||||
@@ -14,6 +19,32 @@ namespace MP.Land.Pages
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Procedura di aggiunta folder a ZipFile, ricorsiva
|
||||
/// </summary>
|
||||
/// <param name="f"></param>
|
||||
/// <param name="root"></param>
|
||||
/// <param name="folder"></param>
|
||||
public void AddFolderToZip(ZipFile f, string root, string folder)
|
||||
{
|
||||
string relative = folder.Substring(root.Length);
|
||||
if (relative.Length > 0)
|
||||
{
|
||||
f.AddDirectory(relative);
|
||||
}
|
||||
|
||||
foreach (string file in Directory.GetFiles(folder))
|
||||
{
|
||||
relative = file.Substring(root.Length);
|
||||
f.Add(file, relative);
|
||||
}
|
||||
|
||||
foreach (string subFolder in Directory.GetDirectories(folder))
|
||||
{
|
||||
this.AddFolderToZip(f, root, subFolder);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ListRecords = null;
|
||||
@@ -30,7 +61,7 @@ namespace MP.Land.Pages
|
||||
|
||||
protected int totalCount = 0;
|
||||
|
||||
protected double TotalMb = 0;
|
||||
protected long TotalMb = 0;
|
||||
|
||||
protected UpdateMan updateManAuth = new UpdateMan("SWDownloader", "viaD@nte16");
|
||||
|
||||
@@ -55,10 +86,28 @@ namespace MP.Land.Pages
|
||||
protected bool showProgress { get; set; } = false;
|
||||
protected bool showUpdate { get; set; } = false;
|
||||
|
||||
[Inject]
|
||||
protected SyncService SyncServ { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce size calcolata
|
||||
/// </summary>
|
||||
/// <param name="origSize"></param>
|
||||
/// <returns></returns>
|
||||
protected string CalcSize(long origSize)
|
||||
{
|
||||
return MeasureUtils.SizeSuffix(origSize, 1);
|
||||
}
|
||||
|
||||
protected void CloseProgUpdate()
|
||||
{
|
||||
showUpdate = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cicla su tutti i record ed effettua il download
|
||||
/// </summary>
|
||||
@@ -68,7 +117,7 @@ namespace MP.Land.Pages
|
||||
showProgress = true;
|
||||
showUpdate = true;
|
||||
outMessages = $"Iniziato download per {numTot} packages";
|
||||
StateHasChanged();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
percLoading = 0;
|
||||
TotalMb = 0;
|
||||
numDone = 0;
|
||||
@@ -90,20 +139,16 @@ namespace MP.Land.Pages
|
||||
numTot = authList.Count;
|
||||
foreach (var item in authList)
|
||||
{
|
||||
long size = 0;
|
||||
size = await scaricaSingolo(item);
|
||||
TotalMb += (double)size / (1024 * 1024);
|
||||
outMessages = $"Scaricati {numDone}/{numTot} packages | {TotalMb:N2} Mb";
|
||||
StateHasChanged();
|
||||
await Task.Delay(1);
|
||||
ScaricaSingolo(item);
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
outMessages = $"Effettuato download di {numDone} update | {TotalMb:N2} Mb in {ts.TotalSeconds:N2} s";
|
||||
StateHasChanged();
|
||||
outMessages = $"Effettuato download di {numDone} update | {CalcSize(TotalMb)} in {ts.TotalSeconds:N2} s";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Delay(1000);
|
||||
showProgress = false;
|
||||
StateHasChanged();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
protected string localPath(string localRepo)
|
||||
@@ -130,6 +175,66 @@ namespace MP.Land.Pages
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cicla su tutti i record applicativi, crea ZIP cifrato + upload su LiMan
|
||||
/// </summary>
|
||||
protected async Task UploadBackupConfig()
|
||||
{
|
||||
// init progress...
|
||||
showProgress = true;
|
||||
showUpdate = true;
|
||||
outMessages = $"Inizio preparazione per upload configurazioni di {numTot} packages";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
percLoading = 0;
|
||||
TotalMb = 0;
|
||||
numDone = 0;
|
||||
int numIOB = 0;
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
// ciclo su tutti quelli con licenza valida...
|
||||
List<AppAuth.Models.UpdMan> rawList = ListRecords
|
||||
.Where(x => !string.IsNullOrEmpty(x.LicenseKey)).ToList();
|
||||
List<AppAuth.Models.UpdMan> authList = new List<AppAuth.Models.UpdMan>();
|
||||
|
||||
// ciclo SOLO tra quelli davvero autorizzati...
|
||||
foreach (var item in rawList)
|
||||
{
|
||||
if (LicServ.checkLicenseActive(item.LicenseKey))
|
||||
{
|
||||
authList.Add(item);
|
||||
}
|
||||
}
|
||||
// numero app + IOB + DB + ZIP
|
||||
numTot = authList.Count + 3;
|
||||
|
||||
// recupero conf files
|
||||
foreach (var item in authList)
|
||||
{
|
||||
// cerco i file di conf e li copio
|
||||
RecuperaConf(item);
|
||||
await Task.Delay(10);
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
// recupero i file IOB
|
||||
RecuperaIobConf();
|
||||
// salvo Tab Db come json
|
||||
SaveDbConfAsJson();
|
||||
|
||||
// ora creo il file zip
|
||||
PrepareZip();
|
||||
// effettuo upload
|
||||
await UploadZip();
|
||||
|
||||
// concludo!
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
outMessages = $"Effettuato Upload backup configurazioni per {numDone} app + {numIOB} IOB | {CalcSize(TotalMb)} | {ts.TotalSeconds:N2} s";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Delay(1000);
|
||||
showProgress = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
@@ -138,9 +243,165 @@ namespace MP.Land.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private DirectoryInfo AppDir => new DirectoryInfo(Path.Combine("\\\\iis01.egalware.com", "c$\\inetpub\\wwwroot\\MP\\LAND"));
|
||||
#else
|
||||
private DirectoryInfo AppDir => new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Nome del file ZIP da gestire
|
||||
/// </summary>
|
||||
private string zFileName => Path.Combine(AppDir.FullName, "temp", "zip", "MAPO.zip");
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task<long> scaricaSingolo(AppAuth.Models.UpdMan item)
|
||||
/// <summary>
|
||||
/// Preparazione ZIP con password = AuthKey
|
||||
/// </summary>
|
||||
private void PrepareZip()
|
||||
{
|
||||
string srcPath = Path.Combine(AppDir.FullName, "temp", "orig");
|
||||
string destPath = Path.Combine(AppDir.FullName, "temp", "zip");
|
||||
if (!Directory.Exists(destPath))
|
||||
{
|
||||
Directory.CreateDirectory(destPath);
|
||||
}
|
||||
using (ZipFile zipFile = ZipFile.Create(zFileName))
|
||||
{
|
||||
zipFile.Password = LicServ.MasterKey;
|
||||
zipFile.BeginUpdate();
|
||||
AddFolderToZip(zipFile, srcPath, srcPath);
|
||||
zipFile.CommitUpdate();
|
||||
zipFile.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera fdile di conf da app indicata
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void RecuperaConf(AppAuth.Models.UpdMan item)
|
||||
{
|
||||
long size = 0;
|
||||
if (item.IsAuth)
|
||||
{
|
||||
string dstDir = Path.Combine(AppDir.FullName, "temp", "orig", item.PackName);
|
||||
if (!Directory.Exists(dstDir))
|
||||
{
|
||||
Directory.CreateDirectory(dstDir);
|
||||
}
|
||||
string srcDir = Path.Combine(AppDir.Parent.FullName, item.PackName);
|
||||
// recupero elenco files tipo appsettings*.json
|
||||
if (Directory.Exists(srcDir))
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(srcDir);
|
||||
// recupero files CORE
|
||||
List<FileInfo> fileList = dirInfo.GetFiles("appsettings*.json").ToList();
|
||||
// recupero files Framework
|
||||
List<FileInfo> fileListFram = dirInfo.GetFiles("web*.config").ToList();
|
||||
// merge...
|
||||
foreach (var fileFrm in fileListFram)
|
||||
{
|
||||
fileList.Add(fileFrm);
|
||||
}
|
||||
// procedo!
|
||||
foreach (var file in fileList)
|
||||
{
|
||||
string fileDestPath = Path.Combine(dstDir, file.Name);
|
||||
file.CopyTo(fileDestPath, true);
|
||||
size += file.Length;
|
||||
}
|
||||
numDone++;
|
||||
percLoading = 100 * numDone / numTot;
|
||||
TotalMb += size;
|
||||
outMessages = $"Configurazioni preparate: {numDone}/{numTot} | {CalcSize(TotalMb)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// recupera tutte le conf IOB trasferite all'MP-IO dai vari IOB-WIN
|
||||
/// </summary>
|
||||
private void RecuperaIobConf()
|
||||
{
|
||||
long size = 0;
|
||||
|
||||
string dstDir = Path.Combine(AppDir.FullName, "temp", "orig", "IOB");
|
||||
if (!Directory.Exists(dstDir))
|
||||
{
|
||||
Directory.CreateDirectory(dstDir);
|
||||
}
|
||||
string srcIobDir = Path.Combine(AppDir.Parent.FullName, "IO", "fileUpload");
|
||||
// recupero elenco files tipo appsettings*.json
|
||||
if (Directory.Exists(srcIobDir))
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(srcIobDir);
|
||||
// recupero files CORE
|
||||
List<FileInfo> fileList = dirInfo.GetFiles().ToList();
|
||||
// procedo!
|
||||
foreach (var file in fileList)
|
||||
{
|
||||
string fileDestPath = Path.Combine(dstDir, file.Name);
|
||||
file.CopyTo(fileDestPath, true);
|
||||
size += file.Length;
|
||||
}
|
||||
numDone++;
|
||||
percLoading = 100 * numDone / numTot;
|
||||
TotalMb += size;
|
||||
outMessages = $"Configurazioni preparate: {numDone}/{numTot} | {CalcSize(TotalMb)}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio tabelle di configurazione specifica come tracciati json
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void SaveDbConfAsJson()
|
||||
{
|
||||
long size = 0;
|
||||
|
||||
string dstDir = Path.Combine(AppDir.FullName, "temp", "orig", "DB");
|
||||
if (!Directory.Exists(dstDir))
|
||||
{
|
||||
Directory.CreateDirectory(dstDir);
|
||||
}
|
||||
// va fatta 1:1 per ogni tabella
|
||||
|
||||
#if false
|
||||
string srcIobDir = Path.Combine(AppDir.Parent.FullName, "IO", "fileUpload");
|
||||
// recupero elenco files tipo appsettings*.json
|
||||
if (Directory.Exists(srcIobDir))
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(srcIobDir);
|
||||
// recupero files CORE
|
||||
List<FileInfo> fileList = dirInfo.GetFiles().ToList();
|
||||
// procedo!
|
||||
foreach (var file in fileList)
|
||||
{
|
||||
string fileDestPath = Path.Combine(dstDir, file.Name);
|
||||
file.CopyTo(fileDestPath, true);
|
||||
size += file.Length;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
numDone++;
|
||||
percLoading = 100 * numDone / numTot;
|
||||
TotalMb += size;
|
||||
outMessages = $"Configurazioni preparate: {numDone}/{numTot} | {CalcSize(TotalMb)}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua download di una singola app
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void ScaricaSingolo(AppAuth.Models.UpdMan item)
|
||||
{
|
||||
long size = 0;
|
||||
if (item.IsAuth)
|
||||
@@ -153,7 +414,21 @@ namespace MP.Land.Pages
|
||||
}
|
||||
numDone++;
|
||||
percLoading = 100 * numDone / numTot;
|
||||
return await Task.FromResult(size);
|
||||
TotalMb += size;
|
||||
outMessages = $"Scaricati {numDone}/{numTot} packages | {CalcSize(TotalMb)}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invio zip al server LiMan remoto
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private async Task<bool> UploadZip()
|
||||
{
|
||||
// chiamo SendZipFile di SyncService...
|
||||
FileInfo zFileInfo = new FileInfo(zFileName);
|
||||
var fatto = await SyncServ.SendZipFile(LicServ.Applicazione, LicServ.Installazione, true, false, zFileInfo);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo Tablet MAPO - DotNet6</i>
|
||||
<h4>Versione: 6.16.2409.1212</h4>
|
||||
<h4>Versione: 6.16.2410.1815</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2409.1212
|
||||
6.16.2410.1815
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2409.1212</version>
|
||||
<version>6.16.2410.1815</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -199,123 +199,12 @@ else
|
||||
<div class="modal-body col-12">
|
||||
@if (statRecord != null && showStats)
|
||||
{
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="col-8">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 270px">
|
||||
<div class="small textConsensed"><b>N° pezzi:</b> @statRecord.NumPezzi</div>
|
||||
<div class="small textConsensed"><b>T. Ciclo:</b> @statRecord.Tcassegnato.ToString("N3")</div>
|
||||
</td>
|
||||
<td style="width: 300px">
|
||||
<div class="small d-flex justify-content-between">
|
||||
<div>
|
||||
<div><b>@($"{@statRecord.DataInizio:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataInizio:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
<div class="p-0">
|
||||
<i class="fa-solid fa-angles-right"></i>
|
||||
</div>
|
||||
<div>
|
||||
@if (@statRecord.DataFine != null)
|
||||
{
|
||||
<div><b>@($"{@statRecord.DataFine:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataFine:ddd HH:mm:ss}")</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-secondary">
|
||||
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
@tradFase(statRecord.KeyRichiesta)
|
||||
</div>
|
||||
@if (statRecord.Note != "")
|
||||
{
|
||||
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
|
||||
<b class="text-dark"></b> <span class="text-wrap text-start"> @statRecord.Note </span>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-text">
|
||||
<span class="me-1 @leftStringCSS">Tutti gli Stati</span>
|
||||
<span class="form-check form-check-sm form-switch py-1" title="Mostra/Nascondi macchina spenta">
|
||||
<input class="form-check-input" type="checkbox" id="switchSpenta" @onchange="() => toggleSpenta()" value="@hideSpenta">
|
||||
</span>
|
||||
<span class="@rightStringCSS">Nascondi Spenta</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
@if (statRecord != null)
|
||||
{
|
||||
@if (ListOdlStatsAct != null)
|
||||
{
|
||||
@foreach (var stat in ListOdlStatsAct)
|
||||
{
|
||||
<div class="p-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-uppercase">
|
||||
@stat.Descrizione
|
||||
</div>
|
||||
<div>
|
||||
<b>@(formDurata(stat.TotDurata))</b>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar @colorChanger(@stat.Css)" role="progressbar" aria-valuenow="0" aria-valuemin="0" style="width: @Math.Round(calcolaPerc(stat.TotDurata),0)%; background-color:@pbStyle(@stat.Css);" aria-valuemax="100">@($"{calcolaPerc(stat.TotDurata):N1}%")</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 dcContainer">
|
||||
@if (statRecord != null && ListOdlStats != null)
|
||||
{
|
||||
<div class="dcBox">
|
||||
<ODLPlot SelectedOdl="@statRecord.IdxOdl" hideSpenta="@hideSpenta"></ODLPlot>
|
||||
</div>
|
||||
<div class="dcBox dcOverlay d-flex">
|
||||
<div class="align-self-center text-center w-100">
|
||||
<b class="fs-3">@durataFilt</b>
|
||||
@*<b class="fs-3">@statRecord.DurataMinuti</b>*@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<StatsOdl ListOdlStats="@ListOdlStats" ListStati="@ListStati" statRecord="@statRecord"></StatsOdl>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="odlDirModal" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-xl">
|
||||
<div class="modal-content">
|
||||
|
||||
@@ -49,16 +49,10 @@ namespace MP.SPEC.Components
|
||||
ListRecords = null;
|
||||
ListStati = null;
|
||||
ListOdlStats = null;
|
||||
ListOdlStatsNetto = null;
|
||||
statRecord = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public string formDurata(double durataMin)
|
||||
{
|
||||
return MP.Data.Utils.FormDurata(durataMin);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
@@ -108,16 +102,6 @@ namespace MP.SPEC.Components
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected string colorChanger(string colorCSS)
|
||||
{
|
||||
string answ = "";
|
||||
if (colorCSS == "yellow")
|
||||
{
|
||||
answ = "text-dark";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Richiesta invio sync all'IOB-WIN
|
||||
/// </summary>
|
||||
@@ -224,6 +208,16 @@ namespace MP.SPEC.Components
|
||||
browseRecord = currRec;
|
||||
}
|
||||
|
||||
protected async Task selRecord(ODLExpModel? currRec)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
browseRecord = null;
|
||||
selDtFine = DateTime.Now;
|
||||
currRecord = currRec;
|
||||
showStats = false;
|
||||
ListOdlStats = null;
|
||||
}
|
||||
|
||||
protected async Task selStatRecord(ODLExpModel? currRec)
|
||||
{
|
||||
browseRecord = null;
|
||||
@@ -242,27 +236,6 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task selRecord(ODLExpModel? currRec)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
browseRecord = null;
|
||||
selDtFine = DateTime.Now;
|
||||
currRecord = currRec;
|
||||
showStats = false;
|
||||
ListOdlStats = null;
|
||||
ListOdlStatsNetto = null;
|
||||
}
|
||||
|
||||
protected async Task toggleSpenta()
|
||||
{
|
||||
hideSpenta = !hideSpenta;
|
||||
await Task.Delay(1);
|
||||
if (statRecord != null)
|
||||
{
|
||||
await reloadStatsData(statRecord);
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task UpdateData()
|
||||
{
|
||||
await selRecord(null);
|
||||
@@ -285,8 +258,6 @@ namespace MP.SPEC.Components
|
||||
|
||||
private List<StatODLModel>? ListOdlStats;
|
||||
|
||||
private List<StatODLModel>? ListOdlStatsNetto;
|
||||
|
||||
private List<ODLExpModel>? ListRecords;
|
||||
|
||||
private List<ListValues>? ListStati;
|
||||
@@ -307,39 +278,6 @@ namespace MP.SPEC.Components
|
||||
set => currFilter.CurrPage = value;
|
||||
}
|
||||
|
||||
private string durataFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "ND";
|
||||
if (statRecord != null)
|
||||
{
|
||||
if (hideSpenta)
|
||||
{
|
||||
if (ListOdlStatsNetto != null)
|
||||
{
|
||||
var tsDurata = TimeSpan.FromMinutes(ListOdlStatsNetto.Sum(x => x.TotDurata));
|
||||
if (tsDurata.TotalDays < 1)
|
||||
{
|
||||
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = statRecord.DurataMinuti;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
private bool hideSpenta { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Indica se si tratti di ODL correnti
|
||||
/// </summary>
|
||||
@@ -350,39 +288,12 @@ namespace MP.SPEC.Components
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private string leftStringCSS
|
||||
{
|
||||
get => hideSpenta ? "text-secondary" : "text-dark fw-bold";
|
||||
}
|
||||
|
||||
private List<StatODLModel>? ListOdlStatsAct
|
||||
{
|
||||
get
|
||||
{
|
||||
List<StatODLModel>? answ = new List<StatODLModel>();
|
||||
if (hideSpenta)
|
||||
{
|
||||
answ = ListOdlStatsNetto;
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListOdlStats;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
private int numRecord
|
||||
{
|
||||
get => currFilter.NumRec;
|
||||
set => currFilter.NumRec = value;
|
||||
}
|
||||
|
||||
private string rightStringCSS
|
||||
{
|
||||
get => hideSpenta ? "text-dark fw-bold" : "text-secondary";
|
||||
}
|
||||
|
||||
private DateTime selDtFine { get; set; } = DateTime.Now;
|
||||
|
||||
private bool showBrowse { get; set; } = false;
|
||||
@@ -424,28 +335,6 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
}
|
||||
|
||||
private double calcolaPerc(double durata)
|
||||
{
|
||||
double answ = 0;
|
||||
|
||||
double tot = 0;
|
||||
if (ListOdlStatsAct != null)
|
||||
{
|
||||
tot = ListOdlStatsAct.Sum(x => x.TotDurata);
|
||||
|
||||
double perc = (durata / tot) * 100;
|
||||
if (perc > 1)
|
||||
{
|
||||
answ = Math.Round(perc, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = Math.Round(perc, 4);
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
@@ -457,27 +346,6 @@ namespace MP.SPEC.Components
|
||||
await addTask2Exe(IdxMacc, "syncDbData", "");
|
||||
}
|
||||
|
||||
private string pbStyle(string css)
|
||||
{
|
||||
string answ = "";
|
||||
if (ListOdlStats != null)
|
||||
{
|
||||
if (css == "yellow")
|
||||
{
|
||||
answ = "orange";
|
||||
}
|
||||
else if (css == "blue")
|
||||
{
|
||||
answ = "#2874A6";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = css;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
@@ -495,12 +363,10 @@ namespace MP.SPEC.Components
|
||||
if (currRec != null)
|
||||
{
|
||||
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
|
||||
ListOdlStatsNetto = ListOdlStats.Where(x => x.Semaforo != "sGr").ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListOdlStats = null;
|
||||
ListOdlStatsNetto = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
//protected DataLogFilter _SelFilter { get; set; } = new DataLogFilter();
|
||||
protected int _selParam { get; set; } = -1;
|
||||
|
||||
[Inject]
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="col-8">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 270px">
|
||||
<div class="small textConsensed"><b>N° pezzi:</b> @statRecord.NumPezzi</div>
|
||||
<div class="small textConsensed"><b>T. Ciclo:</b> @statRecord.Tcassegnato.ToString("N3")</div>
|
||||
</td>
|
||||
<td style="width: 300px">
|
||||
<div class="small d-flex justify-content-between">
|
||||
<div>
|
||||
<div><b>@($"{@statRecord.DataInizio:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataInizio:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
<div class="p-0">
|
||||
<i class="fa-solid fa-angles-right"></i>
|
||||
</div>
|
||||
<div>
|
||||
@if (@statRecord.DataFine != null)
|
||||
{
|
||||
<div><b>@($"{@statRecord.DataFine:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataFine:ddd HH:mm:ss}")</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-secondary">
|
||||
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
@tradFase(statRecord.KeyRichiesta)
|
||||
</div>
|
||||
@if (statRecord.Note != "")
|
||||
{
|
||||
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
|
||||
<b class="text-dark"></b> <span class="text-wrap text-start"> @statRecord.Note </span>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-text">
|
||||
<span class="me-1 @leftStringCSS">Tutti gli Stati</span>
|
||||
<span class="form-check form-check-sm form-switch py-1" title="Mostra/Nascondi macchina spenta">
|
||||
<input class="form-check-input" type="checkbox" id="switchSpenta" @onchange="() => toggleSpenta()" value="@hideSpenta">
|
||||
</span>
|
||||
<span class="@rightStringCSS">Nascondi Spenta</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
@if (ListOdlStatsAct != null)
|
||||
{
|
||||
@foreach (var stat in ListOdlStatsAct)
|
||||
{
|
||||
<div class="p-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-uppercase">
|
||||
@stat.Descrizione
|
||||
</div>
|
||||
<div>
|
||||
<b>@(formDurata(stat.TotDurata))</b>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar @colorChanger(@stat.Css)" role="progressbar" aria-valuenow="0" aria-valuemin="0" style="width: @Math.Round(calcolaPerc(stat.TotDurata),0)%; background-color:@pbStyle(@stat.Css);" aria-valuemax="100">@($"{calcolaPerc(stat.TotDurata):N1}%")</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 dcContainer">
|
||||
@if (ListOdlStats != null)
|
||||
{
|
||||
<div class="dcBox">
|
||||
<ODLPlot SelectedOdl="@statRecord.IdxOdl" hideSpenta="@hideSpenta"></ODLPlot>
|
||||
</div>
|
||||
<div class="dcBox dcOverlay d-flex">
|
||||
<div class="align-self-center text-center w-100">
|
||||
<b class="fs-3">@durataFilt</b>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class StatsOdl
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public List<StatODLModel>? ListOdlStats { get; set; }
|
||||
|
||||
protected List<StatODLModel>? ListOdlStatsNetto
|
||||
{
|
||||
get => ListOdlStats != null ? ListOdlStats.Where(x => x.Semaforo != "sGr").ToList() : null;
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public List<ListValues>? ListStati { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public ODLExpModel statRecord { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string colorChanger(string colorCSS)
|
||||
{
|
||||
string answ = "";
|
||||
if (colorCSS == "yellow")
|
||||
{
|
||||
answ = "text-dark";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected string formDurata(double durataMin)
|
||||
{
|
||||
return MP.Data.Utils.FormDurata(durataMin);
|
||||
}
|
||||
|
||||
protected void toggleSpenta()
|
||||
{
|
||||
hideSpenta = !hideSpenta;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string durataFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "ND";
|
||||
if (statRecord != null)
|
||||
{
|
||||
if (hideSpenta)
|
||||
{
|
||||
if (ListOdlStatsNetto != null)
|
||||
{
|
||||
var tsDurata = TimeSpan.FromMinutes(ListOdlStatsNetto.Sum(x => x.TotDurata));
|
||||
if (tsDurata.TotalDays < 1)
|
||||
{
|
||||
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = statRecord.DurataMinuti;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
private bool hideSpenta { get; set; } = false;
|
||||
|
||||
private string leftStringCSS
|
||||
{
|
||||
get => hideSpenta ? "text-secondary" : "text-dark fw-bold";
|
||||
}
|
||||
|
||||
private List<StatODLModel>? ListOdlStatsAct
|
||||
{
|
||||
get
|
||||
{
|
||||
List<StatODLModel>? answ = new List<StatODLModel>();
|
||||
if (hideSpenta)
|
||||
{
|
||||
answ = ListOdlStatsNetto;
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListOdlStats;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
private string rightStringCSS
|
||||
{
|
||||
get => hideSpenta ? "text-dark fw-bold" : "text-secondary";
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private double calcolaPerc(double durata)
|
||||
{
|
||||
double answ = 0;
|
||||
|
||||
double tot = 0;
|
||||
if (ListOdlStatsAct != null)
|
||||
{
|
||||
tot = ListOdlStatsAct.Sum(x => x.TotDurata);
|
||||
|
||||
double perc = (durata / tot) * 100;
|
||||
if (perc > 1)
|
||||
{
|
||||
answ = Math.Round(perc, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = Math.Round(perc, 4);
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
private string pbStyle(string css)
|
||||
{
|
||||
string answ = "";
|
||||
if (ListOdlStats != null)
|
||||
{
|
||||
if (css == "yellow")
|
||||
{
|
||||
answ = "orange";
|
||||
}
|
||||
else if (css == "blue")
|
||||
{
|
||||
answ = "#2874A6";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = css;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
private string tradFase(string codFase)
|
||||
{
|
||||
string answ = codFase;
|
||||
if (ListStati != null && ListStati.Count > 0)
|
||||
{
|
||||
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
|
||||
if (recSel != null)
|
||||
{
|
||||
answ = recSel.label;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>6.16.2410.1512</Version>
|
||||
<Version>6.16.2410.1518</Version>
|
||||
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
|
||||
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2408.2710" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2408.2710" />
|
||||
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2409.2607" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2409.2607" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.9" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.12" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.14" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.12" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 6.16.2410.1512</h4>
|
||||
<h4>Versione: 6.16.2410.1518</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2410.1512
|
||||
6.16.2410.1518
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2410.1512</version>
|
||||
<version>6.16.2410.1518</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user